Merge commit 'db1a31c243
' into subtree-update_cg_gcc_2025-04-18
This commit is contained in:
commit
e4ea67b3d7
52 changed files with 959 additions and 1241 deletions
|
@ -1,8 +1,10 @@
|
|||
name: CI
|
||||
|
||||
on:
|
||||
- push
|
||||
- pull_request
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
@ -121,3 +123,22 @@ jobs:
|
|||
run: |
|
||||
cd build_system
|
||||
cargo test
|
||||
|
||||
# Summary job for the merge queue.
|
||||
# ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB!
|
||||
success:
|
||||
needs: [build, duplicates, build_system]
|
||||
# We need to ensure this job does *not* get skipped if its dependencies fail,
|
||||
# because a skipped job is considered a success by GitHub. So we have to
|
||||
# overwrite `if:`. We use `!cancelled()` to ensure the job does still not get run
|
||||
# when the workflow is canceled manually.
|
||||
if: ${{ !cancelled() }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Manually check the status of all dependencies. `if: failure()` does not work.
|
||||
- name: Conclusion
|
||||
run: |
|
||||
# Print the dependent jobs to see them in the CI log
|
||||
jq -C <<< '${{ toJson(needs) }}'
|
||||
# Check if all jobs that we depend on (in the needs array) were successful.
|
||||
jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}'
|
||||
|
|
|
@ -2,7 +2,10 @@
|
|||
name: Failures
|
||||
|
||||
on:
|
||||
- pull_request
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
@ -108,3 +111,22 @@ jobs:
|
|||
echo "Error: 'the compiler unexpectedly panicked' found in output logs. CI Error!!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Summary job for the merge queue.
|
||||
# ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB!
|
||||
success_failures:
|
||||
needs: [build]
|
||||
# We need to ensure this job does *not* get skipped if its dependencies fail,
|
||||
# because a skipped job is considered a success by GitHub. So we have to
|
||||
# overwrite `if:`. We use `!cancelled()` to ensure the job does still not get run
|
||||
# when the workflow is canceled manually.
|
||||
if: ${{ !cancelled() }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Manually check the status of all dependencies. `if: failure()` does not work.
|
||||
- name: Conclusion
|
||||
run: |
|
||||
# Print the dependent jobs to see them in the CI log
|
||||
jq -C <<< '${{ toJson(needs) }}'
|
||||
# Check if all jobs that we depend on (in the needs array) were successful.
|
||||
jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}'
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
name: CI libgccjit 12
|
||||
|
||||
on:
|
||||
- push
|
||||
- pull_request
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
@ -85,3 +87,22 @@ jobs:
|
|||
#- name: Run tests
|
||||
#run: |
|
||||
#./y.sh test --release --clean --build-sysroot ${{ matrix.commands }} --no-default-features
|
||||
|
||||
# Summary job for the merge queue.
|
||||
# ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB!
|
||||
success_gcc12:
|
||||
needs: [build]
|
||||
# We need to ensure this job does *not* get skipped if its dependencies fail,
|
||||
# because a skipped job is considered a success by GitHub. So we have to
|
||||
# overwrite `if:`. We use `!cancelled()` to ensure the job does still not get run
|
||||
# when the workflow is canceled manually.
|
||||
if: ${{ !cancelled() }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Manually check the status of all dependencies. `if: failure()` does not work.
|
||||
- name: Conclusion
|
||||
run: |
|
||||
# Print the dependent jobs to see them in the CI log
|
||||
jq -C <<< '${{ toJson(needs) }}'
|
||||
# Check if all jobs that we depend on (in the needs array) were successful.
|
||||
jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}'
|
||||
|
|
|
@ -3,8 +3,10 @@
|
|||
name: m68k CI
|
||||
|
||||
on:
|
||||
- push
|
||||
- pull_request
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
@ -105,3 +107,22 @@ jobs:
|
|||
- name: Run tests
|
||||
run: |
|
||||
./y.sh test --release --clean --build-sysroot --sysroot-features compiler_builtins/no-f16-f128 ${{ matrix.commands }}
|
||||
|
||||
# Summary job for the merge queue.
|
||||
# ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB!
|
||||
success_m68k:
|
||||
needs: [build]
|
||||
# We need to ensure this job does *not* get skipped if its dependencies fail,
|
||||
# because a skipped job is considered a success by GitHub. So we have to
|
||||
# overwrite `if:`. We use `!cancelled()` to ensure the job does still not get run
|
||||
# when the workflow is canceled manually.
|
||||
if: ${{ !cancelled() }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Manually check the status of all dependencies. `if: failure()` does not work.
|
||||
- name: Conclusion
|
||||
run: |
|
||||
# Print the dependent jobs to see them in the CI log
|
||||
jq -C <<< '${{ toJson(needs) }}'
|
||||
# Check if all jobs that we depend on (in the needs array) were successful.
|
||||
jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}'
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
name: CI with sysroot compiled in release mode
|
||||
|
||||
on:
|
||||
- push
|
||||
- pull_request
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
@ -82,3 +84,22 @@ jobs:
|
|||
echo "Test is done with LTO enabled, hence inlining should occur across crates"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Summary job for the merge queue.
|
||||
# ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB!
|
||||
success_release:
|
||||
needs: [build]
|
||||
# We need to ensure this job does *not* get skipped if its dependencies fail,
|
||||
# because a skipped job is considered a success by GitHub. So we have to
|
||||
# overwrite `if:`. We use `!cancelled()` to ensure the job does still not get run
|
||||
# when the workflow is canceled manually.
|
||||
if: ${{ !cancelled() }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Manually check the status of all dependencies. `if: failure()` does not work.
|
||||
- name: Conclusion
|
||||
run: |
|
||||
# Print the dependent jobs to see them in the CI log
|
||||
jq -C <<< '${{ toJson(needs) }}'
|
||||
# Check if all jobs that we depend on (in the needs array) were successful.
|
||||
jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}'
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
name: stdarch tests with sysroot compiled in release mode
|
||||
|
||||
on:
|
||||
- push
|
||||
- pull_request
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
@ -102,3 +104,22 @@ jobs:
|
|||
# TODO: remove --skip test_mm512_stream_ps when stdarch is updated in rustc.
|
||||
# TODO: remove --skip test_tile_ when it's implemented.
|
||||
STDARCH_TEST_EVERYTHING=1 CHANNEL=release CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER="${{ matrix.cargo_runner }}" TARGET=x86_64-unknown-linux-gnu CG_RUSTFLAGS="-Ainternal_features --cfg stdarch_intel_sde" ./y.sh cargo test --manifest-path build/build_sysroot/sysroot_src/library/stdarch/Cargo.toml -- --skip rtm --skip tbm --skip sse4a --skip test_mm512_stream_ps --skip test_tile_
|
||||
|
||||
# Summary job for the merge queue.
|
||||
# ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB!
|
||||
success_stdarch:
|
||||
needs: [build]
|
||||
# We need to ensure this job does *not* get skipped if its dependencies fail,
|
||||
# because a skipped job is considered a success by GitHub. So we have to
|
||||
# overwrite `if:`. We use `!cancelled()` to ensure the job does still not get run
|
||||
# when the workflow is canceled manually.
|
||||
if: ${{ !cancelled() }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Manually check the status of all dependencies. `if: failure()` does not work.
|
||||
- name: Conclusion
|
||||
run: |
|
||||
# Print the dependent jobs to see them in the CI log
|
||||
jq -C <<< '${{ toJson(needs) }}'
|
||||
# Check if all jobs that we depend on (in the needs array) were successful.
|
||||
jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}'
|
||||
|
|
|
@ -56,18 +56,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gccjit"
|
||||
version = "2.4.0"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72fd91f4adbf02b53cfc73c97bc33c5f253009043f30c56a5ec08dd5c8094dc8"
|
||||
checksum = "2895ddec764de7ac76fe6c056050c4801a80109c066f177a00a9cc8dee02b29b"
|
||||
dependencies = [
|
||||
"gccjit_sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gccjit_sys"
|
||||
version = "0.5.0"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fb7b8f48a75e2cfe78c3d9a980b32771c34ffd12d196021ab3f98c49fbd2f0d"
|
||||
checksum = "ac133db68db8a6a8b2c51ef4b18d8ea16682d5814c4641272fe37bbbc223d5f3"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
|
|
@ -22,7 +22,7 @@ master = ["gccjit/master"]
|
|||
default = ["master"]
|
||||
|
||||
[dependencies]
|
||||
gccjit = "2.4"
|
||||
gccjit = "2.5"
|
||||
#gccjit = { git = "https://github.com/rust-lang/gccjit.rs" }
|
||||
|
||||
# Local copy.
|
||||
|
|
|
@ -23,7 +23,7 @@ A secondary goal is to check if using the gcc backend will provide any run-time
|
|||
## Building
|
||||
|
||||
**This requires a patched libgccjit in order to work.
|
||||
You need to use my [fork of gcc](https://github.com/antoyo/gcc) which already includes these patches.**
|
||||
You need to use my [fork of gcc](https://github.com/rust-lang/gcc) which already includes these patches.**
|
||||
|
||||
```bash
|
||||
$ cp config.example.toml config.toml
|
||||
|
@ -40,7 +40,7 @@ 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):
|
||||
|
||||
```bash
|
||||
$ git clone https://github.com/antoyo/gcc
|
||||
$ git clone https://github.com/rust-lang/gcc
|
||||
$ sudo apt install flex libmpfr-dev libgmp-dev libmpc3 libmpc-dev
|
||||
$ mkdir gcc-build gcc-install
|
||||
$ cd gcc-build
|
||||
|
|
|
@ -61,7 +61,7 @@ pub fn run() -> Result<(), String> {
|
|||
return Ok(());
|
||||
};
|
||||
|
||||
let result = git_clone("https://github.com/antoyo/gcc", Some(&args.out_path), false)?;
|
||||
let result = git_clone("https://github.com/rust-lang/gcc", Some(&args.out_path), false)?;
|
||||
if result.ran_clone {
|
||||
let gcc_commit = args.config_info.get_gcc_commit()?;
|
||||
println!("Checking out GCC commit `{}`...", gcc_commit);
|
||||
|
|
|
@ -529,20 +529,21 @@ fn asm_tests(env: &Env, args: &TestArg) -> Result<(), String> {
|
|||
|
||||
env.insert("COMPILETEST_FORCE_STAGE0".to_string(), "1".to_string());
|
||||
|
||||
let extra =
|
||||
if args.is_using_gcc_master_branch() { "" } else { " -Csymbol-mangling-version=v0" };
|
||||
|
||||
let rustc_args = &format!(
|
||||
r#"-Zpanic-abort-tests \
|
||||
-Zcodegen-backend="{pwd}/target/{channel}/librustc_codegen_gcc.{dylib_ext}" \
|
||||
--sysroot "{sysroot_dir}" -Cpanic=abort{extra}"#,
|
||||
let codegen_backend_path = format!(
|
||||
"{pwd}/target/{channel}/librustc_codegen_gcc.{dylib_ext}",
|
||||
pwd = std::env::current_dir()
|
||||
.map_err(|error| format!("`current_dir` failed: {:?}", error))?
|
||||
.display(),
|
||||
channel = args.config_info.channel.as_str(),
|
||||
dylib_ext = args.config_info.dylib_ext,
|
||||
sysroot_dir = args.config_info.sysroot_path,
|
||||
extra = extra,
|
||||
);
|
||||
|
||||
let extra =
|
||||
if args.is_using_gcc_master_branch() { "" } else { " -Csymbol-mangling-version=v0" };
|
||||
|
||||
let rustc_args = format!(
|
||||
"-Zpanic-abort-tests -Zcodegen-backend={codegen_backend_path} --sysroot {} -Cpanic=abort{extra}",
|
||||
args.config_info.sysroot_path
|
||||
);
|
||||
|
||||
run_command_with_env(
|
||||
|
@ -677,7 +678,7 @@ fn test_projects(env: &Env, args: &TestArg) -> Result<(), String> {
|
|||
fn test_libcore(env: &Env, args: &TestArg) -> Result<(), String> {
|
||||
// FIXME: create a function "display_if_not_quiet" or something along the line.
|
||||
println!("[TEST] libcore");
|
||||
let path = get_sysroot_dir().join("sysroot_src/library/core/tests");
|
||||
let path = get_sysroot_dir().join("sysroot_src/library/coretests");
|
||||
let _ = remove_dir_all(path.join("target"));
|
||||
run_cargo_command(&[&"test"], Some(&path), env, args)?;
|
||||
Ok(())
|
||||
|
|
|
@ -14,4 +14,4 @@ Finally, you need to update this repository by calling the relevant API you adde
|
|||
|
||||
To test it, build `gcc`, run `cargo update -p gccjit` and then you can test the generated output for a given Rust crate.
|
||||
|
||||
[gccjit.rs]: https://github.com/antoyo/gccjit.rs
|
||||
[gccjit.rs]: https://github.com/rust-lang/gccjit.rs
|
||||
|
|
|
@ -51,6 +51,10 @@ impl<T: ?Sized> LegacyReceiver for &T {}
|
|||
impl<T: ?Sized> LegacyReceiver for &mut T {}
|
||||
impl<T: ?Sized, A: Allocator> LegacyReceiver for Box<T, A> {}
|
||||
|
||||
#[lang = "receiver"]
|
||||
trait Receiver {
|
||||
}
|
||||
|
||||
#[lang = "copy"]
|
||||
pub trait Copy {}
|
||||
|
||||
|
@ -134,6 +138,14 @@ impl Mul for u8 {
|
|||
}
|
||||
}
|
||||
|
||||
impl Mul for i32 {
|
||||
type Output = Self;
|
||||
|
||||
fn mul(self, rhs: Self) -> Self::Output {
|
||||
self * rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul for usize {
|
||||
type Output = Self;
|
||||
|
||||
|
@ -142,6 +154,14 @@ impl Mul for usize {
|
|||
}
|
||||
}
|
||||
|
||||
impl Mul for isize {
|
||||
type Output = Self;
|
||||
|
||||
fn mul(self, rhs: Self) -> Self::Output {
|
||||
self * rhs
|
||||
}
|
||||
}
|
||||
|
||||
#[lang = "add"]
|
||||
pub trait Add<RHS = Self> {
|
||||
type Output;
|
||||
|
@ -165,6 +185,14 @@ impl Add for i8 {
|
|||
}
|
||||
}
|
||||
|
||||
impl Add for i32 {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Self) -> Self {
|
||||
self + rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for usize {
|
||||
type Output = Self;
|
||||
|
||||
|
@ -196,6 +224,14 @@ impl Sub for usize {
|
|||
}
|
||||
}
|
||||
|
||||
impl Sub for isize {
|
||||
type Output = Self;
|
||||
|
||||
fn sub(self, rhs: Self) -> Self {
|
||||
self - rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub for u8 {
|
||||
type Output = Self;
|
||||
|
||||
|
@ -220,6 +256,14 @@ impl Sub for i16 {
|
|||
}
|
||||
}
|
||||
|
||||
impl Sub for i32 {
|
||||
type Output = Self;
|
||||
|
||||
fn sub(self, rhs: Self) -> Self {
|
||||
self - rhs
|
||||
}
|
||||
}
|
||||
|
||||
#[lang = "rem"]
|
||||
pub trait Rem<RHS = Self> {
|
||||
type Output;
|
||||
|
@ -628,6 +672,10 @@ pub mod libc {
|
|||
pub fn memcpy(dst: *mut u8, src: *const u8, size: usize);
|
||||
pub fn memmove(dst: *mut u8, src: *const u8, size: usize);
|
||||
pub fn strncpy(dst: *mut u8, src: *const u8, size: usize);
|
||||
pub fn fflush(stream: *mut i32) -> i32;
|
||||
pub fn exit(status: i32);
|
||||
|
||||
pub static stdout: *mut i32;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
e607be166673a8de9fc07f6f02c60426e556c5f2
|
||||
0ea98a1365b81f7488073512c850e8ee951a4afd
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
From af0e237f056fa838c77463381a19b0dc993c0a35 Mon Sep 17 00:00:00 2001
|
||||
From: None <none@example.com>
|
||||
Date: Sun, 1 Sep 2024 11:42:17 -0400
|
||||
Subject: [PATCH] Disable not compiling tests
|
||||
|
||||
---
|
||||
library/core/tests/Cargo.toml | 14 ++++++++++++++
|
||||
library/core/tests/lib.rs | 1 +
|
||||
2 files changed, 15 insertions(+)
|
||||
create mode 100644 library/core/tests/Cargo.toml
|
||||
|
||||
diff --git a/library/core/tests/Cargo.toml b/library/core/tests/Cargo.toml
|
||||
new file mode 100644
|
||||
index 0000000..ca326ac
|
||||
--- /dev/null
|
||||
+++ b/library/core/tests/Cargo.toml
|
||||
@@ -0,0 +1,14 @@
|
||||
+[workspace]
|
||||
+
|
||||
+[package]
|
||||
+name = "coretests"
|
||||
+version = "0.0.0"
|
||||
+edition = "2021"
|
||||
+
|
||||
+[lib]
|
||||
+name = "coretests"
|
||||
+path = "lib.rs"
|
||||
+
|
||||
+[dependencies]
|
||||
+rand = { version = "0.8.5", default-features = false }
|
||||
+rand_xorshift = { version = "0.3.0", default-features = false }
|
||||
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
|
||||
index a4a7946..ecfe43f 100644
|
||||
--- a/library/core/tests/lib.rs
|
||||
+++ b/library/core/tests/lib.rs
|
||||
@@ -1,4 +1,5 @@
|
||||
// tidy-alphabetical-start
|
||||
+#![cfg(test)]
|
||||
#![cfg_attr(target_has_atomic = "128", feature(integer_atomics))]
|
||||
#![cfg_attr(test, feature(cfg_match))]
|
||||
#![feature(alloc_layout_extra)]
|
||||
--
|
||||
2.47.1
|
||||
|
|
@ -1,17 +1,17 @@
|
|||
From eb703e627e7a84f1cd8d0d87f0f69da1f0acf765 Mon Sep 17 00:00:00 2001
|
||||
From: bjorn3 <bjorn3@users.noreply.github.com>
|
||||
Date: Fri, 3 Dec 2021 12:16:30 +0100
|
||||
From ec2d0dc77fb484d926b45bb626b0db6a4bb0ab5c Mon Sep 17 00:00:00 2001
|
||||
From: None <none@example.com>
|
||||
Date: Thu, 27 Mar 2025 09:20:41 -0400
|
||||
Subject: [PATCH] Disable long running tests
|
||||
|
||||
---
|
||||
library/core/tests/slice.rs | 2 ++
|
||||
library/coretests/tests/slice.rs | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs
|
||||
index 8402833..84592e0 100644
|
||||
--- a/library/core/tests/slice.rs
|
||||
+++ b/library/core/tests/slice.rs
|
||||
@@ -2462,6 +2462,7 @@ take_tests! {
|
||||
diff --git a/library/coretests/tests/slice.rs b/library/coretests/tests/slice.rs
|
||||
index d17e681..fba5cd6 100644
|
||||
--- a/library/coretests/tests/slice.rs
|
||||
+++ b/library/coretests/tests/slice.rs
|
||||
@@ -2486,6 +2486,7 @@ split_off_tests! {
|
||||
#[cfg(not(miri))] // unused in Miri
|
||||
const EMPTY_MAX: &'static [()] = &[(); usize::MAX];
|
||||
|
||||
|
@ -19,14 +19,14 @@ index 8402833..84592e0 100644
|
|||
// can't be a constant due to const mutability rules
|
||||
#[cfg(not(miri))] // unused in Miri
|
||||
macro_rules! empty_max_mut {
|
||||
@@ -2485,6 +2486,7 @@ take_tests! {
|
||||
(take_mut_oob_max_range_to_inclusive, (..=usize::MAX), None, empty_max_mut!()),
|
||||
(take_mut_in_bounds_max_range_from, (usize::MAX..), Some(&mut [] as _), empty_max_mut!()),
|
||||
@@ -2509,6 +2510,7 @@ split_off_tests! {
|
||||
(split_off_mut_oob_max_range_to_inclusive, (..=usize::MAX), None, empty_max_mut!()),
|
||||
(split_off_mut_in_bounds_max_range_from, (usize::MAX..), Some(&mut [] as _), empty_max_mut!()),
|
||||
}
|
||||
+*/
|
||||
|
||||
#[test]
|
||||
fn test_slice_from_ptr_range() {
|
||||
--
|
||||
2.26.2.7.g19db9cfb68
|
||||
2.49.0
|
||||
|
||||
|
|
|
@ -1,19 +1,18 @@
|
|||
From 966beefe08be6045bfcca26079b76a7a80413080 Mon Sep 17 00:00:00 2001
|
||||
From b2911e732d1bf0e28872495c4c47af1dad3c7911 Mon Sep 17 00:00:00 2001
|
||||
From: None <none@example.com>
|
||||
Date: Thu, 28 Sep 2023 17:37:38 -0400
|
||||
Date: Thu, 27 Mar 2025 14:30:10 -0400
|
||||
Subject: [PATCH] Disable libstd and libtest dylib
|
||||
|
||||
---
|
||||
library/std/Cargo.toml | 2 +-
|
||||
library/test/Cargo.toml | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
library/std/Cargo.toml | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
|
||||
index 5b21355..cb0c49b 100644
|
||||
index 176da60..c183cdb 100644
|
||||
--- a/library/std/Cargo.toml
|
||||
+++ b/library/std/Cargo.toml
|
||||
@@ -9,7 +9,7 @@ description = "The Rust Standard Library"
|
||||
edition = "2021"
|
||||
@@ -10,7 +10,7 @@ edition = "2024"
|
||||
autobenches = false
|
||||
|
||||
[lib]
|
||||
-crate-type = ["dylib", "rlib"]
|
||||
|
@ -21,3 +20,6 @@ index 5b21355..cb0c49b 100644
|
|||
|
||||
[dependencies]
|
||||
alloc = { path = "../alloc", public = true }
|
||||
--
|
||||
2.49.0
|
||||
|
||||
|
|
|
@ -1,25 +1,17 @@
|
|||
From 124a11ce086952a5794d5cfbaa45175809497b81 Mon Sep 17 00:00:00 2001
|
||||
From 1a8f6b8e39f343959d4d2e6b6957a6d780ac3fc0 Mon Sep 17 00:00:00 2001
|
||||
From: None <none@example.com>
|
||||
Date: Sat, 18 Nov 2023 10:50:36 -0500
|
||||
Subject: [PATCH] [core] Disable portable-simd test
|
||||
Date: Thu, 27 Mar 2025 14:32:14 -0400
|
||||
Subject: [PATCH] Disable portable-simd test
|
||||
|
||||
---
|
||||
library/core/tests/lib.rs | 2 --
|
||||
1 file changed, 2 deletions(-)
|
||||
library/coretests/tests/lib.rs | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
|
||||
index b71786c..cf484d5 100644
|
||||
--- a/library/core/tests/lib.rs
|
||||
+++ b/library/core/tests/lib.rs
|
||||
@@ -87,7 +87,6 @@
|
||||
#![feature(numfmt)]
|
||||
#![feature(pattern)]
|
||||
#![feature(pointer_is_aligned_to)]
|
||||
-#![feature(portable_simd)]
|
||||
#![feature(ptr_metadata)]
|
||||
#![feature(slice_from_ptr_range)]
|
||||
#![feature(slice_internals)]
|
||||
@@ -155,7 +154,6 @@ mod pin;
|
||||
diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs
|
||||
index 79022fe..9223b2f 100644
|
||||
--- a/library/coretests/tests/lib.rs
|
||||
+++ b/library/coretests/tests/lib.rs
|
||||
@@ -165,7 +165,6 @@ mod pin;
|
||||
mod pin_macro;
|
||||
mod ptr;
|
||||
mod result;
|
||||
|
@ -27,4 +19,6 @@ index b71786c..cf484d5 100644
|
|||
mod slice;
|
||||
mod str;
|
||||
mod str_lossy;
|
||||
-- 2.45.2
|
||||
--
|
||||
2.49.0
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
[toolchain]
|
||||
channel = "nightly-2025-01-12"
|
||||
channel = "nightly-2025-04-17"
|
||||
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]
|
||||
|
|
|
@ -9,7 +9,8 @@ use rustc_middle::ty::Ty;
|
|||
use rustc_middle::ty::layout::LayoutOf;
|
||||
#[cfg(feature = "master")]
|
||||
use rustc_session::config;
|
||||
use rustc_target::callconv::{ArgAttributes, CastTarget, FnAbi, PassMode};
|
||||
#[cfg(feature = "master")]
|
||||
use rustc_target::callconv::{ArgAttributes, CastTarget, Conv, FnAbi, PassMode};
|
||||
|
||||
use crate::builder::Builder;
|
||||
use crate::context::CodegenCx;
|
||||
|
@ -105,6 +106,8 @@ pub trait FnAbiGccExt<'gcc, 'tcx> {
|
|||
// TODO(antoyo): return a function pointer type instead?
|
||||
fn gcc_type(&self, cx: &CodegenCx<'gcc, 'tcx>) -> FnAbiGcc<'gcc>;
|
||||
fn ptr_to_gcc_type(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc>;
|
||||
#[cfg(feature = "master")]
|
||||
fn gcc_cconv(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Option<FnAttribute<'gcc>>;
|
||||
}
|
||||
|
||||
impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
|
||||
|
@ -227,4 +230,47 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
|
|||
);
|
||||
pointer_type
|
||||
}
|
||||
|
||||
#[cfg(feature = "master")]
|
||||
fn gcc_cconv(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Option<FnAttribute<'gcc>> {
|
||||
conv_to_fn_attribute(self.conv, &cx.tcx.sess.target.arch)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "master")]
|
||||
pub fn conv_to_fn_attribute<'gcc>(conv: Conv, arch: &str) -> Option<FnAttribute<'gcc>> {
|
||||
// TODO: handle the calling conventions returning None.
|
||||
let attribute = match conv {
|
||||
Conv::C
|
||||
| Conv::Rust
|
||||
| Conv::CCmseNonSecureCall
|
||||
| Conv::CCmseNonSecureEntry
|
||||
| Conv::RiscvInterrupt { .. } => return None,
|
||||
Conv::Cold => return None,
|
||||
Conv::PreserveMost => return None,
|
||||
Conv::PreserveAll => return None,
|
||||
Conv::GpuKernel => {
|
||||
// TODO(antoyo): remove clippy allow attribute when this is implemented.
|
||||
#[allow(clippy::if_same_then_else)]
|
||||
if arch == "amdgpu" {
|
||||
return None;
|
||||
} else if arch == "nvptx64" {
|
||||
return None;
|
||||
} else {
|
||||
panic!("Architecture {} does not support GpuKernel calling convention", arch);
|
||||
}
|
||||
}
|
||||
Conv::AvrInterrupt => return None,
|
||||
Conv::AvrNonBlockingInterrupt => return None,
|
||||
Conv::ArmAapcs => return None,
|
||||
Conv::Msp430Intr => return None,
|
||||
Conv::X86Fastcall => return None,
|
||||
Conv::X86Intr => return None,
|
||||
Conv::X86Stdcall => return None,
|
||||
Conv::X86ThisCall => return None,
|
||||
Conv::X86VectorCall => return None,
|
||||
Conv::X86_64SysV => FnAttribute::SysvAbi,
|
||||
Conv::X86_64Win64 => FnAttribute::MsAbi,
|
||||
};
|
||||
Some(attribute)
|
||||
}
|
||||
|
|
|
@ -36,7 +36,8 @@ use crate::type_of::LayoutGccExt;
|
|||
//
|
||||
// 3. Clobbers. GCC has a separate list of clobbers, and clobbers don't have indexes.
|
||||
// Contrary, Rust expresses clobbers through "out" operands that aren't tied to
|
||||
// a variable (`_`), and such "clobbers" do have index.
|
||||
// a variable (`_`), and such "clobbers" do have index. Input operands cannot also
|
||||
// be clobbered.
|
||||
//
|
||||
// 4. Furthermore, GCC Extended Asm does not support explicit register constraints
|
||||
// (like `out("eax")`) directly, offering so-called "local register variables"
|
||||
|
@ -161,6 +162,16 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
|
|||
// Also, we don't emit any asm operands immediately; we save them to
|
||||
// the one of the buffers to be emitted later.
|
||||
|
||||
let mut input_registers = vec![];
|
||||
|
||||
for op in rust_operands {
|
||||
if let InlineAsmOperandRef::In { reg, .. } = *op {
|
||||
if let ConstraintOrRegister::Register(reg_name) = reg_to_gcc(reg) {
|
||||
input_registers.push(reg_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 1. Normal variables (and saving operands to buffers).
|
||||
for (rust_idx, op) in rust_operands.iter().enumerate() {
|
||||
match *op {
|
||||
|
@ -183,25 +194,39 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
|
|||
continue;
|
||||
}
|
||||
(Register(reg_name), None) => {
|
||||
// `clobber_abi` can add lots of clobbers that are not supported by the target,
|
||||
// such as AVX-512 registers, so we just ignore unsupported registers
|
||||
let is_target_supported =
|
||||
reg.reg_class().supported_types(asm_arch, true).iter().any(
|
||||
|&(_, feature)| {
|
||||
if let Some(feature) = feature {
|
||||
self.tcx
|
||||
.asm_target_features(instance.def_id())
|
||||
.contains(&feature)
|
||||
} else {
|
||||
true // Register class is unconditionally supported
|
||||
}
|
||||
},
|
||||
);
|
||||
if input_registers.contains(®_name) {
|
||||
// the `clobber_abi` operand is converted into a series of
|
||||
// `lateout("reg") _` operands. Of course, a user could also
|
||||
// explicitly define such an output operand.
|
||||
//
|
||||
// GCC does not allow input registers to be clobbered, so if this out register
|
||||
// is also used as an in register, do not add it to the clobbers list.
|
||||
// it will be treated as a lateout register with `out_place: None`
|
||||
if !late {
|
||||
bug!("input registers can only be used as lateout regisers");
|
||||
}
|
||||
("r", dummy_output_type(self.cx, reg.reg_class()))
|
||||
} else {
|
||||
// `clobber_abi` can add lots of clobbers that are not supported by the target,
|
||||
// such as AVX-512 registers, so we just ignore unsupported registers
|
||||
let is_target_supported =
|
||||
reg.reg_class().supported_types(asm_arch, true).iter().any(
|
||||
|&(_, feature)| {
|
||||
if let Some(feature) = feature {
|
||||
self.tcx
|
||||
.asm_target_features(instance.def_id())
|
||||
.contains(&feature)
|
||||
} else {
|
||||
true // Register class is unconditionally supported
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
if is_target_supported && !clobbers.contains(®_name) {
|
||||
clobbers.push(reg_name);
|
||||
if is_target_supported && !clobbers.contains(®_name) {
|
||||
clobbers.push(reg_name);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -230,13 +255,10 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
|
|||
}
|
||||
|
||||
InlineAsmOperandRef::InOut { reg, late, in_value, out_place } => {
|
||||
let constraint =
|
||||
if let ConstraintOrRegister::Constraint(constraint) = reg_to_gcc(reg) {
|
||||
constraint
|
||||
} else {
|
||||
// left for the next pass
|
||||
continue;
|
||||
};
|
||||
let ConstraintOrRegister::Constraint(constraint) = reg_to_gcc(reg) else {
|
||||
// left for the next pass
|
||||
continue;
|
||||
};
|
||||
|
||||
// Rustc frontend guarantees that input and output types are "compatible",
|
||||
// so we can just use input var's type for the output variable.
|
||||
|
@ -589,114 +611,127 @@ fn estimate_template_length(
|
|||
}
|
||||
|
||||
/// Converts a register class to a GCC constraint code.
|
||||
fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister {
|
||||
let constraint = match reg {
|
||||
// For vector registers LLVM wants the register name to match the type size.
|
||||
fn reg_to_gcc(reg_or_reg_class: InlineAsmRegOrRegClass) -> ConstraintOrRegister {
|
||||
match reg_or_reg_class {
|
||||
InlineAsmRegOrRegClass::Reg(reg) => {
|
||||
match reg {
|
||||
InlineAsmReg::X86(_) => {
|
||||
// TODO(antoyo): add support for vector register.
|
||||
//
|
||||
// // For explicit registers, we have to create a register variable: https://stackoverflow.com/a/31774784/389119
|
||||
return ConstraintOrRegister::Register(match reg.name() {
|
||||
// Some of registers' names does not map 1-1 from rust to gcc
|
||||
"st(0)" => "st",
|
||||
ConstraintOrRegister::Register(explicit_reg_to_gcc(reg))
|
||||
}
|
||||
InlineAsmRegOrRegClass::RegClass(reg_class) => {
|
||||
ConstraintOrRegister::Constraint(reg_class_to_gcc(reg_class))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
name => name,
|
||||
});
|
||||
fn explicit_reg_to_gcc(reg: InlineAsmReg) -> &'static str {
|
||||
// For explicit registers, we have to create a register variable: https://stackoverflow.com/a/31774784/389119
|
||||
match reg {
|
||||
InlineAsmReg::X86(reg) => {
|
||||
// TODO(antoyo): add support for vector register.
|
||||
match reg.reg_class() {
|
||||
X86InlineAsmRegClass::reg_byte => {
|
||||
// GCC does not support the `b` suffix, so we just strip it
|
||||
// see https://github.com/rust-lang/rustc_codegen_gcc/issues/485
|
||||
reg.name().trim_end_matches('b')
|
||||
}
|
||||
_ => match reg.name() {
|
||||
// Some of registers' names does not map 1-1 from rust to gcc
|
||||
"st(0)" => "st",
|
||||
|
||||
_ => unimplemented!(),
|
||||
name => name,
|
||||
},
|
||||
}
|
||||
}
|
||||
// They can be retrieved from https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html
|
||||
InlineAsmRegOrRegClass::RegClass(reg) => match reg {
|
||||
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::reg) => "r",
|
||||
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg) => "w",
|
||||
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16) => "x",
|
||||
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::preg) => {
|
||||
unreachable!("clobber-only")
|
||||
}
|
||||
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => "r",
|
||||
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg)
|
||||
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg_low16)
|
||||
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low8)
|
||||
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg_low16)
|
||||
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg_low8)
|
||||
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low4)
|
||||
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg)
|
||||
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg) => "t",
|
||||
InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg) => "r",
|
||||
InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_upper) => "d",
|
||||
InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_pair) => "r",
|
||||
InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_iw) => "w",
|
||||
InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_ptr) => "e",
|
||||
InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => "r",
|
||||
InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::wreg) => "w",
|
||||
InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => "r",
|
||||
InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::preg) => {
|
||||
unreachable!("clobber-only")
|
||||
}
|
||||
InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => "r",
|
||||
InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => "f",
|
||||
InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => "r",
|
||||
InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_addr) => "a",
|
||||
InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_data) => "d",
|
||||
InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::reg) => "r",
|
||||
InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::freg) => "f",
|
||||
InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => "d", // more specific than "r"
|
||||
InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg) => "f",
|
||||
InlineAsmRegClass::Msp430(Msp430InlineAsmRegClass::reg) => "r",
|
||||
// https://github.com/gcc-mirror/gcc/blob/master/gcc/config/nvptx/nvptx.md -> look for
|
||||
// "define_constraint".
|
||||
InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg16) => "h",
|
||||
InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg32) => "r",
|
||||
InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg64) => "l",
|
||||
|
||||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg) => "r",
|
||||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => "b",
|
||||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::freg) => "f",
|
||||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => "v",
|
||||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr)
|
||||
| InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer) => {
|
||||
unreachable!("clobber-only")
|
||||
}
|
||||
InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg) => "r",
|
||||
InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg) => "f",
|
||||
InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::vreg) => {
|
||||
unreachable!("clobber-only")
|
||||
}
|
||||
InlineAsmRegClass::X86(X86InlineAsmRegClass::reg) => "r",
|
||||
InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_abcd) => "Q",
|
||||
InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_byte) => "q",
|
||||
InlineAsmRegClass::X86(X86InlineAsmRegClass::xmm_reg)
|
||||
| InlineAsmRegClass::X86(X86InlineAsmRegClass::ymm_reg) => "x",
|
||||
InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => "v",
|
||||
InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => "Yk",
|
||||
InlineAsmRegClass::X86(
|
||||
X86InlineAsmRegClass::kreg0
|
||||
| X86InlineAsmRegClass::x87_reg
|
||||
| X86InlineAsmRegClass::mmx_reg
|
||||
| X86InlineAsmRegClass::tmm_reg,
|
||||
) => unreachable!("clobber-only"),
|
||||
InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => {
|
||||
bug!("GCC backend does not support SPIR-V")
|
||||
}
|
||||
InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => "r",
|
||||
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg) => "r",
|
||||
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg_addr) => "a",
|
||||
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => "f",
|
||||
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::vreg) => "v",
|
||||
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::areg) => {
|
||||
unreachable!("clobber-only")
|
||||
}
|
||||
InlineAsmRegClass::Sparc(SparcInlineAsmRegClass::reg) => "r",
|
||||
InlineAsmRegClass::Sparc(SparcInlineAsmRegClass::yreg) => unreachable!("clobber-only"),
|
||||
InlineAsmRegClass::Err => unreachable!(),
|
||||
},
|
||||
};
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
ConstraintOrRegister::Constraint(constraint)
|
||||
/// They can be retrieved from https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html
|
||||
fn reg_class_to_gcc(reg_class: InlineAsmRegClass) -> &'static str {
|
||||
match reg_class {
|
||||
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::reg) => "r",
|
||||
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg) => "w",
|
||||
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16) => "x",
|
||||
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::preg) => {
|
||||
unreachable!("clobber-only")
|
||||
}
|
||||
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => "r",
|
||||
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg)
|
||||
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg_low16)
|
||||
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low8)
|
||||
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg_low16)
|
||||
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg_low8)
|
||||
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low4)
|
||||
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg)
|
||||
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg) => "t",
|
||||
InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg) => "r",
|
||||
InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_upper) => "d",
|
||||
InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_pair) => "r",
|
||||
InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_iw) => "w",
|
||||
InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_ptr) => "e",
|
||||
InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => "r",
|
||||
InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::wreg) => "w",
|
||||
InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => "r",
|
||||
InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::preg) => {
|
||||
unreachable!("clobber-only")
|
||||
}
|
||||
InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => "r",
|
||||
InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => "f",
|
||||
InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => "r",
|
||||
InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_addr) => "a",
|
||||
InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_data) => "d",
|
||||
InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::reg) => "r",
|
||||
InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::freg) => "f",
|
||||
InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => "d", // more specific than "r"
|
||||
InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg) => "f",
|
||||
InlineAsmRegClass::Msp430(Msp430InlineAsmRegClass::reg) => "r",
|
||||
// https://github.com/gcc-mirror/gcc/blob/master/gcc/config/nvptx/nvptx.md -> look for
|
||||
// "define_constraint".
|
||||
InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg16) => "h",
|
||||
InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg32) => "r",
|
||||
InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg64) => "l",
|
||||
|
||||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg) => "r",
|
||||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => "b",
|
||||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::freg) => "f",
|
||||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => "v",
|
||||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr)
|
||||
| InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer) => {
|
||||
unreachable!("clobber-only")
|
||||
}
|
||||
InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg) => "r",
|
||||
InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg) => "f",
|
||||
InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::vreg) => {
|
||||
unreachable!("clobber-only")
|
||||
}
|
||||
InlineAsmRegClass::X86(X86InlineAsmRegClass::reg) => "r",
|
||||
InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_abcd) => "Q",
|
||||
InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_byte) => "q",
|
||||
InlineAsmRegClass::X86(X86InlineAsmRegClass::xmm_reg)
|
||||
| InlineAsmRegClass::X86(X86InlineAsmRegClass::ymm_reg) => "x",
|
||||
InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => "v",
|
||||
InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => "Yk",
|
||||
InlineAsmRegClass::X86(
|
||||
X86InlineAsmRegClass::kreg0
|
||||
| X86InlineAsmRegClass::x87_reg
|
||||
| X86InlineAsmRegClass::mmx_reg
|
||||
| X86InlineAsmRegClass::tmm_reg,
|
||||
) => unreachable!("clobber-only"),
|
||||
InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => {
|
||||
bug!("GCC backend does not support SPIR-V")
|
||||
}
|
||||
InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => "r",
|
||||
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg) => "r",
|
||||
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg_addr) => "a",
|
||||
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => "f",
|
||||
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::vreg) => "v",
|
||||
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::areg) => {
|
||||
unreachable!("clobber-only")
|
||||
}
|
||||
InlineAsmRegClass::Sparc(SparcInlineAsmRegClass::reg) => "r",
|
||||
InlineAsmRegClass::Sparc(SparcInlineAsmRegClass::yreg) => unreachable!("clobber-only"),
|
||||
InlineAsmRegClass::Err => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Type to use for outputs that are discarded. It doesn't really matter what
|
||||
|
|
|
@ -368,16 +368,8 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
|
|||
let previous_arg_count = args.len();
|
||||
let orig_args = args;
|
||||
let args = {
|
||||
let function_address_names = self.function_address_names.borrow();
|
||||
let original_function_name = function_address_names.get(&func_ptr);
|
||||
func_ptr = llvm::adjust_function(self.context, &func_name, func_ptr, args);
|
||||
llvm::adjust_intrinsic_arguments(
|
||||
self,
|
||||
gcc_func,
|
||||
args.into(),
|
||||
&func_name,
|
||||
original_function_name,
|
||||
)
|
||||
llvm::adjust_intrinsic_arguments(self, gcc_func, args.into(), &func_name)
|
||||
};
|
||||
let args_adjusted = args.len() != previous_arg_count;
|
||||
let args = self.check_ptr_call("call", func_ptr, &args);
|
||||
|
@ -1271,7 +1263,50 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
|
|||
}
|
||||
|
||||
fn fcmp(&mut self, op: RealPredicate, lhs: RValue<'gcc>, rhs: RValue<'gcc>) -> RValue<'gcc> {
|
||||
self.context.new_comparison(self.location, op.to_gcc_comparison(), lhs, rhs)
|
||||
// LLVM has a concept of "unordered compares", where eg ULT returns true if either the two
|
||||
// arguments are unordered (i.e. either is NaN), or the lhs is less than the rhs. GCC does
|
||||
// not natively have this concept, so in some cases we must manually handle NaNs
|
||||
let must_handle_nan = match op {
|
||||
RealPredicate::RealPredicateFalse => unreachable!(),
|
||||
RealPredicate::RealOEQ => false,
|
||||
RealPredicate::RealOGT => false,
|
||||
RealPredicate::RealOGE => false,
|
||||
RealPredicate::RealOLT => false,
|
||||
RealPredicate::RealOLE => false,
|
||||
RealPredicate::RealONE => false,
|
||||
RealPredicate::RealORD => unreachable!(),
|
||||
RealPredicate::RealUNO => unreachable!(),
|
||||
RealPredicate::RealUEQ => false,
|
||||
RealPredicate::RealUGT => true,
|
||||
RealPredicate::RealUGE => true,
|
||||
RealPredicate::RealULT => true,
|
||||
RealPredicate::RealULE => true,
|
||||
RealPredicate::RealUNE => false,
|
||||
RealPredicate::RealPredicateTrue => unreachable!(),
|
||||
};
|
||||
|
||||
let cmp = self.context.new_comparison(self.location, op.to_gcc_comparison(), lhs, rhs);
|
||||
|
||||
if must_handle_nan {
|
||||
let is_nan = self.context.new_binary_op(
|
||||
self.location,
|
||||
BinaryOp::LogicalOr,
|
||||
self.cx.bool_type,
|
||||
// compare a value to itself to check whether it is NaN
|
||||
self.context.new_comparison(self.location, ComparisonOp::NotEquals, lhs, lhs),
|
||||
self.context.new_comparison(self.location, ComparisonOp::NotEquals, rhs, rhs),
|
||||
);
|
||||
|
||||
self.context.new_binary_op(
|
||||
self.location,
|
||||
BinaryOp::LogicalOr,
|
||||
self.cx.bool_type,
|
||||
is_nan,
|
||||
cmp,
|
||||
)
|
||||
} else {
|
||||
cmp
|
||||
}
|
||||
}
|
||||
|
||||
/* Miscellaneous instructions */
|
||||
|
|
|
@ -23,6 +23,8 @@ use rustc_target::spec::{
|
|||
HasTargetSpec, HasWasmCAbiOpt, HasX86AbiOpt, Target, TlsModel, WasmCAbi, X86Abi,
|
||||
};
|
||||
|
||||
#[cfg(feature = "master")]
|
||||
use crate::abi::conv_to_fn_attribute;
|
||||
use crate::callee::get_fn;
|
||||
use crate::common::SignType;
|
||||
|
||||
|
@ -213,33 +215,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
|||
let bool_type = context.new_type::<bool>();
|
||||
|
||||
let mut functions = FxHashMap::default();
|
||||
let builtins = [
|
||||
"__builtin_unreachable",
|
||||
"abort",
|
||||
"__builtin_expect", /*"__builtin_expect_with_probability",*/
|
||||
"__builtin_constant_p",
|
||||
"__builtin_add_overflow",
|
||||
"__builtin_mul_overflow",
|
||||
"__builtin_saddll_overflow",
|
||||
/*"__builtin_sadd_overflow",*/
|
||||
"__builtin_smulll_overflow", /*"__builtin_smul_overflow",*/
|
||||
"__builtin_ssubll_overflow",
|
||||
/*"__builtin_ssub_overflow",*/ "__builtin_sub_overflow",
|
||||
"__builtin_uaddll_overflow",
|
||||
"__builtin_uadd_overflow",
|
||||
"__builtin_umulll_overflow",
|
||||
"__builtin_umul_overflow",
|
||||
"__builtin_usubll_overflow",
|
||||
"__builtin_usub_overflow",
|
||||
"__builtin_powif",
|
||||
"__builtin_powi",
|
||||
"fabsf",
|
||||
"fabs",
|
||||
"copysignf",
|
||||
"copysign",
|
||||
"nearbyintf",
|
||||
"nearbyint",
|
||||
];
|
||||
let builtins = ["abort"];
|
||||
|
||||
for builtin in builtins.iter() {
|
||||
functions.insert(builtin.to_string(), context.get_builtin_function(builtin));
|
||||
|
@ -509,7 +485,11 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
|
|||
fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function> {
|
||||
let entry_name = self.sess().target.entry_name.as_ref();
|
||||
if !self.functions.borrow().contains_key(entry_name) {
|
||||
Some(self.declare_entry_fn(entry_name, fn_type, ()))
|
||||
#[cfg(feature = "master")]
|
||||
let conv = conv_to_fn_attribute(self.sess().target.entry_abi, &self.sess().target.arch);
|
||||
#[cfg(not(feature = "master"))]
|
||||
let conv = None;
|
||||
Some(self.declare_entry_fn(entry_name, fn_type, conv))
|
||||
} else {
|
||||
// If the symbol already exists, it is an error: for example, the user wrote
|
||||
// #[no_mangle] extern "C" fn main(..) {..}
|
||||
|
@ -605,7 +585,10 @@ impl<'b, 'tcx> CodegenCx<'b, 'tcx> {
|
|||
let mut name = String::with_capacity(prefix.len() + 6);
|
||||
name.push_str(prefix);
|
||||
name.push('.');
|
||||
name.push_str(&(idx as u64).to_base(ALPHANUMERIC_ONLY));
|
||||
// Offset the index by the base so that always at least two characters
|
||||
// are generated. This avoids cases where the suffix is interpreted as
|
||||
// size by the assembler (for m68k: .b, .w, .l).
|
||||
name.push_str(&(idx as u64 + ALPHANUMERIC_ONLY as u64).to_base(ALPHANUMERIC_ONLY));
|
||||
name
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
|||
variadic: bool,
|
||||
) -> Function<'gcc> {
|
||||
self.linkage.set(FunctionType::Extern);
|
||||
declare_raw_fn(self, name, () /*llvm::CCallConv*/, return_type, params, variadic)
|
||||
declare_raw_fn(self, name, None, return_type, params, variadic)
|
||||
}
|
||||
|
||||
pub fn declare_global(
|
||||
|
@ -92,7 +92,8 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
|||
&self,
|
||||
name: &str,
|
||||
_fn_type: Type<'gcc>,
|
||||
callconv: (), /*llvm::CCallConv*/
|
||||
#[cfg(feature = "master")] callconv: Option<FnAttribute<'gcc>>,
|
||||
#[cfg(not(feature = "master"))] callconv: Option<()>,
|
||||
) -> RValue<'gcc> {
|
||||
// TODO(antoyo): use the fn_type parameter.
|
||||
let const_string = self.context.new_type::<u8>().make_pointer().make_pointer();
|
||||
|
@ -123,14 +124,11 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
|||
#[cfg(feature = "master")]
|
||||
fn_attributes,
|
||||
} = fn_abi.gcc_type(self);
|
||||
let func = declare_raw_fn(
|
||||
self,
|
||||
name,
|
||||
(), /*fn_abi.llvm_cconv()*/
|
||||
return_type,
|
||||
&arguments_type,
|
||||
is_c_variadic,
|
||||
);
|
||||
#[cfg(feature = "master")]
|
||||
let conv = fn_abi.gcc_cconv(self);
|
||||
#[cfg(not(feature = "master"))]
|
||||
let conv = None;
|
||||
let func = declare_raw_fn(self, name, conv, return_type, &arguments_type, is_c_variadic);
|
||||
self.on_stack_function_params.borrow_mut().insert(func, on_stack_param_indices);
|
||||
#[cfg(feature = "master")]
|
||||
for fn_attr in fn_attributes {
|
||||
|
@ -162,7 +160,8 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
|||
fn declare_raw_fn<'gcc>(
|
||||
cx: &CodegenCx<'gcc, '_>,
|
||||
name: &str,
|
||||
_callconv: (), /*llvm::CallConv*/
|
||||
#[cfg(feature = "master")] callconv: Option<FnAttribute<'gcc>>,
|
||||
#[cfg(not(feature = "master"))] _callconv: Option<()>,
|
||||
return_type: Type<'gcc>,
|
||||
param_types: &[Type<'gcc>],
|
||||
variadic: bool,
|
||||
|
@ -192,6 +191,10 @@ fn declare_raw_fn<'gcc>(
|
|||
let name = &mangle_name(name);
|
||||
let func =
|
||||
cx.context.new_function(None, cx.linkage.get(), return_type, ¶ms, name, variadic);
|
||||
#[cfg(feature = "master")]
|
||||
if let Some(attribute) = callconv {
|
||||
func.add_attribute(attribute);
|
||||
}
|
||||
cx.functions.borrow_mut().insert(name.to_string(), func);
|
||||
|
||||
#[cfg(feature = "master")]
|
||||
|
|
|
@ -194,6 +194,7 @@ pub fn to_gcc_features<'a>(sess: &Session, s: &'a str) -> SmallVec<[&'a str; 2]>
|
|||
|
||||
fn arch_to_gcc(name: &str) -> &str {
|
||||
match name {
|
||||
"M68000" => "68000",
|
||||
"M68020" => "68020",
|
||||
_ => name,
|
||||
}
|
||||
|
|
|
@ -432,8 +432,17 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
|
|||
);
|
||||
self.context.new_call(self.location, func, &[lhs, rhs, overflow_addr])
|
||||
};
|
||||
// NOTE: we must assign the result of the operation to a variable at this point to make
|
||||
// sure it will be evaluated by libgccjit now.
|
||||
// Otherwise, it will only be evaluated when the rvalue for the call is used somewhere else
|
||||
// and overflow_value will not be initialized at the correct point in the program.
|
||||
let result = self.current_func().new_local(self.location, res_type, "result");
|
||||
self.block.add_assignment(self.location, result, call);
|
||||
|
||||
(result, self.context.new_cast(self.location, overflow_value, self.bool_type).to_rvalue())
|
||||
(
|
||||
result.to_rvalue(),
|
||||
self.context.new_cast(self.location, overflow_value, self.bool_type).to_rvalue(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn gcc_icmp(
|
||||
|
@ -865,6 +874,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
|||
let value_type = value.get_type();
|
||||
if self.is_native_int_type_or_bool(dest_typ) && self.is_native_int_type_or_bool(value_type)
|
||||
{
|
||||
// TODO: use self.location.
|
||||
self.context.new_cast(None, value, dest_typ)
|
||||
} else if self.is_native_int_type_or_bool(dest_typ) {
|
||||
self.context.new_cast(None, self.low(value), dest_typ)
|
||||
|
@ -905,6 +915,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
|||
let name_suffix = match self.type_kind(dest_typ) {
|
||||
TypeKind::Float => "tisf",
|
||||
TypeKind::Double => "tidf",
|
||||
TypeKind::FP128 => "tixf",
|
||||
kind => panic!("cannot cast a non-native integer to type {:?}", kind),
|
||||
};
|
||||
let sign = if signed { "" } else { "un" };
|
||||
|
|
|
@ -1,11 +1,90 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use gccjit::{CType, Context, Function, FunctionPtrType, RValue, ToRValue, UnaryOp};
|
||||
use gccjit::{CType, Context, Field, Function, FunctionPtrType, RValue, ToRValue, Type};
|
||||
use rustc_codegen_ssa::traits::BuilderMethods;
|
||||
|
||||
use crate::builder::Builder;
|
||||
use crate::context::CodegenCx;
|
||||
|
||||
fn encode_key_128_type<'a, 'gcc, 'tcx>(
|
||||
builder: &Builder<'a, 'gcc, 'tcx>,
|
||||
) -> (Type<'gcc>, Field<'gcc>, Field<'gcc>) {
|
||||
let m128i = builder.context.new_vector_type(builder.i64_type, 2);
|
||||
let field1 = builder.context.new_field(None, builder.u32_type, "field1");
|
||||
let field2 = builder.context.new_field(None, m128i, "field2");
|
||||
let field3 = builder.context.new_field(None, m128i, "field3");
|
||||
let field4 = builder.context.new_field(None, m128i, "field4");
|
||||
let field5 = builder.context.new_field(None, m128i, "field5");
|
||||
let field6 = builder.context.new_field(None, m128i, "field6");
|
||||
let field7 = builder.context.new_field(None, m128i, "field7");
|
||||
let encode_type = builder.context.new_struct_type(
|
||||
None,
|
||||
"EncodeKey128Output",
|
||||
&[field1, field2, field3, field4, field5, field6, field7],
|
||||
);
|
||||
#[cfg(feature = "master")]
|
||||
encode_type.as_type().set_packed();
|
||||
(encode_type.as_type(), field1, field2)
|
||||
}
|
||||
|
||||
fn encode_key_256_type<'a, 'gcc, 'tcx>(
|
||||
builder: &Builder<'a, 'gcc, 'tcx>,
|
||||
) -> (Type<'gcc>, Field<'gcc>, Field<'gcc>) {
|
||||
let m128i = builder.context.new_vector_type(builder.i64_type, 2);
|
||||
let field1 = builder.context.new_field(None, builder.u32_type, "field1");
|
||||
let field2 = builder.context.new_field(None, m128i, "field2");
|
||||
let field3 = builder.context.new_field(None, m128i, "field3");
|
||||
let field4 = builder.context.new_field(None, m128i, "field4");
|
||||
let field5 = builder.context.new_field(None, m128i, "field5");
|
||||
let field6 = builder.context.new_field(None, m128i, "field6");
|
||||
let field7 = builder.context.new_field(None, m128i, "field7");
|
||||
let field8 = builder.context.new_field(None, m128i, "field8");
|
||||
let encode_type = builder.context.new_struct_type(
|
||||
None,
|
||||
"EncodeKey256Output",
|
||||
&[field1, field2, field3, field4, field5, field6, field7, field8],
|
||||
);
|
||||
#[cfg(feature = "master")]
|
||||
encode_type.as_type().set_packed();
|
||||
(encode_type.as_type(), field1, field2)
|
||||
}
|
||||
|
||||
fn aes_output_type<'a, 'gcc, 'tcx>(
|
||||
builder: &Builder<'a, 'gcc, 'tcx>,
|
||||
) -> (Type<'gcc>, Field<'gcc>, Field<'gcc>) {
|
||||
let m128i = builder.context.new_vector_type(builder.i64_type, 2);
|
||||
let field1 = builder.context.new_field(None, builder.u8_type, "field1");
|
||||
let field2 = builder.context.new_field(None, m128i, "field2");
|
||||
let aes_output_type = builder.context.new_struct_type(None, "AesOutput", &[field1, field2]);
|
||||
let typ = aes_output_type.as_type();
|
||||
#[cfg(feature = "master")]
|
||||
typ.set_packed();
|
||||
(typ, field1, field2)
|
||||
}
|
||||
|
||||
fn wide_aes_output_type<'a, 'gcc, 'tcx>(
|
||||
builder: &Builder<'a, 'gcc, 'tcx>,
|
||||
) -> (Type<'gcc>, Field<'gcc>, Field<'gcc>) {
|
||||
let m128i = builder.context.new_vector_type(builder.i64_type, 2);
|
||||
let field1 = builder.context.new_field(None, builder.u8_type, "field1");
|
||||
let field2 = builder.context.new_field(None, m128i, "field2");
|
||||
let field3 = builder.context.new_field(None, m128i, "field3");
|
||||
let field4 = builder.context.new_field(None, m128i, "field4");
|
||||
let field5 = builder.context.new_field(None, m128i, "field5");
|
||||
let field6 = builder.context.new_field(None, m128i, "field6");
|
||||
let field7 = builder.context.new_field(None, m128i, "field7");
|
||||
let field8 = builder.context.new_field(None, m128i, "field8");
|
||||
let field9 = builder.context.new_field(None, m128i, "field9");
|
||||
let aes_output_type = builder.context.new_struct_type(
|
||||
None,
|
||||
"WideAesOutput",
|
||||
&[field1, field2, field3, field4, field5, field6, field7, field8, field9],
|
||||
);
|
||||
#[cfg(feature = "master")]
|
||||
aes_output_type.as_type().set_packed();
|
||||
(aes_output_type.as_type(), field1, field2)
|
||||
}
|
||||
|
||||
#[cfg_attr(not(feature = "master"), allow(unused_variables))]
|
||||
pub fn adjust_function<'gcc>(
|
||||
context: &'gcc Context<'gcc>,
|
||||
|
@ -43,7 +122,6 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>(
|
|||
gcc_func: FunctionPtrType<'gcc>,
|
||||
mut args: Cow<'b, [RValue<'gcc>]>,
|
||||
func_name: &str,
|
||||
original_function_name: Option<&String>,
|
||||
) -> Cow<'b, [RValue<'gcc>]> {
|
||||
// TODO: this might not be a good way to workaround the missing tile builtins.
|
||||
if func_name == "__builtin_trap" {
|
||||
|
@ -504,6 +582,72 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>(
|
|||
let arg4 = builder.context.new_rvalue_from_int(arg4_type, -1);
|
||||
args = vec![a, b, c, arg4, new_args[3]].into();
|
||||
}
|
||||
"__builtin_ia32_encodekey128_u32" => {
|
||||
let mut new_args = args.to_vec();
|
||||
let m128i = builder.context.new_vector_type(builder.i64_type, 2);
|
||||
let array_type = builder.context.new_array_type(None, m128i, 6);
|
||||
let result = builder.current_func().new_local(None, array_type, "result");
|
||||
new_args.push(result.get_address(None));
|
||||
args = new_args.into();
|
||||
}
|
||||
"__builtin_ia32_encodekey256_u32" => {
|
||||
let mut new_args = args.to_vec();
|
||||
let m128i = builder.context.new_vector_type(builder.i64_type, 2);
|
||||
let array_type = builder.context.new_array_type(None, m128i, 7);
|
||||
let result = builder.current_func().new_local(None, array_type, "result");
|
||||
new_args.push(result.get_address(None));
|
||||
args = new_args.into();
|
||||
}
|
||||
"__builtin_ia32_aesenc128kl_u8"
|
||||
| "__builtin_ia32_aesdec128kl_u8"
|
||||
| "__builtin_ia32_aesenc256kl_u8"
|
||||
| "__builtin_ia32_aesdec256kl_u8" => {
|
||||
let mut new_args = vec![];
|
||||
let m128i = builder.context.new_vector_type(builder.i64_type, 2);
|
||||
let result = builder.current_func().new_local(None, m128i, "result");
|
||||
new_args.push(result.get_address(None));
|
||||
new_args.extend(args.to_vec());
|
||||
args = new_args.into();
|
||||
}
|
||||
"__builtin_ia32_aesencwide128kl_u8"
|
||||
| "__builtin_ia32_aesdecwide128kl_u8"
|
||||
| "__builtin_ia32_aesencwide256kl_u8"
|
||||
| "__builtin_ia32_aesdecwide256kl_u8" => {
|
||||
let mut new_args = vec![];
|
||||
|
||||
let mut old_args = args.to_vec();
|
||||
let handle = old_args.swap_remove(0); // Called __P in GCC.
|
||||
let first_value = old_args.swap_remove(0);
|
||||
|
||||
let element_type = first_value.get_type();
|
||||
let array_type = builder.context.new_array_type(None, element_type, 8);
|
||||
let result = builder.current_func().new_local(None, array_type, "result");
|
||||
new_args.push(result.get_address(None));
|
||||
|
||||
let array = builder.current_func().new_local(None, array_type, "array");
|
||||
let input = builder.context.new_array_constructor(
|
||||
None,
|
||||
array_type,
|
||||
&[
|
||||
first_value,
|
||||
old_args.swap_remove(0),
|
||||
old_args.swap_remove(0),
|
||||
old_args.swap_remove(0),
|
||||
old_args.swap_remove(0),
|
||||
old_args.swap_remove(0),
|
||||
old_args.swap_remove(0),
|
||||
old_args.swap_remove(0),
|
||||
],
|
||||
);
|
||||
builder.llbb().add_assignment(None, array, input);
|
||||
let input_ptr = array.get_address(None);
|
||||
let arg2_type = gcc_func.get_param_type(1);
|
||||
let input_ptr = builder.context.new_cast(None, input_ptr, arg2_type);
|
||||
new_args.push(input_ptr);
|
||||
|
||||
new_args.push(handle);
|
||||
args = new_args.into();
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
} else {
|
||||
|
@ -541,33 +685,6 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>(
|
|||
let c = builder.context.new_rvalue_from_vector(None, arg3_type, &[new_args[2]; 2]);
|
||||
args = vec![a, b, c, new_args[3]].into();
|
||||
}
|
||||
"__builtin_ia32_vfmaddsubpd256"
|
||||
| "__builtin_ia32_vfmaddsubps"
|
||||
| "__builtin_ia32_vfmaddsubps256"
|
||||
| "__builtin_ia32_vfmaddsubpd" => {
|
||||
if let Some(original_function_name) = original_function_name {
|
||||
match &**original_function_name {
|
||||
"llvm.x86.fma.vfmsubadd.pd.256"
|
||||
| "llvm.x86.fma.vfmsubadd.ps"
|
||||
| "llvm.x86.fma.vfmsubadd.ps.256"
|
||||
| "llvm.x86.fma.vfmsubadd.pd" => {
|
||||
// NOTE: since both llvm.x86.fma.vfmsubadd.ps and llvm.x86.fma.vfmaddsub.ps maps to
|
||||
// __builtin_ia32_vfmaddsubps, only add minus if this comes from a
|
||||
// subadd LLVM intrinsic, e.g. _mm256_fmsubadd_pd.
|
||||
let mut new_args = args.to_vec();
|
||||
let arg3 = &mut new_args[2];
|
||||
*arg3 = builder.context.new_unary_op(
|
||||
None,
|
||||
UnaryOp::Minus,
|
||||
arg3.get_type(),
|
||||
*arg3,
|
||||
);
|
||||
args = new_args.into();
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
"__builtin_ia32_ldmxcsr" => {
|
||||
// The builtin __builtin_ia32_ldmxcsr takes an integer value while llvm.x86.sse.ldmxcsr takes a pointer,
|
||||
// so dereference the pointer.
|
||||
|
@ -728,6 +845,96 @@ pub fn adjust_intrinsic_return_value<'a, 'gcc, 'tcx>(
|
|||
let f16_type = builder.context.new_c_type(CType::Float16);
|
||||
return_value = builder.context.new_cast(None, return_value, f16_type);
|
||||
}
|
||||
"__builtin_ia32_encodekey128_u32" => {
|
||||
// The builtin __builtin_ia32_encodekey128_u32 writes the result in its pointer argument while
|
||||
// llvm.x86.encodekey128 returns a value.
|
||||
// We added a result pointer argument and now need to assign its value to the return_value expected by
|
||||
// the LLVM intrinsic.
|
||||
let (encode_type, field1, field2) = encode_key_128_type(builder);
|
||||
let result = builder.current_func().new_local(None, encode_type, "result");
|
||||
let field1 = result.access_field(None, field1);
|
||||
builder.llbb().add_assignment(None, field1, return_value);
|
||||
let field2 = result.access_field(None, field2);
|
||||
let field2_type = field2.to_rvalue().get_type();
|
||||
let array_type = builder.context.new_array_type(None, field2_type, 6);
|
||||
let ptr = builder.context.new_cast(None, args[2], array_type.make_pointer());
|
||||
let field2_ptr =
|
||||
builder.context.new_cast(None, field2.get_address(None), array_type.make_pointer());
|
||||
builder.llbb().add_assignment(
|
||||
None,
|
||||
field2_ptr.dereference(None),
|
||||
ptr.dereference(None),
|
||||
);
|
||||
return_value = result.to_rvalue();
|
||||
}
|
||||
"__builtin_ia32_encodekey256_u32" => {
|
||||
// The builtin __builtin_ia32_encodekey256_u32 writes the result in its pointer argument while
|
||||
// llvm.x86.encodekey256 returns a value.
|
||||
// We added a result pointer argument and now need to assign its value to the return_value expected by
|
||||
// the LLVM intrinsic.
|
||||
let (encode_type, field1, field2) = encode_key_256_type(builder);
|
||||
let result = builder.current_func().new_local(None, encode_type, "result");
|
||||
let field1 = result.access_field(None, field1);
|
||||
builder.llbb().add_assignment(None, field1, return_value);
|
||||
let field2 = result.access_field(None, field2);
|
||||
let field2_type = field2.to_rvalue().get_type();
|
||||
let array_type = builder.context.new_array_type(None, field2_type, 7);
|
||||
let ptr = builder.context.new_cast(None, args[3], array_type.make_pointer());
|
||||
let field2_ptr =
|
||||
builder.context.new_cast(None, field2.get_address(None), array_type.make_pointer());
|
||||
builder.llbb().add_assignment(
|
||||
None,
|
||||
field2_ptr.dereference(None),
|
||||
ptr.dereference(None),
|
||||
);
|
||||
return_value = result.to_rvalue();
|
||||
}
|
||||
"__builtin_ia32_aesdec128kl_u8"
|
||||
| "__builtin_ia32_aesenc128kl_u8"
|
||||
| "__builtin_ia32_aesdec256kl_u8"
|
||||
| "__builtin_ia32_aesenc256kl_u8" => {
|
||||
// The builtin for aesdec/aesenc writes the result in its pointer argument while
|
||||
// llvm.x86.aesdec128kl returns a value.
|
||||
// We added a result pointer argument and now need to assign its value to the return_value expected by
|
||||
// the LLVM intrinsic.
|
||||
let (aes_output_type, field1, field2) = aes_output_type(builder);
|
||||
let result = builder.current_func().new_local(None, aes_output_type, "result");
|
||||
let field1 = result.access_field(None, field1);
|
||||
builder.llbb().add_assignment(None, field1, return_value);
|
||||
let field2 = result.access_field(None, field2);
|
||||
let ptr = builder.context.new_cast(
|
||||
None,
|
||||
args[0],
|
||||
field2.to_rvalue().get_type().make_pointer(),
|
||||
);
|
||||
builder.llbb().add_assignment(None, field2, ptr.dereference(None));
|
||||
return_value = result.to_rvalue();
|
||||
}
|
||||
"__builtin_ia32_aesencwide128kl_u8"
|
||||
| "__builtin_ia32_aesdecwide128kl_u8"
|
||||
| "__builtin_ia32_aesencwide256kl_u8"
|
||||
| "__builtin_ia32_aesdecwide256kl_u8" => {
|
||||
// The builtin for aesdecwide/aesencwide writes the result in its pointer argument while
|
||||
// llvm.x86.aesencwide128kl returns a value.
|
||||
// We added a result pointer argument and now need to assign its value to the return_value expected by
|
||||
// the LLVM intrinsic.
|
||||
let (aes_output_type, field1, field2) = wide_aes_output_type(builder);
|
||||
let result = builder.current_func().new_local(None, aes_output_type, "result");
|
||||
let field1 = result.access_field(None, field1);
|
||||
builder.llbb().add_assignment(None, field1, return_value);
|
||||
let field2 = result.access_field(None, field2);
|
||||
let field2_type = field2.to_rvalue().get_type();
|
||||
let array_type = builder.context.new_array_type(None, field2_type, 8);
|
||||
let ptr = builder.context.new_cast(None, args[0], array_type.make_pointer());
|
||||
let field2_ptr =
|
||||
builder.context.new_cast(None, field2.get_address(None), array_type.make_pointer());
|
||||
builder.llbb().add_assignment(
|
||||
None,
|
||||
field2_ptr.dereference(None),
|
||||
ptr.dereference(None),
|
||||
);
|
||||
return_value = result.to_rvalue();
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
|
@ -915,16 +1122,6 @@ pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function
|
|||
"llvm.ctlz.v4i64" => "__builtin_ia32_vplzcntq_256_mask",
|
||||
"llvm.ctlz.v2i64" => "__builtin_ia32_vplzcntq_128_mask",
|
||||
"llvm.ctpop.v32i16" => "__builtin_ia32_vpopcountw_v32hi",
|
||||
"llvm.x86.fma.vfmsub.sd" => "__builtin_ia32_vfmsubsd3",
|
||||
"llvm.x86.fma.vfmsub.ss" => "__builtin_ia32_vfmsubss3",
|
||||
"llvm.x86.fma.vfmsubadd.pd" => "__builtin_ia32_vfmaddsubpd",
|
||||
"llvm.x86.fma.vfmsubadd.pd.256" => "__builtin_ia32_vfmaddsubpd256",
|
||||
"llvm.x86.fma.vfmsubadd.ps" => "__builtin_ia32_vfmaddsubps",
|
||||
"llvm.x86.fma.vfmsubadd.ps.256" => "__builtin_ia32_vfmaddsubps256",
|
||||
"llvm.x86.fma.vfnmadd.sd" => "__builtin_ia32_vfnmaddsd3",
|
||||
"llvm.x86.fma.vfnmadd.ss" => "__builtin_ia32_vfnmaddss3",
|
||||
"llvm.x86.fma.vfnmsub.sd" => "__builtin_ia32_vfnmsubsd3",
|
||||
"llvm.x86.fma.vfnmsub.ss" => "__builtin_ia32_vfnmsubss3",
|
||||
"llvm.x86.avx512.conflict.d.512" => "__builtin_ia32_vpconflictsi_512_mask",
|
||||
"llvm.x86.avx512.conflict.d.256" => "__builtin_ia32_vpconflictsi_256_mask",
|
||||
"llvm.x86.avx512.conflict.d.128" => "__builtin_ia32_vpconflictsi_128_mask",
|
||||
|
@ -1002,8 +1199,6 @@ pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function
|
|||
"llvm.fshr.v32i16" => "__builtin_ia32_vpshrdv_v32hi",
|
||||
"llvm.fshr.v16i16" => "__builtin_ia32_vpshrdv_v16hi",
|
||||
"llvm.fshr.v8i16" => "__builtin_ia32_vpshrdv_v8hi",
|
||||
"llvm.x86.fma.vfmadd.sd" => "__builtin_ia32_vfmaddsd3",
|
||||
"llvm.x86.fma.vfmadd.ss" => "__builtin_ia32_vfmaddss3",
|
||||
"llvm.x86.rdrand.64" => "__builtin_ia32_rdrand64_step",
|
||||
|
||||
// The above doc points to unknown builtins for the following, so override them:
|
||||
|
@ -1324,6 +1519,16 @@ pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function
|
|||
"llvm.x86.avx512fp16.mask.vfmadd.cph.256" => "__builtin_ia32_vfmaddcph256_mask3",
|
||||
"llvm.x86.avx512fp16.mask.vfcmadd.cph.128" => "__builtin_ia32_vfcmaddcph128_mask3",
|
||||
"llvm.x86.avx512fp16.mask.vfmadd.cph.128" => "__builtin_ia32_vfmaddcph128_mask3",
|
||||
"llvm.x86.encodekey128" => "__builtin_ia32_encodekey128_u32",
|
||||
"llvm.x86.encodekey256" => "__builtin_ia32_encodekey256_u32",
|
||||
"llvm.x86.aesenc128kl" => "__builtin_ia32_aesenc128kl_u8",
|
||||
"llvm.x86.aesdec128kl" => "__builtin_ia32_aesdec128kl_u8",
|
||||
"llvm.x86.aesenc256kl" => "__builtin_ia32_aesenc256kl_u8",
|
||||
"llvm.x86.aesdec256kl" => "__builtin_ia32_aesdec256kl_u8",
|
||||
"llvm.x86.aesencwide128kl" => "__builtin_ia32_aesencwide128kl_u8",
|
||||
"llvm.x86.aesdecwide128kl" => "__builtin_ia32_aesdecwide128kl_u8",
|
||||
"llvm.x86.aesencwide256kl" => "__builtin_ia32_aesencwide256kl_u8",
|
||||
"llvm.x86.aesdecwide256kl" => "__builtin_ia32_aesdecwide256kl_u8",
|
||||
|
||||
// TODO: support the tile builtins:
|
||||
"llvm.x86.ldtilecfg" => "__builtin_trap",
|
||||
|
|
|
@ -78,6 +78,7 @@ fn get_simple_intrinsic<'gcc, 'tcx>(
|
|||
sym::maxnumf64 => "fmax",
|
||||
sym::copysignf32 => "copysignf",
|
||||
sym::copysignf64 => "copysign",
|
||||
sym::copysignf128 => "copysignl",
|
||||
sym::floorf32 => "floorf",
|
||||
sym::floorf64 => "floor",
|
||||
sym::ceilf32 => "ceilf",
|
||||
|
|
|
@ -399,7 +399,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
|||
}
|
||||
|
||||
#[cfg(feature = "master")]
|
||||
if name == sym::simd_insert {
|
||||
if name == sym::simd_insert || name == sym::simd_insert_dyn {
|
||||
require!(
|
||||
in_elem == arg_tys[2],
|
||||
InvalidMonomorphization::InsertedType {
|
||||
|
@ -410,6 +410,8 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
|||
out_ty: arg_tys[2]
|
||||
}
|
||||
);
|
||||
|
||||
// TODO(antoyo): For simd_insert, check if the index is a constant of the correct size.
|
||||
let vector = args[0].immediate();
|
||||
let index = args[1].immediate();
|
||||
let value = args[2].immediate();
|
||||
|
@ -422,13 +424,15 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
|||
}
|
||||
|
||||
#[cfg(feature = "master")]
|
||||
if name == sym::simd_extract {
|
||||
if name == sym::simd_extract || name == sym::simd_extract_dyn {
|
||||
require!(
|
||||
ret_ty == in_elem,
|
||||
InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
|
||||
);
|
||||
// TODO(antoyo): For simd_extract, check if the index is a constant of the correct size.
|
||||
let vector = args[0].immediate();
|
||||
return Ok(bx.context.new_vector_access(None, vector, args[1].immediate()).to_rvalue());
|
||||
let index = args[1].immediate();
|
||||
return Ok(bx.context.new_vector_access(None, vector, index).to_rvalue());
|
||||
}
|
||||
|
||||
if name == sym::simd_select {
|
||||
|
|
|
@ -188,10 +188,10 @@ impl CodegenBackend for GccCodegenBackend {
|
|||
crate::DEFAULT_LOCALE_RESOURCE
|
||||
}
|
||||
|
||||
fn init(&self, sess: &Session) {
|
||||
fn init(&self, _sess: &Session) {
|
||||
#[cfg(feature = "master")]
|
||||
{
|
||||
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.
|
||||
let context = Context::default();
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
tests/ui/allocator/no_std-alloc-error-handler-custom.rs
|
||||
tests/ui/allocator/no_std-alloc-error-handler-default.rs
|
||||
tests/ui/asm/may_unwind.rs
|
||||
tests/ui/asm/x86_64/multiple-clobber-abi.rs
|
||||
tests/ui/functions-closures/parallel-codegen-closures.rs
|
||||
tests/ui/linkage-attr/linkage1.rs
|
||||
tests/ui/lto/dylib-works.rs
|
||||
tests/ui/numbers-arithmetic/saturating-float-casts.rs
|
||||
tests/ui/sepcomp/sepcomp-cci.rs
|
||||
tests/ui/sepcomp/sepcomp-extern.rs
|
||||
tests/ui/sepcomp/sepcomp-fns-backwards.rs
|
||||
|
@ -33,7 +31,6 @@ tests/ui/unwind-no-uwtable.rs
|
|||
tests/ui/parser/unclosed-delimiter-in-dep.rs
|
||||
tests/ui/consts/missing_span_in_backtrace.rs
|
||||
tests/ui/drop/dynamic-drop.rs
|
||||
tests/ui/issues/issue-40883.rs
|
||||
tests/ui/issues/issue-43853.rs
|
||||
tests/ui/issues/issue-47364.rs
|
||||
tests/ui/macros/rfc-2011-nicer-assert-messages/assert-without-captures-does-not-create-unnecessary-code.rs
|
||||
|
@ -102,14 +99,12 @@ tests/ui/codegen/equal-pointers-unequal/as-cast/basic.rs
|
|||
tests/ui/codegen/equal-pointers-unequal/as-cast/inline1.rs
|
||||
tests/ui/codegen/equal-pointers-unequal/as-cast/print.rs
|
||||
tests/ui/codegen/equal-pointers-unequal/as-cast/inline2.rs
|
||||
tests/ui/codegen/equal-pointers-unequal/as-cast/print3.rs
|
||||
tests/ui/codegen/equal-pointers-unequal/as-cast/segfault.rs
|
||||
tests/ui/codegen/equal-pointers-unequal/exposed-provenance/function.rs
|
||||
tests/ui/codegen/equal-pointers-unequal/exposed-provenance/basic.rs
|
||||
tests/ui/codegen/equal-pointers-unequal/as-cast/zero.rs
|
||||
tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline1.rs
|
||||
tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print.rs
|
||||
tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print3.rs
|
||||
tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline2.rs
|
||||
tests/ui/codegen/equal-pointers-unequal/exposed-provenance/segfault.rs
|
||||
tests/ui/codegen/equal-pointers-unequal/exposed-provenance/zero.rs
|
||||
|
@ -117,8 +112,9 @@ tests/ui/codegen/equal-pointers-unequal/strict-provenance/basic.rs
|
|||
tests/ui/codegen/equal-pointers-unequal/strict-provenance/function.rs
|
||||
tests/ui/codegen/equal-pointers-unequal/strict-provenance/print.rs
|
||||
tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline1.rs
|
||||
tests/ui/codegen/equal-pointers-unequal/strict-provenance/print3.rs
|
||||
tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline2.rs
|
||||
tests/ui/codegen/equal-pointers-unequal/strict-provenance/segfault.rs
|
||||
tests/ui/codegen/equal-pointers-unequal/strict-provenance/zero.rs
|
||||
tests/ui/simd/simd-bitmask-notpow2.rs
|
||||
tests/ui/codegen/StackColoring-not-blowup-stack-issue-40883.rs
|
||||
tests/ui/uninhabited/uninhabited-transparent-return-abi.rs
|
||||
|
|
|
@ -3,45 +3,13 @@
|
|||
// Run-time:
|
||||
// status: signal
|
||||
|
||||
#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs)]
|
||||
#![allow(internal_features)]
|
||||
|
||||
#![feature(no_core)]
|
||||
#![no_std]
|
||||
#![no_core]
|
||||
#![no_main]
|
||||
|
||||
/*
|
||||
* Core
|
||||
*/
|
||||
|
||||
// Because we don't have core yet.
|
||||
#[lang = "sized"]
|
||||
pub trait Sized {}
|
||||
|
||||
#[lang = "copy"]
|
||||
trait Copy {
|
||||
}
|
||||
|
||||
impl Copy for isize {}
|
||||
|
||||
#[lang = "receiver"]
|
||||
trait Receiver {
|
||||
}
|
||||
|
||||
#[lang = "freeze"]
|
||||
pub(crate) unsafe auto trait Freeze {}
|
||||
|
||||
mod intrinsics {
|
||||
use super::Sized;
|
||||
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
pub fn abort() -> !;
|
||||
}
|
||||
|
||||
/*
|
||||
* Code
|
||||
*/
|
||||
extern crate mini_core;
|
||||
use mini_core::*;
|
||||
|
||||
fn test_fail() -> ! {
|
||||
unsafe { intrinsics::abort() };
|
||||
|
|
|
@ -3,45 +3,13 @@
|
|||
// Run-time:
|
||||
// status: signal
|
||||
|
||||
#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs)]
|
||||
#![allow(internal_features)]
|
||||
|
||||
#![feature(no_core)]
|
||||
#![no_std]
|
||||
#![no_core]
|
||||
#![no_main]
|
||||
|
||||
/*
|
||||
* Core
|
||||
*/
|
||||
|
||||
// Because we don't have core yet.
|
||||
#[lang = "sized"]
|
||||
pub trait Sized {}
|
||||
|
||||
#[lang = "copy"]
|
||||
trait Copy {
|
||||
}
|
||||
|
||||
impl Copy for isize {}
|
||||
|
||||
#[lang = "receiver"]
|
||||
trait Receiver {
|
||||
}
|
||||
|
||||
#[lang = "freeze"]
|
||||
pub(crate) unsafe auto trait Freeze {}
|
||||
|
||||
mod intrinsics {
|
||||
use super::Sized;
|
||||
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
pub fn abort() -> !;
|
||||
}
|
||||
|
||||
/*
|
||||
* Code
|
||||
*/
|
||||
extern crate mini_core;
|
||||
use mini_core::*;
|
||||
|
||||
fn fail() -> i32 {
|
||||
unsafe { intrinsics::abort() };
|
||||
|
|
|
@ -8,20 +8,12 @@
|
|||
// 10
|
||||
|
||||
#![feature(no_core)]
|
||||
|
||||
#![no_std]
|
||||
#![no_core]
|
||||
#![no_main]
|
||||
|
||||
extern crate mini_core;
|
||||
|
||||
mod libc {
|
||||
#[link(name = "c")]
|
||||
extern "C" {
|
||||
pub fn printf(format: *const i8, ...) -> i32;
|
||||
pub fn puts(s: *const u8) -> i32;
|
||||
}
|
||||
}
|
||||
use mini_core::*;
|
||||
|
||||
static mut ONE: usize = 1;
|
||||
|
||||
|
|
|
@ -174,6 +174,59 @@ fn asm() {
|
|||
mem_cpy(array2.as_mut_ptr(), array1.as_ptr(), 3);
|
||||
}
|
||||
assert_eq!(array1, array2);
|
||||
|
||||
// in and clobber registers cannot overlap. This tests that the lateout register without an
|
||||
// output place (indicated by the `_`) is not added to the list of clobbered registers
|
||||
let x = 8;
|
||||
let y: i32;
|
||||
unsafe {
|
||||
asm!(
|
||||
"mov rax, rdi",
|
||||
in("rdi") x,
|
||||
lateout("rdi") _,
|
||||
out("rax") y,
|
||||
);
|
||||
}
|
||||
assert_eq!((x, y), (8, 8));
|
||||
|
||||
// sysv64 is the default calling convention on unix systems. The rdi register is
|
||||
// used to pass arguments in the sysv64 calling convention, so this register will be clobbered
|
||||
#[cfg(unix)]
|
||||
{
|
||||
let x = 16;
|
||||
let y: i32;
|
||||
unsafe {
|
||||
asm!(
|
||||
"mov rax, rdi",
|
||||
in("rdi") x,
|
||||
out("rax") y,
|
||||
clobber_abi("sysv64"),
|
||||
);
|
||||
}
|
||||
assert_eq!((x, y), (16, 16));
|
||||
}
|
||||
|
||||
// the `b` suffix for registers in the `reg_byte` register class is not supported in GCC
|
||||
// and needs to be stripped in order to use these registers.
|
||||
unsafe {
|
||||
core::arch::asm!(
|
||||
"",
|
||||
out("al") _,
|
||||
out("bl") _,
|
||||
out("cl") _,
|
||||
out("dl") _,
|
||||
out("sil") _,
|
||||
out("dil") _,
|
||||
out("r8b") _,
|
||||
out("r9b") _,
|
||||
out("r10b") _,
|
||||
out("r11b") _,
|
||||
out("r12b") _,
|
||||
out("r13b") _,
|
||||
out("r14b") _,
|
||||
out("r15b") _,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "x86_64"))]
|
||||
|
|
|
@ -5,130 +5,13 @@
|
|||
// 7 8
|
||||
// 10
|
||||
|
||||
#![allow(internal_features, unused_attributes)]
|
||||
#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs, track_caller)]
|
||||
|
||||
#![feature(no_core)]
|
||||
#![no_std]
|
||||
#![no_core]
|
||||
#![no_main]
|
||||
|
||||
/*
|
||||
* Core
|
||||
*/
|
||||
|
||||
// Because we don't have core yet.
|
||||
#[lang = "sized"]
|
||||
pub trait Sized {}
|
||||
|
||||
#[lang = "copy"]
|
||||
trait Copy {
|
||||
}
|
||||
|
||||
impl Copy for isize {}
|
||||
impl Copy for *mut i32 {}
|
||||
impl Copy for usize {}
|
||||
impl Copy for u8 {}
|
||||
impl Copy for i8 {}
|
||||
impl Copy for i32 {}
|
||||
|
||||
#[lang = "receiver"]
|
||||
trait Receiver {
|
||||
}
|
||||
|
||||
#[lang = "freeze"]
|
||||
pub(crate) unsafe auto trait Freeze {}
|
||||
|
||||
#[lang = "panic_location"]
|
||||
struct PanicLocation {
|
||||
file: &'static str,
|
||||
line: u32,
|
||||
column: u32,
|
||||
}
|
||||
|
||||
mod libc {
|
||||
#[link(name = "c")]
|
||||
extern "C" {
|
||||
pub fn puts(s: *const u8) -> i32;
|
||||
pub fn fflush(stream: *mut i32) -> i32;
|
||||
pub fn printf(format: *const i8, ...) -> i32;
|
||||
|
||||
pub static stdout: *mut i32;
|
||||
}
|
||||
}
|
||||
|
||||
mod intrinsics {
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
pub fn abort() -> !;
|
||||
}
|
||||
|
||||
#[lang = "panic"]
|
||||
#[track_caller]
|
||||
#[no_mangle]
|
||||
pub fn panic(_msg: &'static str) -> ! {
|
||||
unsafe {
|
||||
libc::puts("Panicking\0" as *const str as *const u8);
|
||||
libc::fflush(libc::stdout);
|
||||
intrinsics::abort();
|
||||
}
|
||||
}
|
||||
|
||||
#[lang = "add"]
|
||||
trait Add<RHS = Self> {
|
||||
type Output;
|
||||
|
||||
fn add(self, rhs: RHS) -> Self::Output;
|
||||
}
|
||||
|
||||
impl Add for u8 {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Self) -> Self {
|
||||
self + rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for i8 {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Self) -> Self {
|
||||
self + rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for i32 {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Self) -> Self {
|
||||
self + rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for usize {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Self) -> Self {
|
||||
self + rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for isize {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Self) -> Self {
|
||||
self + rhs
|
||||
}
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
#[lang = "panic_const_add_overflow"]
|
||||
pub fn panic_const_add_overflow() -> ! {
|
||||
panic("attempt to add with overflow");
|
||||
}
|
||||
|
||||
/*
|
||||
* Code
|
||||
*/
|
||||
extern crate mini_core;
|
||||
use mini_core::*;
|
||||
|
||||
fn inc_ref(num: &mut isize) -> isize {
|
||||
*num = *num + 5;
|
||||
|
@ -139,9 +22,8 @@ fn inc(num: isize) -> isize {
|
|||
num + 1
|
||||
}
|
||||
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
|
||||
extern "C" fn main(mut argc: isize, _argv: *const *const u8) -> i32 {
|
||||
argc = inc(argc);
|
||||
unsafe {
|
||||
libc::printf(b"%ld\n\0" as *const u8 as *const i8, argc);
|
||||
|
|
|
@ -9,55 +9,38 @@
|
|||
// Both args: 11
|
||||
|
||||
#![feature(no_core)]
|
||||
|
||||
#![no_std]
|
||||
#![no_core]
|
||||
#![no_main]
|
||||
|
||||
extern crate mini_core;
|
||||
|
||||
mod libc {
|
||||
#[link(name = "c")]
|
||||
extern "C" {
|
||||
pub fn printf(format: *const i8, ...) -> i32;
|
||||
}
|
||||
}
|
||||
use mini_core::*;
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
|
||||
extern "C" fn main(argc: isize, _argv: *const *const u8) -> i32 {
|
||||
let string = "Arg: %d\n\0";
|
||||
let mut closure = || {
|
||||
unsafe {
|
||||
libc::printf(string as *const str as *const i8, argc);
|
||||
}
|
||||
let mut closure = || unsafe {
|
||||
libc::printf(string as *const str as *const i8, argc);
|
||||
};
|
||||
closure();
|
||||
|
||||
let mut closure = || {
|
||||
unsafe {
|
||||
libc::printf("Argument: %d\n\0" as *const str as *const i8, argc);
|
||||
}
|
||||
let mut closure = || unsafe {
|
||||
libc::printf("Argument: %d\n\0" as *const str as *const i8, argc);
|
||||
};
|
||||
closure();
|
||||
|
||||
let mut closure = |string| {
|
||||
unsafe {
|
||||
libc::printf(string as *const str as *const i8, argc);
|
||||
}
|
||||
let mut closure = |string| unsafe {
|
||||
libc::printf(string as *const str as *const i8, argc);
|
||||
};
|
||||
closure("String arg: %d\n\0");
|
||||
|
||||
let mut closure = |arg: isize| {
|
||||
unsafe {
|
||||
libc::printf("Int argument: %d\n\0" as *const str as *const i8, arg);
|
||||
}
|
||||
let mut closure = |arg: isize| unsafe {
|
||||
libc::printf("Int argument: %d\n\0" as *const str as *const i8, arg);
|
||||
};
|
||||
closure(argc + 1);
|
||||
|
||||
let mut closure = |string, arg: isize| {
|
||||
unsafe {
|
||||
libc::printf(string as *const str as *const i8, arg);
|
||||
}
|
||||
let mut closure = |string, arg: isize| unsafe {
|
||||
libc::printf(string as *const str as *const i8, arg);
|
||||
};
|
||||
closure("Both args: %d\n\0", argc + 10);
|
||||
|
||||
|
|
|
@ -6,19 +6,12 @@
|
|||
// 1
|
||||
|
||||
#![feature(no_core)]
|
||||
|
||||
#![no_std]
|
||||
#![no_core]
|
||||
#![no_main]
|
||||
|
||||
extern crate mini_core;
|
||||
|
||||
mod libc {
|
||||
#[link(name = "c")]
|
||||
extern "C" {
|
||||
pub fn printf(format: *const i8, ...) -> i32;
|
||||
}
|
||||
}
|
||||
use mini_core::*;
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
|
||||
|
@ -27,15 +20,14 @@ extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
|
|||
libc::printf(b"true\n\0" as *const u8 as *const i8);
|
||||
}
|
||||
|
||||
let string =
|
||||
match argc {
|
||||
1 => b"1\n\0",
|
||||
2 => b"2\n\0",
|
||||
3 => b"3\n\0",
|
||||
4 => b"4\n\0",
|
||||
5 => b"5\n\0",
|
||||
_ => b"_\n\0",
|
||||
};
|
||||
let string = match argc {
|
||||
1 => b"1\n\0",
|
||||
2 => b"2\n\0",
|
||||
3 => b"3\n\0",
|
||||
4 => b"4\n\0",
|
||||
5 => b"5\n\0",
|
||||
_ => b"_\n\0",
|
||||
};
|
||||
libc::printf(string as *const u8 as *const i8);
|
||||
}
|
||||
0
|
||||
|
|
|
@ -3,37 +3,13 @@
|
|||
// Run-time:
|
||||
// status: 0
|
||||
|
||||
#![feature(auto_traits, lang_items, no_core)]
|
||||
#![allow(internal_features)]
|
||||
|
||||
#![feature(no_core)]
|
||||
#![no_std]
|
||||
#![no_core]
|
||||
#![no_main]
|
||||
|
||||
/*
|
||||
* Core
|
||||
*/
|
||||
|
||||
// Because we don't have core yet.
|
||||
#[lang = "sized"]
|
||||
pub trait Sized {}
|
||||
|
||||
#[lang = "copy"]
|
||||
trait Copy {
|
||||
}
|
||||
|
||||
impl Copy for isize {}
|
||||
|
||||
#[lang = "receiver"]
|
||||
trait Receiver {
|
||||
}
|
||||
|
||||
#[lang = "freeze"]
|
||||
pub(crate) unsafe auto trait Freeze {}
|
||||
|
||||
/*
|
||||
* Code
|
||||
*/
|
||||
extern crate mini_core;
|
||||
use mini_core::*;
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
|
||||
|
|
|
@ -3,44 +3,13 @@
|
|||
// Run-time:
|
||||
// status: 2
|
||||
|
||||
#![feature(auto_traits, lang_items, no_core, intrinsics)]
|
||||
#![allow(internal_features)]
|
||||
|
||||
#![feature(no_core)]
|
||||
#![no_std]
|
||||
#![no_core]
|
||||
#![no_main]
|
||||
|
||||
mod libc {
|
||||
#[link(name = "c")]
|
||||
extern "C" {
|
||||
pub fn exit(status: i32);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Core
|
||||
*/
|
||||
|
||||
// Because we don't have core yet.
|
||||
#[lang = "sized"]
|
||||
pub trait Sized {}
|
||||
|
||||
#[lang = "copy"]
|
||||
trait Copy {
|
||||
}
|
||||
|
||||
impl Copy for isize {}
|
||||
|
||||
#[lang = "receiver"]
|
||||
trait Receiver {
|
||||
}
|
||||
|
||||
#[lang = "freeze"]
|
||||
pub(crate) unsafe auto trait Freeze {}
|
||||
|
||||
/*
|
||||
* Code
|
||||
*/
|
||||
extern crate mini_core;
|
||||
use mini_core::*;
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
|
||||
|
|
|
@ -3,37 +3,13 @@
|
|||
// Run-time:
|
||||
// status: 1
|
||||
|
||||
#![feature(auto_traits, lang_items, no_core)]
|
||||
#![allow(internal_features)]
|
||||
|
||||
#![feature(no_core)]
|
||||
#![no_std]
|
||||
#![no_core]
|
||||
#![no_main]
|
||||
|
||||
/*
|
||||
* Core
|
||||
*/
|
||||
|
||||
// Because we don't have core yet.
|
||||
#[lang = "sized"]
|
||||
pub trait Sized {}
|
||||
|
||||
#[lang = "copy"]
|
||||
trait Copy {
|
||||
}
|
||||
|
||||
impl Copy for isize {}
|
||||
|
||||
#[lang = "receiver"]
|
||||
trait Receiver {
|
||||
}
|
||||
|
||||
#[lang = "freeze"]
|
||||
pub(crate) unsafe auto trait Freeze {}
|
||||
|
||||
/*
|
||||
* Code
|
||||
*/
|
||||
extern crate mini_core;
|
||||
use mini_core::*;
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
|
||||
|
|
28
compiler/rustc_codegen_gcc/tests/run/float.rs
Normal file
28
compiler/rustc_codegen_gcc/tests/run/float.rs
Normal file
|
@ -0,0 +1,28 @@
|
|||
// Compiler:
|
||||
//
|
||||
// Run-time:
|
||||
// status: 0
|
||||
|
||||
#![feature(const_black_box)]
|
||||
|
||||
fn main() {
|
||||
use std::hint::black_box;
|
||||
|
||||
macro_rules! check {
|
||||
($ty:ty, $expr:expr) => {{
|
||||
const EXPECTED: $ty = $expr;
|
||||
assert_eq!($expr, EXPECTED);
|
||||
}};
|
||||
}
|
||||
|
||||
check!(i32, (black_box(0.0f32) as i32));
|
||||
|
||||
check!(u64, (black_box(f32::NAN) as u64));
|
||||
check!(u128, (black_box(f32::NAN) as u128));
|
||||
|
||||
check!(i64, (black_box(f64::NAN) as i64));
|
||||
check!(u64, (black_box(f64::NAN) as u64));
|
||||
|
||||
check!(i16, (black_box(f32::MIN) as i16));
|
||||
check!(i16, (black_box(f32::MAX) as i16));
|
||||
}
|
|
@ -5,19 +5,12 @@
|
|||
// stdout: 1
|
||||
|
||||
#![feature(no_core)]
|
||||
|
||||
#![no_std]
|
||||
#![no_core]
|
||||
#![no_main]
|
||||
|
||||
extern crate mini_core;
|
||||
|
||||
mod libc {
|
||||
#[link(name = "c")]
|
||||
extern "C" {
|
||||
pub fn printf(format: *const i8, ...) -> i32;
|
||||
}
|
||||
}
|
||||
use mini_core::*;
|
||||
|
||||
fn i16_as_i8(a: i16) -> i8 {
|
||||
a as i8
|
||||
|
|
|
@ -3,9 +3,7 @@
|
|||
// Run-time:
|
||||
// status: 0
|
||||
|
||||
/*
|
||||
* Code
|
||||
*/
|
||||
#![feature(const_black_box)]
|
||||
|
||||
fn main() {
|
||||
use std::hint::black_box;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
// Compiler:
|
||||
//
|
||||
// Run-time:
|
||||
|
@ -7,139 +6,20 @@
|
|||
// 6
|
||||
// 11
|
||||
|
||||
#![allow(internal_features, unused_attributes)]
|
||||
#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs, track_caller)]
|
||||
|
||||
#![feature(no_core)]
|
||||
#![no_std]
|
||||
#![no_core]
|
||||
#![no_main]
|
||||
|
||||
/*
|
||||
* Core
|
||||
*/
|
||||
|
||||
// Because we don't have core yet.
|
||||
#[lang = "sized"]
|
||||
pub trait Sized {}
|
||||
|
||||
#[lang = "copy"]
|
||||
trait Copy {
|
||||
}
|
||||
|
||||
impl Copy for isize {}
|
||||
impl Copy for *mut i32 {}
|
||||
impl Copy for usize {}
|
||||
impl Copy for u8 {}
|
||||
impl Copy for i8 {}
|
||||
impl Copy for i32 {}
|
||||
|
||||
#[lang = "receiver"]
|
||||
trait Receiver {
|
||||
}
|
||||
|
||||
#[lang = "freeze"]
|
||||
pub(crate) unsafe auto trait Freeze {}
|
||||
|
||||
#[lang = "panic_location"]
|
||||
struct PanicLocation {
|
||||
file: &'static str,
|
||||
line: u32,
|
||||
column: u32,
|
||||
}
|
||||
|
||||
mod libc {
|
||||
#[link(name = "c")]
|
||||
extern "C" {
|
||||
pub fn puts(s: *const u8) -> i32;
|
||||
pub fn fflush(stream: *mut i32) -> i32;
|
||||
pub fn printf(format: *const i8, ...) -> i32;
|
||||
|
||||
pub static stdout: *mut i32;
|
||||
}
|
||||
}
|
||||
|
||||
mod intrinsics {
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
pub fn abort() -> !;
|
||||
}
|
||||
|
||||
#[lang = "panic"]
|
||||
#[track_caller]
|
||||
#[no_mangle]
|
||||
pub fn panic(_msg: &'static str) -> ! {
|
||||
unsafe {
|
||||
libc::puts("Panicking\0" as *const str as *const u8);
|
||||
libc::fflush(libc::stdout);
|
||||
intrinsics::abort();
|
||||
}
|
||||
}
|
||||
|
||||
#[lang = "add"]
|
||||
trait Add<RHS = Self> {
|
||||
type Output;
|
||||
|
||||
fn add(self, rhs: RHS) -> Self::Output;
|
||||
}
|
||||
|
||||
impl Add for u8 {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Self) -> Self {
|
||||
self + rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for i8 {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Self) -> Self {
|
||||
self + rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for i32 {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Self) -> Self {
|
||||
self + rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for usize {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Self) -> Self {
|
||||
self + rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for isize {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Self) -> Self {
|
||||
self + rhs
|
||||
}
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
#[lang = "panic_const_add_overflow"]
|
||||
pub fn panic_const_add_overflow() -> ! {
|
||||
panic("attempt to add with overflow");
|
||||
}
|
||||
|
||||
/*
|
||||
* Code
|
||||
*/
|
||||
extern crate mini_core;
|
||||
use mini_core::*;
|
||||
|
||||
struct Test {
|
||||
field: isize,
|
||||
}
|
||||
|
||||
fn test(num: isize) -> Test {
|
||||
Test {
|
||||
field: num + 1,
|
||||
}
|
||||
Test { field: num + 1 }
|
||||
}
|
||||
|
||||
fn update_num(num: &mut isize) {
|
||||
|
@ -147,7 +27,7 @@ fn update_num(num: &mut isize) {
|
|||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
|
||||
extern "C" fn main(mut argc: isize, _argv: *const *const u8) -> i32 {
|
||||
let mut test = test(argc);
|
||||
unsafe {
|
||||
libc::printf(b"%ld\n\0" as *const u8 as *const i8, test.field);
|
||||
|
|
|
@ -5,229 +5,13 @@
|
|||
// 39
|
||||
// 10
|
||||
|
||||
#![allow(internal_features, unused_attributes)]
|
||||
#![feature(auto_traits, lang_items, no_core, intrinsics, arbitrary_self_types, rustc_attrs)]
|
||||
|
||||
#![feature(no_core)]
|
||||
#![no_std]
|
||||
#![no_core]
|
||||
#![no_main]
|
||||
|
||||
/*
|
||||
* Core
|
||||
*/
|
||||
|
||||
// Because we don't have core yet.
|
||||
#[lang = "sized"]
|
||||
pub trait Sized {}
|
||||
|
||||
#[lang = "copy"]
|
||||
trait Copy {
|
||||
}
|
||||
|
||||
impl Copy for isize {}
|
||||
impl Copy for *mut i32 {}
|
||||
impl Copy for usize {}
|
||||
impl Copy for u8 {}
|
||||
impl Copy for i8 {}
|
||||
impl Copy for i16 {}
|
||||
impl Copy for i32 {}
|
||||
|
||||
#[lang = "deref"]
|
||||
pub trait Deref {
|
||||
type Target: ?Sized;
|
||||
|
||||
fn deref(&self) -> &Self::Target;
|
||||
}
|
||||
|
||||
#[lang = "legacy_receiver"]
|
||||
trait LegacyReceiver {
|
||||
}
|
||||
|
||||
#[lang = "freeze"]
|
||||
pub(crate) unsafe auto trait Freeze {}
|
||||
|
||||
#[lang = "panic_location"]
|
||||
struct PanicLocation {
|
||||
file: &'static str,
|
||||
line: u32,
|
||||
column: u32,
|
||||
}
|
||||
|
||||
mod libc {
|
||||
#[link(name = "c")]
|
||||
extern "C" {
|
||||
pub fn printf(format: *const i8, ...) -> i32;
|
||||
pub fn puts(s: *const u8) -> i32;
|
||||
pub fn fflush(stream: *mut i32) -> i32;
|
||||
|
||||
pub static stdout: *mut i32;
|
||||
}
|
||||
}
|
||||
|
||||
mod intrinsics {
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
pub fn abort() -> !;
|
||||
}
|
||||
|
||||
#[lang = "panic"]
|
||||
#[track_caller]
|
||||
#[no_mangle]
|
||||
pub fn panic(_msg: &'static str) -> ! {
|
||||
unsafe {
|
||||
libc::puts("Panicking\0" as *const str as *const u8);
|
||||
libc::fflush(libc::stdout);
|
||||
intrinsics::abort();
|
||||
}
|
||||
}
|
||||
|
||||
#[lang = "add"]
|
||||
trait Add<RHS = Self> {
|
||||
type Output;
|
||||
|
||||
fn add(self, rhs: RHS) -> Self::Output;
|
||||
}
|
||||
|
||||
impl Add for u8 {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Self) -> Self {
|
||||
self + rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for i8 {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Self) -> Self {
|
||||
self + rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for i32 {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Self) -> Self {
|
||||
self + rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for usize {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Self) -> Self {
|
||||
self + rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for isize {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Self) -> Self {
|
||||
self + rhs
|
||||
}
|
||||
}
|
||||
|
||||
#[lang = "sub"]
|
||||
pub trait Sub<RHS = Self> {
|
||||
type Output;
|
||||
|
||||
fn sub(self, rhs: RHS) -> Self::Output;
|
||||
}
|
||||
|
||||
impl Sub for usize {
|
||||
type Output = Self;
|
||||
|
||||
fn sub(self, rhs: Self) -> Self {
|
||||
self - rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub for isize {
|
||||
type Output = Self;
|
||||
|
||||
fn sub(self, rhs: Self) -> Self {
|
||||
self - rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub for u8 {
|
||||
type Output = Self;
|
||||
|
||||
fn sub(self, rhs: Self) -> Self {
|
||||
self - rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub for i8 {
|
||||
type Output = Self;
|
||||
|
||||
fn sub(self, rhs: Self) -> Self {
|
||||
self - rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub for i16 {
|
||||
type Output = Self;
|
||||
|
||||
fn sub(self, rhs: Self) -> Self {
|
||||
self - rhs
|
||||
}
|
||||
}
|
||||
|
||||
#[lang = "mul"]
|
||||
pub trait Mul<RHS = Self> {
|
||||
type Output;
|
||||
|
||||
#[must_use]
|
||||
fn mul(self, rhs: RHS) -> Self::Output;
|
||||
}
|
||||
|
||||
impl Mul for u8 {
|
||||
type Output = Self;
|
||||
|
||||
fn mul(self, rhs: Self) -> Self::Output {
|
||||
self * rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul for usize {
|
||||
type Output = Self;
|
||||
|
||||
fn mul(self, rhs: Self) -> Self::Output {
|
||||
self * rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul for isize {
|
||||
type Output = Self;
|
||||
|
||||
fn mul(self, rhs: Self) -> Self::Output {
|
||||
self * rhs
|
||||
}
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
#[lang = "panic_const_add_overflow"]
|
||||
pub fn panic_const_add_overflow() -> ! {
|
||||
panic("attempt to add with overflow");
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
#[lang = "panic_const_sub_overflow"]
|
||||
pub fn panic_const_sub_overflow() -> ! {
|
||||
panic("attempt to subtract with overflow");
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
#[lang = "panic_const_mul_overflow"]
|
||||
pub fn panic_const_mul_overflow() -> ! {
|
||||
panic("attempt to multiply with overflow");
|
||||
}
|
||||
|
||||
/*
|
||||
* Code
|
||||
*/
|
||||
extern crate mini_core;
|
||||
use mini_core::*;
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
|
||||
|
|
|
@ -2,35 +2,32 @@
|
|||
//
|
||||
// Run-time:
|
||||
// status: 0
|
||||
// stdout: 1
|
||||
// stdout: 10
|
||||
// 10
|
||||
// 42
|
||||
|
||||
#![feature(no_core)]
|
||||
|
||||
#![no_std]
|
||||
#![no_core]
|
||||
#![no_main]
|
||||
|
||||
extern crate mini_core;
|
||||
use mini_core::*;
|
||||
|
||||
mod libc {
|
||||
#[link(name = "c")]
|
||||
extern "C" {
|
||||
pub fn printf(format: *const i8, ...) -> i32;
|
||||
}
|
||||
}
|
||||
|
||||
static mut ONE: usize = 1;
|
||||
|
||||
fn make_array() -> [u8; 3] {
|
||||
[42, 10, 5]
|
||||
fn int_cast(a: u16, b: i16) -> (u8, u16, u32, usize, i8, i16, i32, isize, u8, u32) {
|
||||
(
|
||||
a as u8, a as u16, a as u32, a as usize, a as i8, a as i16, a as i32, a as isize, b as u8,
|
||||
b as u32,
|
||||
)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
|
||||
let (a, b, c, d, e, f, g, h, i, j) = int_cast(10, 42);
|
||||
unsafe {
|
||||
let ptr = ONE as *mut usize;
|
||||
let value = ptr as usize;
|
||||
libc::printf(b"%ld\n\0" as *const u8 as *const i8, value);
|
||||
libc::printf(b"%d\n\0" as *const u8 as *const i8, c);
|
||||
libc::printf(b"%ld\n\0" as *const u8 as *const i8, d);
|
||||
libc::printf(b"%ld\n\0" as *const u8 as *const i8, j);
|
||||
}
|
||||
0
|
||||
}
|
||||
|
|
|
@ -6,54 +6,19 @@
|
|||
// 10
|
||||
// 42
|
||||
|
||||
<<<<<<< HEAD
|
||||
#![feature(auto_traits, lang_items, no_core, intrinsics)]
|
||||
#![allow(internal_features)]
|
||||
|
||||
=======
|
||||
#![feature(no_core)]
|
||||
>>>>>>> db1a31c243a649e1fe20f5466ba181da5be35c14
|
||||
#![no_std]
|
||||
#![no_core]
|
||||
#![no_main]
|
||||
|
||||
#[lang = "copy"]
|
||||
pub unsafe trait Copy {}
|
||||
|
||||
impl Copy for bool {}
|
||||
impl Copy for u8 {}
|
||||
impl Copy for u16 {}
|
||||
impl Copy for u32 {}
|
||||
impl Copy for u64 {}
|
||||
impl Copy for usize {}
|
||||
impl Copy for i8 {}
|
||||
impl Copy for i16 {}
|
||||
impl Copy for i32 {}
|
||||
impl Copy for isize {}
|
||||
impl Copy for f32 {}
|
||||
impl Copy for char {}
|
||||
|
||||
mod libc {
|
||||
#[link(name = "c")]
|
||||
extern "C" {
|
||||
pub fn printf(format: *const i8, ...) -> i32;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Core
|
||||
*/
|
||||
|
||||
// Because we don't have core yet.
|
||||
#[lang = "sized"]
|
||||
pub trait Sized {}
|
||||
|
||||
#[lang = "legacy_receiver"]
|
||||
trait LegacyReceiver {
|
||||
}
|
||||
|
||||
#[lang = "freeze"]
|
||||
pub(crate) unsafe auto trait Freeze {}
|
||||
|
||||
/*
|
||||
* Code
|
||||
*/
|
||||
extern crate mini_core;
|
||||
use mini_core::*;
|
||||
|
||||
fn int_cast(a: u16, b: i16) -> (u8, u16, u32, usize, i8, i16, i32, isize, u8, u32) {
|
||||
(
|
||||
|
|
|
@ -5,26 +5,17 @@
|
|||
// stdout: 5
|
||||
|
||||
#![feature(no_core)]
|
||||
|
||||
#![no_std]
|
||||
#![no_core]
|
||||
#![no_main]
|
||||
|
||||
extern crate mini_core;
|
||||
|
||||
mod libc {
|
||||
#[link(name = "c")]
|
||||
extern "C" {
|
||||
pub fn printf(format: *const i8, ...) -> i32;
|
||||
}
|
||||
}
|
||||
use mini_core::*;
|
||||
|
||||
static mut TWO: usize = 2;
|
||||
|
||||
fn index_slice(s: &[u32]) -> u32 {
|
||||
unsafe {
|
||||
s[TWO]
|
||||
}
|
||||
unsafe { s[TWO] }
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
|
|
@ -9,70 +9,13 @@
|
|||
// 12
|
||||
// 1
|
||||
|
||||
#![feature(auto_traits, lang_items, no_core, intrinsics, rustc_attrs)]
|
||||
#![allow(internal_features)]
|
||||
|
||||
#![feature(no_core)]
|
||||
#![no_std]
|
||||
#![no_core]
|
||||
#![no_main]
|
||||
|
||||
/*
|
||||
* Core
|
||||
*/
|
||||
|
||||
// Because we don't have core yet.
|
||||
#[lang = "sized"]
|
||||
pub trait Sized {}
|
||||
|
||||
#[lang = "destruct"]
|
||||
pub trait Destruct {}
|
||||
|
||||
#[lang = "drop"]
|
||||
pub trait Drop {}
|
||||
|
||||
#[lang = "copy"]
|
||||
trait Copy {
|
||||
}
|
||||
|
||||
impl Copy for isize {}
|
||||
impl<T: ?Sized> Copy for *mut T {}
|
||||
|
||||
#[lang = "receiver"]
|
||||
trait Receiver {
|
||||
}
|
||||
|
||||
#[lang = "freeze"]
|
||||
pub(crate) unsafe auto trait Freeze {}
|
||||
|
||||
mod intrinsics {
|
||||
use super::Sized;
|
||||
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
pub fn abort() -> !;
|
||||
}
|
||||
|
||||
mod libc {
|
||||
#[link(name = "c")]
|
||||
extern "C" {
|
||||
pub fn printf(format: *const i8, ...) -> i32;
|
||||
}
|
||||
}
|
||||
|
||||
#[lang = "structural_peq"]
|
||||
pub trait StructuralPartialEq {}
|
||||
|
||||
#[lang = "drop_in_place"]
|
||||
#[allow(unconditional_recursion)]
|
||||
pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
|
||||
// Code here does not matter - this is replaced by the
|
||||
// real drop glue by the compiler.
|
||||
drop_in_place(to_drop);
|
||||
}
|
||||
|
||||
/*
|
||||
* Code
|
||||
*/
|
||||
extern crate mini_core;
|
||||
use mini_core::*;
|
||||
|
||||
struct Test {
|
||||
field: isize,
|
||||
|
@ -84,20 +27,14 @@ struct WithRef {
|
|||
|
||||
static mut CONSTANT: isize = 10;
|
||||
|
||||
static mut TEST: Test = Test {
|
||||
field: 12,
|
||||
};
|
||||
static mut TEST: Test = Test { field: 12 };
|
||||
|
||||
static mut TEST2: Test = Test {
|
||||
field: 14,
|
||||
};
|
||||
static mut TEST2: Test = Test { field: 14 };
|
||||
|
||||
static mut WITH_REF: WithRef = WithRef {
|
||||
refe: unsafe { &TEST },
|
||||
};
|
||||
static mut WITH_REF: WithRef = WithRef { refe: unsafe { &TEST } };
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
|
||||
extern "C" fn main(argc: isize, _argv: *const *const u8) -> i32 {
|
||||
unsafe {
|
||||
libc::printf(b"%ld\n\0" as *const u8 as *const i8, CONSTANT);
|
||||
libc::printf(b"%ld\n\0" as *const u8 as *const i8, TEST2.field);
|
||||
|
|
|
@ -5,44 +5,13 @@
|
|||
// stdout: 1
|
||||
// 2
|
||||
|
||||
#![feature(auto_traits, lang_items, no_core, intrinsics)]
|
||||
#![allow(internal_features)]
|
||||
|
||||
#![feature(no_core)]
|
||||
#![no_std]
|
||||
#![no_core]
|
||||
#![no_main]
|
||||
|
||||
/*
|
||||
* Core
|
||||
*/
|
||||
|
||||
// Because we don't have core yet.
|
||||
#[lang = "sized"]
|
||||
pub trait Sized {}
|
||||
|
||||
#[lang = "copy"]
|
||||
trait Copy {
|
||||
}
|
||||
|
||||
impl Copy for isize {}
|
||||
|
||||
#[lang = "receiver"]
|
||||
trait Receiver {
|
||||
}
|
||||
|
||||
#[lang = "freeze"]
|
||||
pub(crate) unsafe auto trait Freeze {}
|
||||
|
||||
mod libc {
|
||||
#[link(name = "c")]
|
||||
extern "C" {
|
||||
pub fn printf(format: *const i8, ...) -> i32;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Code
|
||||
*/
|
||||
extern crate mini_core;
|
||||
use mini_core::*;
|
||||
|
||||
struct Test {
|
||||
field: isize,
|
||||
|
|
|
@ -4,44 +4,13 @@
|
|||
// status: 0
|
||||
// stdout: 3
|
||||
|
||||
#![feature(auto_traits, lang_items, no_core, intrinsics)]
|
||||
#![allow(internal_features)]
|
||||
|
||||
#![feature(no_core)]
|
||||
#![no_std]
|
||||
#![no_core]
|
||||
#![no_main]
|
||||
|
||||
/*
|
||||
* Core
|
||||
*/
|
||||
|
||||
// Because we don't have core yet.
|
||||
#[lang = "sized"]
|
||||
pub trait Sized {}
|
||||
|
||||
#[lang = "copy"]
|
||||
trait Copy {
|
||||
}
|
||||
|
||||
impl Copy for isize {}
|
||||
|
||||
#[lang = "receiver"]
|
||||
trait Receiver {
|
||||
}
|
||||
|
||||
#[lang = "freeze"]
|
||||
pub(crate) unsafe auto trait Freeze {}
|
||||
|
||||
mod libc {
|
||||
#[link(name = "c")]
|
||||
extern "C" {
|
||||
pub fn printf(format: *const i8, ...) -> i32;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Code
|
||||
*/
|
||||
extern crate mini_core;
|
||||
use mini_core::*;
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue