Rollup merge of #152622 - GuillaumeGomez:subtree-update_cg_gcc_2026-02-14, r=GuillaumeGomez
Update GCC subtree cc @antoyo r? ghost
This commit is contained in:
commit
0318407e30
34 changed files with 1790 additions and 1641 deletions
|
|
@ -18,6 +18,7 @@
|
||||||
],
|
],
|
||||||
"ignorePaths": [
|
"ignorePaths": [
|
||||||
"src/intrinsic/archs.rs",
|
"src/intrinsic/archs.rs",
|
||||||
|
"src/intrinsic/old_archs.rs",
|
||||||
"src/intrinsic/llvm.rs"
|
"src/intrinsic/llvm.rs"
|
||||||
],
|
],
|
||||||
"ignoreRegExpList": [
|
"ignoreRegExpList": [
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,10 @@ jobs:
|
||||||
git config --global user.name "User"
|
git config --global user.name "User"
|
||||||
./y.sh prepare
|
./y.sh prepare
|
||||||
|
|
||||||
|
- name: Add more failing tests for GCC without 128-bit integers support
|
||||||
|
if: ${{ matrix.libgccjit_version.gcc == 'gcc-15-without-int128.deb' }}
|
||||||
|
run: cat tests/failing-ui-tests-without-128bit-integers.txt >> tests/failing-ui-tests.txt
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: |
|
run: |
|
||||||
./y.sh test --release --clean --build-sysroot ${{ matrix.commands }}
|
./y.sh test --release --clean --build-sysroot ${{ matrix.commands }}
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
./y.sh prepare --only-libcore --cross
|
./y.sh prepare --only-libcore --cross
|
||||||
./y.sh build --sysroot --target-triple m68k-unknown-linux-gnu --target ${{ github.workspace }}/target_specs/m68k-unknown-linux-gnu.json
|
./y.sh build --sysroot --target-triple m68k-unknown-linux-gnu --target ${{ github.workspace }}/target_specs/m68k-unknown-linux-gnu.json
|
||||||
CG_RUSTFLAGS="-Clinker=m68k-unknown-linux-gnu-gcc" ./y.sh cargo build --manifest-path=./tests/hello-world/Cargo.toml --target ${{ github.workspace }}/target_specs/m68k-unknown-linux-gnu.json
|
CG_RUSTFLAGS="-Clinker=m68k-unknown-linux-gnu-gcc" ./y.sh cargo build -Zjson-target-spec --manifest-path=./tests/hello-world/Cargo.toml --target ${{ github.workspace }}/target_specs/m68k-unknown-linux-gnu.json
|
||||||
./y.sh clean all
|
./y.sh clean all
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
|
|
|
||||||
|
|
@ -56,18 +56,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gccjit"
|
name = "gccjit"
|
||||||
version = "3.1.1"
|
version = "3.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ff80f4d6d0749eab3a69122210b3a1fdd52edb6162781aadd7c4842e26983683"
|
checksum = "26b73d18b642ce16378af78f89664841d7eeafa113682ff5d14573424eb0232a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gccjit_sys",
|
"gccjit_sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gccjit_sys"
|
name = "gccjit_sys"
|
||||||
version = "1.1.2"
|
version = "1.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4f81d901767ddba371a619fa9bba657066a4d3c5607ee69bbb557c1c5ba9bf85"
|
checksum = "ee689456c013616942d5aef9a84d613cefcc3b335340d036f3650fc1a7459e15"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ default = ["master"]
|
||||||
[dependencies]
|
[dependencies]
|
||||||
object = { version = "0.37.0", default-features = false, features = ["std", "read"] }
|
object = { version = "0.37.0", default-features = false, features = ["std", "read"] }
|
||||||
tempfile = "3.20"
|
tempfile = "3.20"
|
||||||
gccjit = { version = "3.1.1", features = ["dlopen"] }
|
gccjit = { version = "3.3.0", features = ["dlopen"] }
|
||||||
#gccjit = { git = "https://github.com/rust-lang/gccjit.rs", branch = "error-dlopen", features = ["dlopen"] }
|
#gccjit = { git = "https://github.com/rust-lang/gccjit.rs", branch = "error-dlopen", features = ["dlopen"] }
|
||||||
|
|
||||||
# Local copy.
|
# Local copy.
|
||||||
|
|
|
||||||
|
|
@ -45,12 +45,12 @@ The default configuration (see below in the [Quick start](#quick-start) section)
|
||||||
./y.sh test --release
|
./y.sh test --release
|
||||||
```
|
```
|
||||||
|
|
||||||
If don't need to test GCC patches you wrote in our GCC fork, then the default configuration should
|
If you don't need to test GCC patches you wrote in our GCC fork, then the default configuration should
|
||||||
be all you need. You can update the `rustc_codegen_gcc` without worrying about GCC.
|
be all you need. You can update the `rustc_codegen_gcc` without worrying about GCC.
|
||||||
|
|
||||||
### Building with your own GCC version
|
### Building with your own GCC version
|
||||||
|
|
||||||
If you wrote a patch for GCC and want to test it without this backend, you will need
|
If you wrote a patch for GCC and want to test it with this backend, you will need
|
||||||
to do a few more things.
|
to do a few more things.
|
||||||
|
|
||||||
To build it (most of these instructions come from [here](https://gcc.gnu.org/onlinedocs/jit/internals/index.html), so don't hesitate to take a look there if you encounter an issue):
|
To build it (most of these instructions come from [here](https://gcc.gnu.org/onlinedocs/jit/internals/index.html), so don't hesitate to take a look there if you encounter an issue):
|
||||||
|
|
@ -127,7 +127,7 @@ You have to run these commands, in the corresponding order:
|
||||||
$ ./y.sh prepare
|
$ ./y.sh prepare
|
||||||
$ ./y.sh build --sysroot
|
$ ./y.sh build --sysroot
|
||||||
```
|
```
|
||||||
To check if all is working correctly, run:
|
To check if all is working correctly, run:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ ./y.sh cargo build --manifest-path tests/hello-world/Cargo.toml
|
$ ./y.sh cargo build --manifest-path tests/hello-world/Cargo.toml
|
||||||
|
|
|
||||||
|
|
@ -6,4 +6,4 @@ seh = "seh"
|
||||||
typ = "typ"
|
typ = "typ"
|
||||||
|
|
||||||
[files]
|
[files]
|
||||||
extend-exclude = ["src/intrinsic/archs.rs"]
|
extend-exclude = ["src/intrinsic/archs.rs", "src/intrinsic/old_archs.rs"]
|
||||||
|
|
|
||||||
|
|
@ -141,6 +141,10 @@ pub fn build_sysroot(env: &HashMap<String, String>, config: &ConfigInfo) -> Resu
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut args: Vec<&dyn AsRef<OsStr>> = vec![&"cargo", &"build", &"--target", &config.target];
|
let mut args: Vec<&dyn AsRef<OsStr>> = vec![&"cargo", &"build", &"--target", &config.target];
|
||||||
|
if config.target.ends_with(".json") {
|
||||||
|
args.push(&"-Zjson-target-spec");
|
||||||
|
}
|
||||||
|
|
||||||
for feature in &config.features {
|
for feature in &config.features {
|
||||||
args.push(&"--features");
|
args.push(&"--features");
|
||||||
args.push(feature);
|
args.push(feature);
|
||||||
|
|
|
||||||
|
|
@ -679,10 +679,10 @@ fn test_projects(env: &Env, args: &TestArg) -> Result<(), String> {
|
||||||
create_dir(projects_path)?;
|
create_dir(projects_path)?;
|
||||||
|
|
||||||
let nb_parts = args.nb_parts.unwrap_or(0);
|
let nb_parts = args.nb_parts.unwrap_or(0);
|
||||||
if nb_parts > 0 {
|
if let Some(count) = projects.len().checked_div(nb_parts) {
|
||||||
// We increment the number of tests by one because if this is an odd number, we would skip
|
// We increment the number of tests by one because if this is an odd number, we would skip
|
||||||
// one test.
|
// one test.
|
||||||
let count = projects.len() / nb_parts + 1;
|
let count = count + 1;
|
||||||
let current_part = args.current_part.unwrap();
|
let current_part = args.current_part.unwrap();
|
||||||
let start = current_part * count;
|
let start = current_part * count;
|
||||||
// We remove the projects we don't want to test.
|
// We remove the projects we don't want to test.
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
## How to debug GCC LTO
|
## How to debug GCC LTO
|
||||||
|
|
||||||
Run do the command with `-v -save-temps` and then extract the `lto1` line from the output and run that under the debugger.
|
Run the command with `-v -save-temps` and then extract the `lto1` line from the output and run that under the debugger.
|
||||||
|
|
||||||
## How to debug stdarch tests that cannot be ran locally
|
## How to debug stdarch tests that cannot be run locally
|
||||||
|
|
||||||
First, run the tests normally:
|
First, run the tests normally:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ That can be caused by the fact that you try to compile with `lto = "fat"`, but y
|
||||||
|
|
||||||
### ld: cannot find crtbegin.o
|
### ld: cannot find crtbegin.o
|
||||||
|
|
||||||
When compiling an executable with libgccijt, if setting the `*LIBRARY_PATH` variables to the install directory, you will get the following errors:
|
When compiling an executable with libgccjit, if setting the `*LIBRARY_PATH` variables to the install directory, you will get the following errors:
|
||||||
|
|
||||||
```
|
```
|
||||||
ld: cannot find crtbegin.o: No such file or directory
|
ld: cannot find crtbegin.o: No such file or directory
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
You can see the full documentation about what GIMPLE is [here](https://gcc.gnu.org/onlinedocs/gccint/GIMPLE.html). In this document we will explain how to generate it.
|
You can see the full documentation about what GIMPLE is [here](https://gcc.gnu.org/onlinedocs/gccint/GIMPLE.html). In this document we will explain how to generate it.
|
||||||
|
|
||||||
First, we'll copy the content from `gcc/gcc/testsuite/jit.dg/test-const-attribute.c` into a
|
First, we'll copy the content from `gcc/gcc/testsuite/jit.dg/test-const-attribute.c` into a
|
||||||
file named `local.c` and remove the content we're not interested into:
|
file named `local.c` and remove the content we're not interested in:
|
||||||
|
|
||||||
```diff
|
```diff
|
||||||
- /* { dg-do compile { target x86_64-*-* } } */
|
- /* { dg-do compile { target x86_64-*-* } } */
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ If you wish to build a custom sysroot, pass the path of your sysroot source to `
|
||||||
|
|
||||||
### How to use [mem-trace](https://github.com/antoyo/mem-trace)
|
### How to use [mem-trace](https://github.com/antoyo/mem-trace)
|
||||||
|
|
||||||
`rustc` needs to be built without `jemalloc` so that `mem-trace` can overload `malloc` since `jemalloc` is linked statically, so a `LD_PRELOAD`-ed library won't a chance to intercept the calls to `malloc`.
|
`rustc` needs to be built without `jemalloc` so that `mem-trace` can overload `malloc` since `jemalloc` is linked statically, so a `LD_PRELOAD`-ed library won't have a chance to intercept the calls to `malloc`.
|
||||||
|
|
||||||
### How to generate GIMPLE
|
### How to generate GIMPLE
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
0081ca6631abdfa02bf42bc85aaf507b8a0e6beb
|
efdd0a7290c22f5438d7c5380105d353ee3e8518
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
[toolchain]
|
[toolchain]
|
||||||
channel = "nightly-2025-12-20"
|
channel = "nightly-2026-02-14"
|
||||||
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]
|
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]
|
||||||
|
|
|
||||||
|
|
@ -575,9 +575,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
|
||||||
}
|
}
|
||||||
if dest.is_none() && options.contains(InlineAsmOptions::NORETURN) {
|
if dest.is_none() && options.contains(InlineAsmOptions::NORETURN) {
|
||||||
let builtin_unreachable = self.context.get_builtin_function("__builtin_unreachable");
|
let builtin_unreachable = self.context.get_builtin_function("__builtin_unreachable");
|
||||||
let builtin_unreachable: RValue<'gcc> =
|
self.llbb().add_eval(None, self.context.new_call(None, builtin_unreachable, &[]));
|
||||||
unsafe { std::mem::transmute(builtin_unreachable) };
|
|
||||||
self.call(self.type_void(), None, None, builtin_unreachable, &[], None, None);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write results to outputs.
|
// Write results to outputs.
|
||||||
|
|
|
||||||
|
|
@ -1495,6 +1495,8 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
|
||||||
|
|
||||||
#[cfg(not(feature = "master"))]
|
#[cfg(not(feature = "master"))]
|
||||||
fn extract_element(&mut self, vec: RValue<'gcc>, idx: RValue<'gcc>) -> RValue<'gcc> {
|
fn extract_element(&mut self, vec: RValue<'gcc>, idx: RValue<'gcc>) -> RValue<'gcc> {
|
||||||
|
use crate::context::new_array_type;
|
||||||
|
|
||||||
let vector_type = vec
|
let vector_type = vec
|
||||||
.get_type()
|
.get_type()
|
||||||
.unqualified()
|
.unqualified()
|
||||||
|
|
@ -1503,7 +1505,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
|
||||||
let element_type = vector_type.get_element_type();
|
let element_type = vector_type.get_element_type();
|
||||||
let vec_num_units = vector_type.get_num_units();
|
let vec_num_units = vector_type.get_num_units();
|
||||||
let array_type =
|
let array_type =
|
||||||
self.context.new_array_type(self.location, element_type, vec_num_units as u64);
|
new_array_type(self.context, self.location, element_type, vec_num_units as u64);
|
||||||
let array = self.context.new_bitcast(self.location, vec, array_type).to_rvalue();
|
let array = self.context.new_bitcast(self.location, vec, array_type).to_rvalue();
|
||||||
self.context.new_array_access(self.location, array, idx).to_rvalue()
|
self.context.new_array_access(self.location, array, idx).to_rvalue()
|
||||||
}
|
}
|
||||||
|
|
@ -1871,32 +1873,31 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
|
||||||
// On the other hand, f_max works even if int_ty::MAX is greater than float_ty::MAX. Because
|
// On the other hand, f_max works even if int_ty::MAX is greater than float_ty::MAX. Because
|
||||||
// we're rounding towards zero, we just get float_ty::MAX (which is always an integer).
|
// we're rounding towards zero, we just get float_ty::MAX (which is always an integer).
|
||||||
// This already happens today with u128::MAX = 2^128 - 1 > f32::MAX.
|
// This already happens today with u128::MAX = 2^128 - 1 > f32::MAX.
|
||||||
let int_max = |signed: bool, int_width: u64| -> u128 {
|
fn int_max(signed: bool, int_width: u64) -> u128 {
|
||||||
let shift_amount = 128 - int_width;
|
let shift_amount = 128 - int_width;
|
||||||
if signed { i128::MAX as u128 >> shift_amount } else { u128::MAX >> shift_amount }
|
if signed { i128::MAX as u128 >> shift_amount } else { u128::MAX >> shift_amount }
|
||||||
};
|
}
|
||||||
let int_min = |signed: bool, int_width: u64| -> i128 {
|
fn int_min(signed: bool, int_width: u64) -> i128 {
|
||||||
if signed { i128::MIN >> (128 - int_width) } else { 0 }
|
if signed { i128::MIN >> (128 - int_width) } else { 0 }
|
||||||
};
|
}
|
||||||
|
|
||||||
let compute_clamp_bounds_single = |signed: bool, int_width: u64| -> (u128, u128) {
|
// TODO: rewrite using a generic function with <F: Float>.
|
||||||
|
let compute_clamp_bounds_half = |signed: bool, int_width: u64| -> (u128, u128) {
|
||||||
let rounded_min =
|
let rounded_min =
|
||||||
ieee::Single::from_i128_r(int_min(signed, int_width), Round::TowardZero);
|
ieee::Half::from_i128_r(int_min(signed, int_width), Round::TowardZero);
|
||||||
assert_eq!(rounded_min.status, Status::OK);
|
//assert_eq!(rounded_min.status, Status::OK);
|
||||||
let rounded_max =
|
let rounded_max =
|
||||||
ieee::Single::from_u128_r(int_max(signed, int_width), Round::TowardZero);
|
ieee::Half::from_u128_r(int_max(signed, int_width), Round::TowardZero);
|
||||||
assert!(rounded_max.value.is_finite());
|
assert!(rounded_max.value.is_finite());
|
||||||
(rounded_min.value.to_bits(), rounded_max.value.to_bits())
|
(rounded_min.value.to_bits(), rounded_max.value.to_bits())
|
||||||
};
|
};
|
||||||
let compute_clamp_bounds_double = |signed: bool, int_width: u64| -> (u128, u128) {
|
fn compute_clamp_bounds<F: Float>(signed: bool, int_width: u64) -> (u128, u128) {
|
||||||
let rounded_min =
|
let rounded_min = F::from_i128_r(int_min(signed, int_width), Round::TowardZero);
|
||||||
ieee::Double::from_i128_r(int_min(signed, int_width), Round::TowardZero);
|
|
||||||
assert_eq!(rounded_min.status, Status::OK);
|
assert_eq!(rounded_min.status, Status::OK);
|
||||||
let rounded_max =
|
let rounded_max = F::from_u128_r(int_max(signed, int_width), Round::TowardZero);
|
||||||
ieee::Double::from_u128_r(int_max(signed, int_width), Round::TowardZero);
|
|
||||||
assert!(rounded_max.value.is_finite());
|
assert!(rounded_max.value.is_finite());
|
||||||
(rounded_min.value.to_bits(), rounded_max.value.to_bits())
|
(rounded_min.value.to_bits(), rounded_max.value.to_bits())
|
||||||
};
|
}
|
||||||
// To implement saturation, we perform the following steps:
|
// To implement saturation, we perform the following steps:
|
||||||
//
|
//
|
||||||
// 1. Cast val to an integer with fpto[su]i. This may result in undef.
|
// 1. Cast val to an integer with fpto[su]i. This may result in undef.
|
||||||
|
|
@ -1926,15 +1927,19 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
|
||||||
|
|
||||||
let float_bits_to_llval = |bx: &mut Self, bits| {
|
let float_bits_to_llval = |bx: &mut Self, bits| {
|
||||||
let bits_llval = match float_width {
|
let bits_llval = match float_width {
|
||||||
|
16 => bx.cx().const_u16(bits as u16),
|
||||||
32 => bx.cx().const_u32(bits as u32),
|
32 => bx.cx().const_u32(bits as u32),
|
||||||
64 => bx.cx().const_u64(bits as u64),
|
64 => bx.cx().const_u64(bits as u64),
|
||||||
|
128 => bx.cx().const_u128(bits),
|
||||||
n => bug!("unsupported float width {}", n),
|
n => bug!("unsupported float width {}", n),
|
||||||
};
|
};
|
||||||
bx.bitcast(bits_llval, float_ty)
|
bx.bitcast(bits_llval, float_ty)
|
||||||
};
|
};
|
||||||
let (f_min, f_max) = match float_width {
|
let (f_min, f_max) = match float_width {
|
||||||
32 => compute_clamp_bounds_single(signed, int_width),
|
16 => compute_clamp_bounds_half(signed, int_width),
|
||||||
64 => compute_clamp_bounds_double(signed, int_width),
|
32 => compute_clamp_bounds::<ieee::Single>(signed, int_width),
|
||||||
|
64 => compute_clamp_bounds::<ieee::Double>(signed, int_width),
|
||||||
|
128 => compute_clamp_bounds::<ieee::Quad>(signed, int_width),
|
||||||
n => bug!("unsupported float width {}", n),
|
n => bug!("unsupported float width {}", n),
|
||||||
};
|
};
|
||||||
let f_min = float_bits_to_llval(self, f_min);
|
let f_min = float_bits_to_llval(self, f_min);
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ use rustc_middle::mir::Mutability;
|
||||||
use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc, PointerArithmetic, Scalar};
|
use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc, PointerArithmetic, Scalar};
|
||||||
use rustc_middle::ty::layout::LayoutOf;
|
use rustc_middle::ty::layout::LayoutOf;
|
||||||
|
|
||||||
use crate::context::CodegenCx;
|
use crate::context::{CodegenCx, new_array_type};
|
||||||
use crate::type_of::LayoutGccExt;
|
use crate::type_of::LayoutGccExt;
|
||||||
|
|
||||||
impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
||||||
|
|
@ -20,6 +20,10 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
||||||
bytes_in_context(self, bytes)
|
bytes_in_context(self, bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn const_u16(&self, i: u16) -> RValue<'gcc> {
|
||||||
|
self.const_uint(self.type_u16(), i as u64)
|
||||||
|
}
|
||||||
|
|
||||||
fn global_string(&self, string: &str) -> LValue<'gcc> {
|
fn global_string(&self, string: &str) -> LValue<'gcc> {
|
||||||
// TODO(antoyo): handle non-null-terminated strings.
|
// TODO(antoyo): handle non-null-terminated strings.
|
||||||
let string = self.context.new_string_literal(string);
|
let string = self.context.new_string_literal(string);
|
||||||
|
|
@ -55,7 +59,7 @@ pub fn bytes_in_context<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, bytes: &[u8]) ->
|
||||||
0 => {
|
0 => {
|
||||||
let context = &cx.context;
|
let context = &cx.context;
|
||||||
let byte_type = context.new_type::<u64>();
|
let byte_type = context.new_type::<u64>();
|
||||||
let typ = context.new_array_type(None, byte_type, bytes.len() as u64 / 8);
|
let typ = new_array_type(context, None, byte_type, bytes.len() as u64 / 8);
|
||||||
let elements: Vec<_> = bytes
|
let elements: Vec<_> = bytes
|
||||||
.chunks_exact(8)
|
.chunks_exact(8)
|
||||||
.map(|arr| {
|
.map(|arr| {
|
||||||
|
|
@ -76,7 +80,7 @@ pub fn bytes_in_context<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, bytes: &[u8]) ->
|
||||||
4 => {
|
4 => {
|
||||||
let context = &cx.context;
|
let context = &cx.context;
|
||||||
let byte_type = context.new_type::<u32>();
|
let byte_type = context.new_type::<u32>();
|
||||||
let typ = context.new_array_type(None, byte_type, bytes.len() as u64 / 4);
|
let typ = new_array_type(context, None, byte_type, bytes.len() as u64 / 4);
|
||||||
let elements: Vec<_> = bytes
|
let elements: Vec<_> = bytes
|
||||||
.chunks_exact(4)
|
.chunks_exact(4)
|
||||||
.map(|arr| {
|
.map(|arr| {
|
||||||
|
|
@ -95,7 +99,7 @@ pub fn bytes_in_context<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, bytes: &[u8]) ->
|
||||||
_ => {
|
_ => {
|
||||||
let context = cx.context;
|
let context = cx.context;
|
||||||
let byte_type = context.new_type::<u8>();
|
let byte_type = context.new_type::<u8>();
|
||||||
let typ = context.new_array_type(None, byte_type, bytes.len() as u64);
|
let typ = new_array_type(context, None, byte_type, bytes.len() as u64);
|
||||||
let elements: Vec<_> = bytes
|
let elements: Vec<_> = bytes
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&byte| context.new_rvalue_from_int(byte_type, byte as i32))
|
.map(|&byte| context.new_rvalue_from_int(byte_type, byte as i32))
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,8 @@ use rustc_middle::ty::layout::{
|
||||||
};
|
};
|
||||||
use rustc_middle::ty::{self, ExistentialTraitRef, Instance, Ty, TyCtxt};
|
use rustc_middle::ty::{self, ExistentialTraitRef, Instance, Ty, TyCtxt};
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
|
#[cfg(feature = "master")]
|
||||||
|
use rustc_session::config::DebugInfo;
|
||||||
use rustc_span::source_map::respan;
|
use rustc_span::source_map::respan;
|
||||||
use rustc_span::{DUMMY_SP, Span};
|
use rustc_span::{DUMMY_SP, Span};
|
||||||
use rustc_target::spec::{HasTargetSpec, HasX86AbiOpt, Target, TlsModel, X86Abi};
|
use rustc_target::spec::{HasTargetSpec, HasX86AbiOpt, Target, TlsModel, X86Abi};
|
||||||
|
|
@ -145,6 +147,11 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
||||||
supports_f64_type: bool,
|
supports_f64_type: bool,
|
||||||
supports_f128_type: bool,
|
supports_f128_type: bool,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
#[cfg(feature = "master")]
|
||||||
|
if tcx.sess.opts.debuginfo != DebugInfo::None {
|
||||||
|
context.set_filename(codegen_unit.name().as_str());
|
||||||
|
}
|
||||||
|
|
||||||
let create_type = |ctype, rust_type| {
|
let create_type = |ctype, rust_type| {
|
||||||
let layout = tcx
|
let layout = tcx
|
||||||
.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(rust_type))
|
.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(rust_type))
|
||||||
|
|
@ -194,8 +201,8 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
||||||
|
|
||||||
// TODO(antoyo): re-enable the alignment when libgccjit fixed the issue in
|
// TODO(antoyo): re-enable the alignment when libgccjit fixed the issue in
|
||||||
// gcc_jit_context_new_array_constructor (it should not use reinterpret_cast).
|
// gcc_jit_context_new_array_constructor (it should not use reinterpret_cast).
|
||||||
let i128_type = context.new_array_type(None, i64_type, 2)/*.get_aligned(i128_align)*/;
|
let i128_type = new_array_type(context, None, i64_type, 2)/*.get_aligned(i128_align)*/;
|
||||||
let u128_type = context.new_array_type(None, u64_type, 2)/*.get_aligned(u128_align)*/;
|
let u128_type = new_array_type(context, None, u64_type, 2)/*.get_aligned(u128_align)*/;
|
||||||
(i128_type, u128_type)
|
(i128_type, u128_type)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -601,3 +608,17 @@ fn to_gcc_tls_mode(tls_model: TlsModel) -> gccjit::TlsModel {
|
||||||
TlsModel::Emulated => gccjit::TlsModel::GlobalDynamic,
|
TlsModel::Emulated => gccjit::TlsModel::GlobalDynamic,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_array_type<'gcc>(
|
||||||
|
context: &'gcc Context<'gcc>,
|
||||||
|
location: Option<Location<'gcc>>,
|
||||||
|
typ: Type<'gcc>,
|
||||||
|
size: u64,
|
||||||
|
) -> Type<'gcc> {
|
||||||
|
#[cfg(feature = "master")]
|
||||||
|
{
|
||||||
|
context.new_array_type_u64(location, typ, size)
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "master"))]
|
||||||
|
context.new_array_type(location, typ, size)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -942,7 +942,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
||||||
fn float_to_int_cast(
|
fn float_to_int_cast(
|
||||||
&self,
|
&self,
|
||||||
signed: bool,
|
signed: bool,
|
||||||
value: RValue<'gcc>,
|
mut value: RValue<'gcc>,
|
||||||
dest_typ: Type<'gcc>,
|
dest_typ: Type<'gcc>,
|
||||||
) -> RValue<'gcc> {
|
) -> RValue<'gcc> {
|
||||||
let value_type = value.get_type();
|
let value_type = value.get_type();
|
||||||
|
|
@ -951,16 +951,22 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_assert!(dest_typ.dyncast_array().is_some());
|
debug_assert!(dest_typ.dyncast_array().is_some());
|
||||||
|
let (dest_type, param_type) = match self.type_kind(value_type) {
|
||||||
|
TypeKind::Half => (Some(self.float_type), self.float_type),
|
||||||
|
_ => (None, value_type),
|
||||||
|
};
|
||||||
let name_suffix = match self.type_kind(value_type) {
|
let name_suffix = match self.type_kind(value_type) {
|
||||||
// cSpell:disable
|
// cSpell:disable
|
||||||
TypeKind::Float => "sfti",
|
// Since we will cast Half to a float, we use sfti for both.
|
||||||
|
TypeKind::Half | TypeKind::Float => "sfti",
|
||||||
TypeKind::Double => "dfti",
|
TypeKind::Double => "dfti",
|
||||||
|
TypeKind::FP128 => "tfti",
|
||||||
// cSpell:enable
|
// cSpell:enable
|
||||||
kind => panic!("cannot cast a {:?} to non-native integer", kind),
|
kind => panic!("cannot cast a {:?} to non-native integer", kind),
|
||||||
};
|
};
|
||||||
let sign = if signed { "" } else { "uns" };
|
let sign = if signed { "" } else { "uns" };
|
||||||
let func_name = format!("__fix{}{}", sign, name_suffix);
|
let func_name = format!("__fix{}{}", sign, name_suffix);
|
||||||
let param = self.context.new_parameter(None, value_type, "n");
|
let param = self.context.new_parameter(None, param_type, "n");
|
||||||
let func = self.context.new_function(
|
let func = self.context.new_function(
|
||||||
None,
|
None,
|
||||||
FunctionType::Extern,
|
FunctionType::Extern,
|
||||||
|
|
@ -969,6 +975,9 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
||||||
func_name,
|
func_name,
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
|
if let Some(dest_type) = dest_type {
|
||||||
|
value = self.context.new_cast(None, value, dest_type);
|
||||||
|
}
|
||||||
self.context.new_call(None, func, &[value])
|
self.context.new_call(None, func, &[value])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -4,7 +4,7 @@ use gccjit::{CType, Context, Field, Function, FunctionPtrType, RValue, ToRValue,
|
||||||
use rustc_codegen_ssa::traits::BuilderMethods;
|
use rustc_codegen_ssa::traits::BuilderMethods;
|
||||||
|
|
||||||
use crate::builder::Builder;
|
use crate::builder::Builder;
|
||||||
use crate::context::CodegenCx;
|
use crate::context::{CodegenCx, new_array_type};
|
||||||
|
|
||||||
fn encode_key_128_type<'a, 'gcc, 'tcx>(
|
fn encode_key_128_type<'a, 'gcc, 'tcx>(
|
||||||
builder: &Builder<'a, 'gcc, 'tcx>,
|
builder: &Builder<'a, 'gcc, 'tcx>,
|
||||||
|
|
@ -585,7 +585,7 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>(
|
||||||
"__builtin_ia32_encodekey128_u32" => {
|
"__builtin_ia32_encodekey128_u32" => {
|
||||||
let mut new_args = args.to_vec();
|
let mut new_args = args.to_vec();
|
||||||
let m128i = builder.context.new_vector_type(builder.i64_type, 2);
|
let m128i = builder.context.new_vector_type(builder.i64_type, 2);
|
||||||
let array_type = builder.context.new_array_type(None, m128i, 6);
|
let array_type = new_array_type(builder.context, None, m128i, 6);
|
||||||
let result = builder.current_func().new_local(None, array_type, "result");
|
let result = builder.current_func().new_local(None, array_type, "result");
|
||||||
new_args.push(result.get_address(None));
|
new_args.push(result.get_address(None));
|
||||||
args = new_args.into();
|
args = new_args.into();
|
||||||
|
|
@ -593,7 +593,7 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>(
|
||||||
"__builtin_ia32_encodekey256_u32" => {
|
"__builtin_ia32_encodekey256_u32" => {
|
||||||
let mut new_args = args.to_vec();
|
let mut new_args = args.to_vec();
|
||||||
let m128i = builder.context.new_vector_type(builder.i64_type, 2);
|
let m128i = builder.context.new_vector_type(builder.i64_type, 2);
|
||||||
let array_type = builder.context.new_array_type(None, m128i, 7);
|
let array_type = new_array_type(builder.context, None, m128i, 7);
|
||||||
let result = builder.current_func().new_local(None, array_type, "result");
|
let result = builder.current_func().new_local(None, array_type, "result");
|
||||||
new_args.push(result.get_address(None));
|
new_args.push(result.get_address(None));
|
||||||
args = new_args.into();
|
args = new_args.into();
|
||||||
|
|
@ -620,7 +620,7 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>(
|
||||||
let first_value = old_args.swap_remove(0);
|
let first_value = old_args.swap_remove(0);
|
||||||
|
|
||||||
let element_type = first_value.get_type();
|
let element_type = first_value.get_type();
|
||||||
let array_type = builder.context.new_array_type(None, element_type, 8);
|
let array_type = new_array_type(builder.context, None, element_type, 8);
|
||||||
let result = builder.current_func().new_local(None, array_type, "result");
|
let result = builder.current_func().new_local(None, array_type, "result");
|
||||||
new_args.push(result.get_address(None));
|
new_args.push(result.get_address(None));
|
||||||
|
|
||||||
|
|
@ -869,7 +869,7 @@ pub fn adjust_intrinsic_return_value<'a, 'gcc, 'tcx>(
|
||||||
builder.llbb().add_assignment(None, field1, return_value);
|
builder.llbb().add_assignment(None, field1, return_value);
|
||||||
let field2 = result.access_field(None, field2);
|
let field2 = result.access_field(None, field2);
|
||||||
let field2_type = field2.to_rvalue().get_type();
|
let field2_type = field2.to_rvalue().get_type();
|
||||||
let array_type = builder.context.new_array_type(None, field2_type, 6);
|
let array_type = new_array_type(builder.context, None, field2_type, 6);
|
||||||
let ptr = builder.context.new_cast(None, args[2], array_type.make_pointer());
|
let ptr = builder.context.new_cast(None, args[2], array_type.make_pointer());
|
||||||
let field2_ptr =
|
let field2_ptr =
|
||||||
builder.context.new_cast(None, field2.get_address(None), array_type.make_pointer());
|
builder.context.new_cast(None, field2.get_address(None), array_type.make_pointer());
|
||||||
|
|
@ -891,7 +891,7 @@ pub fn adjust_intrinsic_return_value<'a, 'gcc, 'tcx>(
|
||||||
builder.llbb().add_assignment(None, field1, return_value);
|
builder.llbb().add_assignment(None, field1, return_value);
|
||||||
let field2 = result.access_field(None, field2);
|
let field2 = result.access_field(None, field2);
|
||||||
let field2_type = field2.to_rvalue().get_type();
|
let field2_type = field2.to_rvalue().get_type();
|
||||||
let array_type = builder.context.new_array_type(None, field2_type, 7);
|
let array_type = new_array_type(builder.context, None, field2_type, 7);
|
||||||
let ptr = builder.context.new_cast(None, args[3], array_type.make_pointer());
|
let ptr = builder.context.new_cast(None, args[3], array_type.make_pointer());
|
||||||
let field2_ptr =
|
let field2_ptr =
|
||||||
builder.context.new_cast(None, field2.get_address(None), array_type.make_pointer());
|
builder.context.new_cast(None, field2.get_address(None), array_type.make_pointer());
|
||||||
|
|
@ -937,7 +937,7 @@ pub fn adjust_intrinsic_return_value<'a, 'gcc, 'tcx>(
|
||||||
builder.llbb().add_assignment(None, field1, return_value);
|
builder.llbb().add_assignment(None, field1, return_value);
|
||||||
let field2 = result.access_field(None, field2);
|
let field2 = result.access_field(None, field2);
|
||||||
let field2_type = field2.to_rvalue().get_type();
|
let field2_type = field2.to_rvalue().get_type();
|
||||||
let array_type = builder.context.new_array_type(None, field2_type, 8);
|
let array_type = new_array_type(builder.context, None, field2_type, 8);
|
||||||
let ptr = builder.context.new_cast(None, args[0], array_type.make_pointer());
|
let ptr = builder.context.new_cast(None, args[0], array_type.make_pointer());
|
||||||
let field2_ptr =
|
let field2_ptr =
|
||||||
builder.context.new_cast(None, field2.get_address(None), array_type.make_pointer());
|
builder.context.new_cast(None, field2.get_address(None), array_type.make_pointer());
|
||||||
|
|
@ -1061,7 +1061,18 @@ pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function
|
||||||
|
|
||||||
"llvm.x86.xgetbv" => "__builtin_ia32_xgetbv",
|
"llvm.x86.xgetbv" => "__builtin_ia32_xgetbv",
|
||||||
// NOTE: this doc specifies the equivalent GCC builtins: http://huonw.github.io/llvmint/llvmint/x86/index.html
|
// NOTE: this doc specifies the equivalent GCC builtins: http://huonw.github.io/llvmint/llvmint/x86/index.html
|
||||||
|
// FIXME: Should handle other targets than `ia32`.
|
||||||
"llvm.sqrt.v2f64" => "__builtin_ia32_sqrtpd",
|
"llvm.sqrt.v2f64" => "__builtin_ia32_sqrtpd",
|
||||||
|
// FIXME: Should handle other targets than `ia32`.
|
||||||
|
"llvm.sqrt.v4f32" => "__builtin_ia32_sqrtps",
|
||||||
|
"llvm.sqrt.f32" => {
|
||||||
|
let gcc_name = "__builtin_sqrtf";
|
||||||
|
let func = cx.context.get_builtin_function(gcc_name);
|
||||||
|
cx.functions.borrow_mut().insert(gcc_name.to_string(), func);
|
||||||
|
return func;
|
||||||
|
}
|
||||||
|
// FIXME: Should handle other targets than `ia32`.
|
||||||
|
"llvm.smax.v4i32" => "__builtin_ia32_pmaxsd128",
|
||||||
"llvm.x86.avx512.pmul.dq.512" => "__builtin_ia32_pmuldq512_mask",
|
"llvm.x86.avx512.pmul.dq.512" => "__builtin_ia32_pmuldq512_mask",
|
||||||
"llvm.x86.avx512.pmulu.dq.512" => "__builtin_ia32_pmuludq512_mask",
|
"llvm.x86.avx512.pmulu.dq.512" => "__builtin_ia32_pmuludq512_mask",
|
||||||
"llvm.x86.avx512.max.ps.512" => "__builtin_ia32_maxps512_mask",
|
"llvm.x86.avx512.max.ps.512" => "__builtin_ia32_maxps512_mask",
|
||||||
|
|
@ -1604,5 +1615,7 @@ pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function
|
||||||
func
|
func
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "master")]
|
||||||
|
include!("old_archs.rs");
|
||||||
#[cfg(feature = "master")]
|
#[cfg(feature = "master")]
|
||||||
include!("archs.rs");
|
include!("archs.rs");
|
||||||
|
|
|
||||||
|
|
@ -208,6 +208,7 @@ fn get_simple_function_f128<'gcc, 'tcx>(
|
||||||
let f128_type = cx.type_f128();
|
let f128_type = cx.type_f128();
|
||||||
let func_name = match name {
|
let func_name = match name {
|
||||||
sym::ceilf128 => "ceilf128",
|
sym::ceilf128 => "ceilf128",
|
||||||
|
sym::fabsf128 => "fabsf128",
|
||||||
sym::floorf128 => "floorf128",
|
sym::floorf128 => "floorf128",
|
||||||
sym::truncf128 => "truncf128",
|
sym::truncf128 => "truncf128",
|
||||||
sym::roundf128 => "roundf128",
|
sym::roundf128 => "roundf128",
|
||||||
|
|
@ -262,6 +263,7 @@ fn f16_builtin<'gcc, 'tcx>(
|
||||||
let builtin_name = match name {
|
let builtin_name = match name {
|
||||||
sym::ceilf16 => "__builtin_ceilf",
|
sym::ceilf16 => "__builtin_ceilf",
|
||||||
sym::copysignf16 => "__builtin_copysignf",
|
sym::copysignf16 => "__builtin_copysignf",
|
||||||
|
sym::fabsf16 => "fabsf",
|
||||||
sym::floorf16 => "__builtin_floorf",
|
sym::floorf16 => "__builtin_floorf",
|
||||||
sym::fmaf16 => "fmaf",
|
sym::fmaf16 => "fmaf",
|
||||||
sym::maxnumf16 => "__builtin_fmaxf",
|
sym::maxnumf16 => "__builtin_fmaxf",
|
||||||
|
|
@ -328,6 +330,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
|
||||||
}
|
}
|
||||||
sym::ceilf16
|
sym::ceilf16
|
||||||
| sym::copysignf16
|
| sym::copysignf16
|
||||||
|
| sym::fabsf16
|
||||||
| sym::floorf16
|
| sym::floorf16
|
||||||
| sym::fmaf16
|
| sym::fmaf16
|
||||||
| sym::maxnumf16
|
| sym::maxnumf16
|
||||||
|
|
@ -648,15 +651,15 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
|
||||||
let fn_ptr = func.get_address(None);
|
let fn_ptr = func.get_address(None);
|
||||||
let fn_ty = fn_ptr.get_type();
|
let fn_ty = fn_ptr.get_type();
|
||||||
|
|
||||||
let mut llargs = vec![];
|
let mut call_args = vec![];
|
||||||
|
|
||||||
for arg in args {
|
for arg in args {
|
||||||
match arg.val {
|
match arg.val {
|
||||||
OperandValue::ZeroSized => {}
|
OperandValue::ZeroSized => {}
|
||||||
OperandValue::Immediate(_) => llargs.push(arg.immediate()),
|
OperandValue::Immediate(_) => call_args.push(arg.immediate()),
|
||||||
OperandValue::Pair(a, b) => {
|
OperandValue::Pair(a, b) => {
|
||||||
llargs.push(a);
|
call_args.push(a);
|
||||||
llargs.push(b);
|
call_args.push(b);
|
||||||
}
|
}
|
||||||
OperandValue::Ref(op_place_val) => {
|
OperandValue::Ref(op_place_val) => {
|
||||||
let mut llval = op_place_val.llval;
|
let mut llval = op_place_val.llval;
|
||||||
|
|
@ -673,13 +676,13 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
|
||||||
// We store bools as `i8` so we need to truncate to `i1`.
|
// We store bools as `i8` so we need to truncate to `i1`.
|
||||||
llval = self.to_immediate_scalar(llval, scalar);
|
llval = self.to_immediate_scalar(llval, scalar);
|
||||||
}
|
}
|
||||||
llargs.push(llval);
|
call_args.push(llval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME directly use the llvm intrinsic adjustment functions here
|
// FIXME directly use the llvm intrinsic adjustment functions here
|
||||||
let llret = self.call(fn_ty, None, None, fn_ptr, &llargs, None, None);
|
let llret = self.call(fn_ty, None, None, fn_ptr, &call_args, None, None);
|
||||||
if is_cleanup {
|
if is_cleanup {
|
||||||
self.apply_attrs_to_cleanup_callsite(llret);
|
self.apply_attrs_to_cleanup_callsite(llret);
|
||||||
}
|
}
|
||||||
|
|
@ -720,7 +723,8 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
|
||||||
}
|
}
|
||||||
|
|
||||||
fn va_end(&mut self, _va_list: RValue<'gcc>) -> RValue<'gcc> {
|
fn va_end(&mut self, _va_list: RValue<'gcc>) -> RValue<'gcc> {
|
||||||
unimplemented!();
|
// TODO(antoyo): implement.
|
||||||
|
self.context.new_rvalue_from_int(self.int_type, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
1390
compiler/rustc_codegen_gcc/src/intrinsic/old_archs.rs
Normal file
1390
compiler/rustc_codegen_gcc/src/intrinsic/old_archs.rs
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -234,6 +234,8 @@ impl CodegenBackend for GccCodegenBackend {
|
||||||
|
|
||||||
#[cfg(feature = "master")]
|
#[cfg(feature = "master")]
|
||||||
{
|
{
|
||||||
|
gccjit::set_lang_name(c"GNU Rust");
|
||||||
|
|
||||||
let target_cpu = target_cpu(sess);
|
let target_cpu = target_cpu(sess);
|
||||||
|
|
||||||
// Get the second TargetInfo with the correct CPU features by setting the arch.
|
// Get the second TargetInfo with the correct CPU features by setting the arch.
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ use rustc_middle::ty::layout::TyAndLayout;
|
||||||
use rustc_middle::{bug, ty};
|
use rustc_middle::{bug, ty};
|
||||||
|
|
||||||
use crate::common::TypeReflection;
|
use crate::common::TypeReflection;
|
||||||
use crate::context::CodegenCx;
|
use crate::context::{CodegenCx, new_array_type};
|
||||||
use crate::type_of::LayoutGccExt;
|
use crate::type_of::LayoutGccExt;
|
||||||
|
|
||||||
impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
||||||
|
|
@ -311,7 +311,7 @@ impl<'gcc, 'tcx> BaseTypeCodegenMethods for CodegenCx<'gcc, 'tcx> {
|
||||||
len = 0;
|
len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.context.new_array_type(None, ty, len)
|
new_array_type(self.context, None, ty, len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,4 +11,4 @@ tests/run-make/foreign-exceptions/
|
||||||
tests/run-make/glibc-staticlib-args/
|
tests/run-make/glibc-staticlib-args/
|
||||||
tests/run-make/lto-smoke-c/
|
tests/run-make/lto-smoke-c/
|
||||||
tests/run-make/return-non-c-like-enum/
|
tests/run-make/return-non-c-like-enum/
|
||||||
|
tests/run-make/short-ice
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
tests/ui/simd/intrinsic/splat.rs
|
||||||
|
|
@ -89,11 +89,13 @@ tests/ui/thir-print/offset_of.rs
|
||||||
tests/ui/iterators/rangefrom-overflow-debug.rs
|
tests/ui/iterators/rangefrom-overflow-debug.rs
|
||||||
tests/ui/iterators/rangefrom-overflow-overflow-checks.rs
|
tests/ui/iterators/rangefrom-overflow-overflow-checks.rs
|
||||||
tests/ui/iterators/iter-filter-count-debug-check.rs
|
tests/ui/iterators/iter-filter-count-debug-check.rs
|
||||||
tests/ui/eii/codegen_single_crate.rs
|
tests/ui/eii/linking/codegen_single_crate.rs
|
||||||
tests/ui/eii/codegen_cross_crate.rs
|
tests/ui/eii/linking/codegen_cross_crate.rs
|
||||||
tests/ui/eii/default/local_crate.rs
|
tests/ui/eii/default/local_crate.rs
|
||||||
tests/ui/eii/multiple_impls.rs
|
tests/ui/eii/duplicate/multiple_impls.rs
|
||||||
tests/ui/eii/default/call_default.rs
|
tests/ui/eii/default/call_default.rs
|
||||||
tests/ui/eii/same-symbol.rs
|
tests/ui/eii/linking/same-symbol.rs
|
||||||
tests/ui/eii/privacy1.rs
|
tests/ui/eii/privacy1.rs
|
||||||
tests/ui/eii/default/call_impl.rs
|
tests/ui/eii/default/call_impl.rs
|
||||||
|
tests/ui/c-variadic/copy.rs
|
||||||
|
tests/ui/asm/x86_64/global_asm_escape.rs
|
||||||
|
|
|
||||||
38
compiler/rustc_codegen_gcc/tests/run/call-llvm-intrinsics.rs
Normal file
38
compiler/rustc_codegen_gcc/tests/run/call-llvm-intrinsics.rs
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
// Compiler:
|
||||||
|
//
|
||||||
|
// Run-time:
|
||||||
|
// status: 0
|
||||||
|
|
||||||
|
// FIXME: Remove this test once rustc's `./tests/codegen/riscv-abi/call-llvm-intrinsics.rs`
|
||||||
|
// stops ignoring GCC backend.
|
||||||
|
|
||||||
|
#![feature(link_llvm_intrinsics)]
|
||||||
|
#![allow(internal_features)]
|
||||||
|
|
||||||
|
struct A;
|
||||||
|
|
||||||
|
impl Drop for A {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
println!("A");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#[link_name = "llvm.sqrt.f32"]
|
||||||
|
fn sqrt(x: f32) -> f32;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn do_call() {
|
||||||
|
let _a = A;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
// Ensure that we `call` LLVM intrinsics instead of trying to `invoke` them
|
||||||
|
// CHECK: store float 4.000000e+00, float* %{{.}}, align 4
|
||||||
|
// CHECK: call float @llvm.sqrt.f32(float %{{.}}
|
||||||
|
sqrt(4.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
do_call();
|
||||||
|
}
|
||||||
102
compiler/rustc_codegen_gcc/tests/run/simd-ffi.rs
Normal file
102
compiler/rustc_codegen_gcc/tests/run/simd-ffi.rs
Normal file
|
|
@ -0,0 +1,102 @@
|
||||||
|
// Compiler:
|
||||||
|
//
|
||||||
|
// Run-time:
|
||||||
|
// status: 0
|
||||||
|
|
||||||
|
// FIXME: Remove this test once <tests/run-make/simd-ffi/simd.rs> stops
|
||||||
|
// ignoring GCC backend.
|
||||||
|
|
||||||
|
#![allow(internal_features, non_camel_case_types)]
|
||||||
|
// we can compile to a variety of platforms, because we don't need
|
||||||
|
// cross-compiled standard libraries.
|
||||||
|
#![feature(no_core, auto_traits)]
|
||||||
|
#![no_core]
|
||||||
|
#![feature(repr_simd, simd_ffi, link_llvm_intrinsics, lang_items, rustc_attrs)]
|
||||||
|
|
||||||
|
#[derive(Copy)]
|
||||||
|
#[repr(simd)]
|
||||||
|
pub struct f32x4([f32; 4]);
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#[link_name = "llvm.sqrt.v4f32"]
|
||||||
|
fn vsqrt(x: f32x4) -> f32x4;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn foo(x: f32x4) -> f32x4 {
|
||||||
|
unsafe { vsqrt(x) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy)]
|
||||||
|
#[repr(simd)]
|
||||||
|
pub struct i32x4([i32; 4]);
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
// _mm_sll_epi32
|
||||||
|
#[cfg(all(any(target_arch = "x86", target_arch = "x86-64"), target_feature = "sse2"))]
|
||||||
|
#[link_name = "llvm.x86.sse2.psll.d"]
|
||||||
|
fn integer(a: i32x4, b: i32x4) -> i32x4;
|
||||||
|
|
||||||
|
// vmaxq_s32
|
||||||
|
#[cfg(target_arch = "arm")]
|
||||||
|
#[link_name = "llvm.arm.neon.vmaxs.v4i32"]
|
||||||
|
fn integer(a: i32x4, b: i32x4) -> i32x4;
|
||||||
|
// vmaxq_s32
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
#[link_name = "llvm.aarch64.neon.maxs.v4i32"]
|
||||||
|
fn integer(a: i32x4, b: i32x4) -> i32x4;
|
||||||
|
|
||||||
|
// Use a generic LLVM intrinsic to do type checking on other platforms
|
||||||
|
#[cfg(not(any(
|
||||||
|
all(any(target_arch = "x86", target_arch = "x86-64"), target_feature = "sse2"),
|
||||||
|
target_arch = "arm",
|
||||||
|
target_arch = "aarch64"
|
||||||
|
)))]
|
||||||
|
#[link_name = "llvm.smax.v4i32"]
|
||||||
|
fn integer(a: i32x4, b: i32x4) -> i32x4;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bar(a: i32x4, b: i32x4) -> i32x4 {
|
||||||
|
unsafe { integer(a, b) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[lang = "pointee_sized"]
|
||||||
|
pub trait PointeeSized {}
|
||||||
|
|
||||||
|
#[lang = "meta_sized"]
|
||||||
|
pub trait MetaSized: PointeeSized {}
|
||||||
|
|
||||||
|
#[lang = "sized"]
|
||||||
|
pub trait Sized: MetaSized {}
|
||||||
|
|
||||||
|
#[lang = "copy"]
|
||||||
|
pub trait Copy {}
|
||||||
|
|
||||||
|
impl Copy for f32 {}
|
||||||
|
impl Copy for i32 {}
|
||||||
|
impl Copy for [f32; 4] {}
|
||||||
|
impl Copy for [i32; 4] {}
|
||||||
|
|
||||||
|
pub mod marker {
|
||||||
|
pub use Copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[lang = "freeze"]
|
||||||
|
auto trait Freeze {}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
#[rustc_builtin_macro]
|
||||||
|
macro_rules! Copy {
|
||||||
|
() => {};
|
||||||
|
}
|
||||||
|
#[macro_export]
|
||||||
|
#[rustc_builtin_macro]
|
||||||
|
macro_rules! derive {
|
||||||
|
() => {};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[lang = "start"]
|
||||||
|
fn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
27
compiler/rustc_codegen_gcc/tests/run/unreachable-function.rs
Normal file
27
compiler/rustc_codegen_gcc/tests/run/unreachable-function.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
// Compiler:
|
||||||
|
//
|
||||||
|
// Run-time:
|
||||||
|
// status: 0
|
||||||
|
|
||||||
|
use std::arch::asm;
|
||||||
|
|
||||||
|
fn exit_syscall(status: i32) -> ! {
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
unsafe {
|
||||||
|
asm!(
|
||||||
|
"syscall",
|
||||||
|
in("rax") 60,
|
||||||
|
in("rdi") status,
|
||||||
|
options(noreturn)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "x86_64"))]
|
||||||
|
std::process::exit(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// Used to crash with rustc_codegen_gcc.
|
||||||
|
exit_syscall(0);
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
|
@ -12,7 +12,7 @@ def run_command(command, cwd=None):
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
def clone_repository(repo_name, path, repo_url, branch="master", sub_paths=None):
|
def clone_repository(repo_name, path, repo_url, sub_paths):
|
||||||
if os.path.exists(path):
|
if os.path.exists(path):
|
||||||
while True:
|
while True:
|
||||||
choice = input("There is already a `{}` folder, do you want to update it? [y/N]".format(path))
|
choice = input("There is already a `{}` folder, do you want to update it? [y/N]".format(path))
|
||||||
|
|
@ -21,18 +21,15 @@ def clone_repository(repo_name, path, repo_url, branch="master", sub_paths=None)
|
||||||
return
|
return
|
||||||
elif choice.lower() == "y":
|
elif choice.lower() == "y":
|
||||||
print("Updating repository...")
|
print("Updating repository...")
|
||||||
run_command(["git", "pull", "origin", branch], cwd=path)
|
run_command(["git", "pull", "origin", "main"], cwd=path)
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
print("Didn't understand answer...")
|
print("Didn't understand answer...")
|
||||||
print("Cloning {} repository...".format(repo_name))
|
print("Cloning {} repository...".format(repo_name))
|
||||||
if sub_paths is None:
|
run_command(["git", "clone", repo_url, "--filter=tree:0", "--no-checkout", path])
|
||||||
run_command(["git", "clone", repo_url, "--depth", "1", path])
|
run_command(["git", "sparse-checkout", "init"], cwd=path)
|
||||||
else:
|
run_command(["git", "sparse-checkout", "set", *sub_paths], cwd=path)
|
||||||
run_command(["git", "clone", repo_url, "--filter=tree:0", "--no-checkout", path])
|
run_command(["git", "checkout"], cwd=path)
|
||||||
run_command(["git", "sparse-checkout", "init"], cwd=path)
|
|
||||||
run_command(["git", "sparse-checkout", "set", *sub_paths], cwd=path)
|
|
||||||
run_command(["git", "checkout"], cwd=path)
|
|
||||||
|
|
||||||
|
|
||||||
def append_intrinsic(array, intrinsic_name, translation):
|
def append_intrinsic(array, intrinsic_name, translation):
|
||||||
|
|
@ -45,121 +42,36 @@ def convert_to_string(content):
|
||||||
return content
|
return content
|
||||||
|
|
||||||
|
|
||||||
def extract_intrinsics_from_llvm(llvm_path, intrinsics):
|
def extract_intrinsics_from_llvm(llvm_path):
|
||||||
command = ["llvm-tblgen", "llvm/IR/Intrinsics.td"]
|
intrinsics = {}
|
||||||
|
command = ["llvm-tblgen", "llvm/IR/Intrinsics.td", "--dump-json"]
|
||||||
cwd = os.path.join(llvm_path, "llvm/include")
|
cwd = os.path.join(llvm_path, "llvm/include")
|
||||||
print("=> Running command `{}` from `{}`".format(command, cwd))
|
print("=> Running command `{}` from `{}`".format(command, cwd))
|
||||||
p = subprocess.Popen(command, cwd=cwd, stdout=subprocess.PIPE)
|
p = subprocess.Popen(command, cwd=cwd, stdout=subprocess.PIPE)
|
||||||
output, err = p.communicate()
|
output, err = p.communicate()
|
||||||
lines = convert_to_string(output).splitlines()
|
content = json.loads(convert_to_string(output))
|
||||||
pos = 0
|
for intrinsic in content:
|
||||||
while pos < len(lines):
|
data = content[intrinsic]
|
||||||
line = lines[pos]
|
if not isinstance(data, dict):
|
||||||
if not line.startswith("def "):
|
|
||||||
pos += 1
|
|
||||||
continue
|
continue
|
||||||
intrinsic = line.split(" ")[1].strip()
|
current_arch = data.get("TargetPrefix")
|
||||||
content = line
|
builtin_name = data.get("ClangBuiltinName")
|
||||||
while pos < len(lines):
|
if current_arch is None or current_arch == "" or builtin_name is None:
|
||||||
line = lines[pos].split(" // ")[0].strip()
|
|
||||||
content += line
|
|
||||||
pos += 1
|
|
||||||
if line == "}":
|
|
||||||
break
|
|
||||||
entries = re.findall('string ClangBuiltinName = "(\\w+)";', content)
|
|
||||||
current_arch = re.findall('string TargetPrefix = "(\\w+)";', content)
|
|
||||||
if len(entries) == 1 and len(current_arch) == 1:
|
|
||||||
current_arch = current_arch[0]
|
|
||||||
intrinsic = intrinsic.split("_")
|
|
||||||
if len(intrinsic) < 2 or intrinsic[0] != "int":
|
|
||||||
continue
|
|
||||||
intrinsic[0] = "llvm"
|
|
||||||
intrinsic = ".".join(intrinsic)
|
|
||||||
if current_arch not in intrinsics:
|
|
||||||
intrinsics[current_arch] = []
|
|
||||||
append_intrinsic(intrinsics[current_arch], intrinsic, entries[0])
|
|
||||||
|
|
||||||
|
|
||||||
def append_translation(json_data, p, array):
|
|
||||||
it = json_data["index"][p]
|
|
||||||
content = it["docs"].split('`')
|
|
||||||
if len(content) != 5:
|
|
||||||
return
|
|
||||||
append_intrinsic(array, content[1], content[3])
|
|
||||||
|
|
||||||
|
|
||||||
def extract_intrinsics_from_llvmint(llvmint, intrinsics):
|
|
||||||
archs = [
|
|
||||||
"AMDGPU",
|
|
||||||
"aarch64",
|
|
||||||
"arm",
|
|
||||||
"cuda",
|
|
||||||
"hexagon",
|
|
||||||
"mips",
|
|
||||||
"nvvm",
|
|
||||||
"ppc",
|
|
||||||
"ptx",
|
|
||||||
"x86",
|
|
||||||
"xcore",
|
|
||||||
]
|
|
||||||
|
|
||||||
json_file = os.path.join(llvmint, "target/doc/llvmint.json")
|
|
||||||
# We need to regenerate the documentation!
|
|
||||||
run_command(
|
|
||||||
["cargo", "rustdoc", "--", "-Zunstable-options", "--output-format", "json"],
|
|
||||||
cwd=llvmint,
|
|
||||||
)
|
|
||||||
with open(json_file, "r", encoding="utf8") as f:
|
|
||||||
json_data = json.loads(f.read())
|
|
||||||
for p in json_data["paths"]:
|
|
||||||
it = json_data["paths"][p]
|
|
||||||
if it["crate_id"] != 0:
|
|
||||||
# This is from an external crate.
|
|
||||||
continue
|
continue
|
||||||
if it["kind"] != "function":
|
intrinsic = intrinsic.split("_")
|
||||||
# We're only looking for functions.
|
if len(intrinsic) < 2 or intrinsic[0] != "int":
|
||||||
continue
|
continue
|
||||||
# if len(it["path"]) == 2:
|
intrinsic[0] = "llvm"
|
||||||
# # This is a "general" intrinsic, not bound to a specific arch.
|
intrinsic = ".".join(intrinsic)
|
||||||
# append_translation(json_data, p, general)
|
if current_arch not in intrinsics:
|
||||||
# continue
|
intrinsics[current_arch] = []
|
||||||
if len(it["path"]) != 3 or it["path"][1] not in archs:
|
append_intrinsic(intrinsics[current_arch], intrinsic, builtin_name)
|
||||||
continue
|
|
||||||
arch = it["path"][1]
|
return intrinsics
|
||||||
if arch not in intrinsics:
|
|
||||||
intrinsics[arch] = []
|
|
||||||
append_translation(json_data, p, intrinsics[arch])
|
|
||||||
|
|
||||||
|
|
||||||
def fill_intrinsics(intrinsics, from_intrinsics, all_intrinsics):
|
def update_intrinsics(llvm_path):
|
||||||
for arch in from_intrinsics:
|
intrinsics = extract_intrinsics_from_llvm(llvm_path)
|
||||||
if arch not in intrinsics:
|
|
||||||
intrinsics[arch] = []
|
|
||||||
for entry in from_intrinsics[arch]:
|
|
||||||
if entry[0] in all_intrinsics:
|
|
||||||
if all_intrinsics[entry[0]] == entry[1]:
|
|
||||||
# This is a "full" duplicate, both the LLVM instruction and the GCC
|
|
||||||
# translation are the same.
|
|
||||||
continue
|
|
||||||
intrinsics[arch].append((entry[0], entry[1], True))
|
|
||||||
else:
|
|
||||||
intrinsics[arch].append((entry[0], entry[1], False))
|
|
||||||
all_intrinsics[entry[0]] = entry[1]
|
|
||||||
|
|
||||||
|
|
||||||
def update_intrinsics(llvm_path, llvmint, llvmint2):
|
|
||||||
intrinsics_llvm = {}
|
|
||||||
intrinsics_llvmint = {}
|
|
||||||
all_intrinsics = {}
|
|
||||||
|
|
||||||
extract_intrinsics_from_llvm(llvm_path, intrinsics_llvm)
|
|
||||||
extract_intrinsics_from_llvmint(llvmint, intrinsics_llvmint)
|
|
||||||
extract_intrinsics_from_llvmint(llvmint2, intrinsics_llvmint)
|
|
||||||
|
|
||||||
intrinsics = {}
|
|
||||||
# We give priority to translations from LLVM over the ones from llvmint.
|
|
||||||
fill_intrinsics(intrinsics, intrinsics_llvm, all_intrinsics)
|
|
||||||
fill_intrinsics(intrinsics, intrinsics_llvmint, all_intrinsics)
|
|
||||||
|
|
||||||
archs = [arch for arch in intrinsics]
|
archs = [arch for arch in intrinsics]
|
||||||
archs.sort()
|
archs.sort()
|
||||||
|
|
@ -173,33 +85,41 @@ def update_intrinsics(llvm_path, llvmint, llvmint2):
|
||||||
# Since all intrinsic names start with "llvm.", we skip that prefix.
|
# Since all intrinsic names start with "llvm.", we skip that prefix.
|
||||||
print("Updating content of `{}`...".format(output_file))
|
print("Updating content of `{}`...".format(output_file))
|
||||||
with open(output_file, "w", encoding="utf8") as out:
|
with open(output_file, "w", encoding="utf8") as out:
|
||||||
out.write("// File generated by `rustc_codegen_gcc/tools/generate_intrinsics.py`\n")
|
out.write("""// File generated by `rustc_codegen_gcc/tools/generate_intrinsics.py`
|
||||||
out.write("// DO NOT EDIT IT!\n")
|
// DO NOT EDIT IT!
|
||||||
out.write("/// Translate a given LLVM intrinsic name to an equivalent GCC one.\n")
|
/// Translate a given LLVM intrinsic name to an equivalent GCC one.
|
||||||
out.write("fn map_arch_intrinsic(full_name:&str)->&'static str{\n")
|
fn map_arch_intrinsic(full_name:&str)-> &'static str {
|
||||||
out.write('let Some(name) = full_name.strip_prefix("llvm.") else { unimplemented!("***** unsupported LLVM intrinsic {}", full_name) };\n')
|
let Some(name) = full_name.strip_prefix("llvm.") else { unimplemented!("***** unsupported LLVM intrinsic {}", full_name) };
|
||||||
out.write('let Some((arch, name)) = name.split_once(\'.\') else { unimplemented!("***** unsupported LLVM intrinsic {}", name) };\n')
|
let Some((arch, name)) = name.split_once('.') else { unimplemented!("***** unsupported LLVM intrinsic llvm.{}", name) };
|
||||||
out.write("match arch {\n")
|
let old_arch_res = old_archs(arch, name);
|
||||||
|
if let ArchCheckResult::Ok(res) = old_arch_res {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
match arch {""")
|
||||||
for arch in archs:
|
for arch in archs:
|
||||||
if len(intrinsics[arch]) == 0:
|
if len(intrinsics[arch]) == 0:
|
||||||
continue
|
continue
|
||||||
attribute = "#[expect(non_snake_case)]" if arch[0].isupper() else ""
|
attribute = "#[expect(non_snake_case)]" if arch[0].isupper() else ""
|
||||||
out.write("\"{}\" => {{ {} fn {}(name: &str,full_name:&str) -> &'static str {{ match name {{".format(arch, attribute, arch))
|
out.write("\"{}\" => {{ {} fn {}(name: &str,full_name:&str) -> &'static str {{ match name {{".format(arch, attribute, arch))
|
||||||
intrinsics[arch].sort(key=lambda x: (x[0], x[2]))
|
intrinsics[arch].sort(key=lambda x: (x[0], x[1]))
|
||||||
out.write(' // {}\n'.format(arch))
|
out.write(' // {}\n'.format(arch))
|
||||||
for entry in intrinsics[arch]:
|
for entry in intrinsics[arch]:
|
||||||
llvm_name = entry[0].removeprefix("llvm.");
|
llvm_name = entry[0].removeprefix("llvm.");
|
||||||
llvm_name = llvm_name.removeprefix(arch);
|
llvm_name = llvm_name.removeprefix(arch);
|
||||||
llvm_name = llvm_name.removeprefix(".");
|
llvm_name = llvm_name.removeprefix(".");
|
||||||
if entry[2] is True: # if it is a duplicate
|
if "_round_mask" in entry[1]:
|
||||||
out.write(' // [DUPLICATE]: "{}" => "{}",\n'.format(llvm_name, entry[1]))
|
|
||||||
elif "_round_mask" in entry[1]:
|
|
||||||
out.write(' // [INVALID CONVERSION]: "{}" => "{}",\n'.format(llvm_name, entry[1]))
|
out.write(' // [INVALID CONVERSION]: "{}" => "{}",\n'.format(llvm_name, entry[1]))
|
||||||
else:
|
else:
|
||||||
out.write(' "{}" => "{}",\n'.format(llvm_name, entry[1]))
|
out.write(' "{}" => "{}",\n'.format(llvm_name, entry[1]))
|
||||||
out.write(' _ => unimplemented!("***** unsupported LLVM intrinsic {full_name}"),\n')
|
out.write(' _ => unimplemented!("***** unsupported LLVM intrinsic {full_name}"),\n')
|
||||||
out.write("}} }} {}(name,full_name) }}\n,".format(arch))
|
out.write("}} }} {}(name,full_name) }}\n,".format(arch))
|
||||||
out.write(' _ => unimplemented!("***** unsupported LLVM architecture {arch}, intrinsic:{full_name}"),\n')
|
out.write(""" _ => {
|
||||||
|
match old_arch_res {
|
||||||
|
ArchCheckResult::UnknownIntrinsic => unimplemented!("***** unsupported LLVM intrinsic {full_name}"),
|
||||||
|
ArchCheckResult::UnknownArch => unimplemented!("***** unsupported LLVM architecture {arch}, intrinsic: {full_name}"),
|
||||||
|
ArchCheckResult::Ok(_) => unreachable!(),
|
||||||
|
}
|
||||||
|
}""")
|
||||||
out.write("}\n}")
|
out.write("}\n}")
|
||||||
subprocess.call(["rustfmt", output_file])
|
subprocess.call(["rustfmt", output_file])
|
||||||
print("Done!")
|
print("Done!")
|
||||||
|
|
@ -210,35 +130,21 @@ def main():
|
||||||
os.path.dirname(os.path.abspath(__file__)),
|
os.path.dirname(os.path.abspath(__file__)),
|
||||||
"llvm-project",
|
"llvm-project",
|
||||||
)
|
)
|
||||||
llvmint_path = os.path.join(
|
|
||||||
os.path.dirname(os.path.abspath(__file__)),
|
|
||||||
"llvmint",
|
|
||||||
)
|
|
||||||
llvmint2_path = os.path.join(
|
|
||||||
os.path.dirname(os.path.abspath(__file__)),
|
|
||||||
"llvmint-2",
|
|
||||||
)
|
|
||||||
|
|
||||||
# First, we clone the LLVM repository if it's not already here.
|
# First, we clone the LLVM repository if it's not already here.
|
||||||
clone_repository(
|
clone_repository(
|
||||||
"llvm-project",
|
"llvm-project",
|
||||||
llvm_path,
|
llvm_path,
|
||||||
"https://github.com/llvm/llvm-project",
|
"https://github.com/llvm/llvm-project",
|
||||||
branch="main",
|
["llvm/include/llvm/IR", "llvm/include/llvm/CodeGen/"],
|
||||||
sub_paths=["llvm/include/llvm/IR", "llvm/include/llvm/CodeGen/"],
|
|
||||||
)
|
)
|
||||||
clone_repository(
|
update_intrinsics(llvm_path)
|
||||||
"llvmint",
|
|
||||||
llvmint_path,
|
|
||||||
"https://github.com/GuillaumeGomez/llvmint",
|
|
||||||
)
|
|
||||||
clone_repository(
|
|
||||||
"llvmint2",
|
|
||||||
llvmint2_path,
|
|
||||||
"https://github.com/antoyo/llvmint",
|
|
||||||
)
|
|
||||||
update_intrinsics(llvm_path, llvmint_path, llvmint2_path)
|
|
||||||
|
|
||||||
|
# llvm-tblgen can be built with:
|
||||||
|
#
|
||||||
|
# mkdir llvm-tblgen-build && cd llvm-tblgen-build
|
||||||
|
# cmake -G Ninja -DLLVM_ENABLE_PROJECTS="llvm" -DCMAKE_BUILD_TYPE=Release ../llvm
|
||||||
|
# ninja llvm-tblgen
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
sys.exit(main())
|
sys.exit(main())
|
||||||
|
|
|
||||||
2
src/gcc
2
src/gcc
|
|
@ -1 +1 @@
|
||||||
Subproject commit 0081ca6631abdfa02bf42bc85aaf507b8a0e6beb
|
Subproject commit efdd0a7290c22f5438d7c5380105d353ee3e8518
|
||||||
Loading…
Add table
Add a link
Reference in a new issue