From 39f45e912afda497ae70211789e28d7b560a3af3 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Tue, 21 May 2024 01:45:17 -0400 Subject: [PATCH 1/4] Organize functions in intrinsics example --- examples/intrinsics.rs | 179 ++++++++++++++++++++++------------------- 1 file changed, 96 insertions(+), 83 deletions(-) diff --git a/examples/intrinsics.rs b/examples/intrinsics.rs index 54b703dfb..201c9a7e0 100644 --- a/examples/intrinsics.rs +++ b/examples/intrinsics.rs @@ -8,10 +8,12 @@ #![allow(internal_features)] #![cfg_attr(thumb, no_main)] #![deny(dead_code)] +#![feature(allocator_api)] #![feature(bench_black_box)] +#![feature(f128)] +#![feature(f16)] #![feature(lang_items)] #![feature(start)] -#![feature(allocator_api)] #![no_std] extern crate panic_handler; @@ -26,126 +28,132 @@ extern "C" {} // have an additional comment: the function name is the ARM name for the intrinsic and the comment // in the non-ARM name for the intrinsic. mod intrinsics { - // truncdfsf2 - pub fn aeabi_d2f(x: f64) -> f32 { - x as f32 + /* f32 operations */ + + // extendsfdf2 + pub fn aeabi_f2d(x: f32) -> f64 { + x as f64 } - // fixdfsi - pub fn aeabi_d2i(x: f64) -> i32 { + // fixsfsi + pub fn aeabi_f2iz(x: f32) -> i32 { x as i32 } - // fixdfdi - pub fn aeabi_d2l(x: f64) -> i64 { + // fixsfdi + pub fn aeabi_f2lz(x: f32) -> i64 { x as i64 } - // fixunsdfsi - pub fn aeabi_d2uiz(x: f64) -> u32 { + // fixunssfsi + pub fn aeabi_f2uiz(x: f32) -> u32 { x as u32 } - // fixunsdfdi - pub fn aeabi_d2ulz(x: f64) -> u64 { + // fixunssfdi + pub fn aeabi_f2ulz(x: f32) -> u64 { x as u64 } - // adddf3 - pub fn aeabi_dadd(a: f64, b: f64) -> f64 { + // addsf3 + pub fn aeabi_fadd(a: f32, b: f32) -> f32 { a + b } - // eqdf2 - pub fn aeabi_dcmpeq(a: f64, b: f64) -> bool { + // eqsf2 + pub fn aeabi_fcmpeq(a: f32, b: f32) -> bool { a == b } - // gtdf2 - pub fn aeabi_dcmpgt(a: f64, b: f64) -> bool { + // gtsf2 + pub fn aeabi_fcmpgt(a: f32, b: f32) -> bool { a > b } - // ltdf2 - pub fn aeabi_dcmplt(a: f64, b: f64) -> bool { + // ltsf2 + pub fn aeabi_fcmplt(a: f32, b: f32) -> bool { a < b } - // divdf3 - pub fn aeabi_ddiv(a: f64, b: f64) -> f64 { + // divsf3 + pub fn aeabi_fdiv(a: f32, b: f32) -> f32 { a / b } - // muldf3 - pub fn aeabi_dmul(a: f64, b: f64) -> f64 { + // mulsf3 + pub fn aeabi_fmul(a: f32, b: f32) -> f32 { a * b } - // subdf3 - pub fn aeabi_dsub(a: f64, b: f64) -> f64 { + // subsf3 + pub fn aeabi_fsub(a: f32, b: f32) -> f32 { a - b } - // extendsfdf2 - pub fn aeabi_f2d(x: f32) -> f64 { - x as f64 + /* f64 operations */ + + // truncdfsf2 + pub fn aeabi_d2f(x: f64) -> f32 { + x as f32 } - // fixsfsi - pub fn aeabi_f2iz(x: f32) -> i32 { + // fixdfsi + pub fn aeabi_d2i(x: f64) -> i32 { x as i32 } - // fixsfdi - pub fn aeabi_f2lz(x: f32) -> i64 { + // fixdfdi + pub fn aeabi_d2l(x: f64) -> i64 { x as i64 } - // fixunssfsi - pub fn aeabi_f2uiz(x: f32) -> u32 { + // fixunsdfsi + pub fn aeabi_d2uiz(x: f64) -> u32 { x as u32 } - // fixunssfdi - pub fn aeabi_f2ulz(x: f32) -> u64 { + // fixunsdfdi + pub fn aeabi_d2ulz(x: f64) -> u64 { x as u64 } - // addsf3 - pub fn aeabi_fadd(a: f32, b: f32) -> f32 { + // adddf3 + pub fn aeabi_dadd(a: f64, b: f64) -> f64 { a + b } - // eqsf2 - pub fn aeabi_fcmpeq(a: f32, b: f32) -> bool { + // eqdf2 + pub fn aeabi_dcmpeq(a: f64, b: f64) -> bool { a == b } - // gtsf2 - pub fn aeabi_fcmpgt(a: f32, b: f32) -> bool { + // gtdf2 + pub fn aeabi_dcmpgt(a: f64, b: f64) -> bool { a > b } - // ltsf2 - pub fn aeabi_fcmplt(a: f32, b: f32) -> bool { + // ltdf2 + pub fn aeabi_dcmplt(a: f64, b: f64) -> bool { a < b } - // divsf3 - pub fn aeabi_fdiv(a: f32, b: f32) -> f32 { + // divdf3 + pub fn aeabi_ddiv(a: f64, b: f64) -> f64 { a / b } - // mulsf3 - pub fn aeabi_fmul(a: f32, b: f32) -> f32 { + // muldf3 + pub fn aeabi_dmul(a: f64, b: f64) -> f64 { a * b } - // subsf3 - pub fn aeabi_fsub(a: f32, b: f32) -> f32 { + // subdf3 + pub fn aeabi_dsub(a: f64, b: f64) -> f64 { a - b } + /* i32 operations */ + // floatsidf pub fn aeabi_i2d(x: i32) -> f64 { x as f64 @@ -164,14 +172,20 @@ mod intrinsics { a % b } + /* i64 operations */ + + // floatdisf + pub fn aeabi_l2f(x: i64) -> f32 { + x as f32 + } + // floatdidf pub fn aeabi_l2d(x: i64) -> f64 { x as f64 } - // floatdisf - pub fn aeabi_l2f(x: i64) -> f32 { - x as f32 + pub fn mulodi4(a: i64, b: i64) -> i64 { + a * b } // divdi3 @@ -179,11 +193,31 @@ mod intrinsics { a / b } + pub fn moddi3(a: i64, b: i64) -> i64 { + a % b + } + // muldi3 pub fn aeabi_lmul(a: i64, b: i64) -> i64 { a.wrapping_mul(b) } + /* i128 operations */ + + pub fn lshrti3(a: i128, b: usize) -> i128 { + a >> b + } + + pub fn divti3(a: i128, b: i128) -> i128 { + a / b + } + + pub fn modti3(a: i128, b: i128) -> i128 { + a % b + } + + /* u32 operations */ + // floatunsidf pub fn aeabi_ui2d(x: u32) -> f64 { x as f64 @@ -202,26 +236,20 @@ mod intrinsics { a % b } - // floatundidf - pub fn aeabi_ul2d(x: u64) -> f64 { - x as f64 - } + /* u64 operations */ // floatundisf pub fn aeabi_ul2f(x: u64) -> f32 { x as f32 } - // udivdi3 - pub fn aeabi_uldivmod(a: u64, b: u64) -> u64 { - a * b - } - - pub fn moddi3(a: i64, b: i64) -> i64 { - a % b + // floatundidf + pub fn aeabi_ul2d(x: u64) -> f64 { + x as f64 } - pub fn mulodi4(a: i64, b: i64) -> i64 { + // udivdi3 + pub fn aeabi_uldivmod(a: u64, b: u64) -> u64 { a * b } @@ -229,6 +257,8 @@ mod intrinsics { a % b } + /* u128 operations */ + pub fn muloti4(a: u128, b: u128) -> Option { a.checked_mul(b) } @@ -245,10 +275,6 @@ mod intrinsics { a << b } - pub fn lshrti3(a: i128, b: usize) -> i128 { - a >> b - } - pub fn udivti3(a: u128, b: u128) -> u128 { a / b } @@ -256,18 +282,6 @@ mod intrinsics { pub fn umodti3(a: u128, b: u128) -> u128 { a % b } - - pub fn divti3(a: i128, b: i128) -> i128 { - a / b - } - - pub fn modti3(a: i128, b: i128) -> i128 { - a % b - } - - pub fn udivsi3(a: u32, b: u32) -> u32 { - a / b - } } fn run() { @@ -325,7 +339,6 @@ fn run() { bb(umodti3(bb(2), bb(2))); bb(divti3(bb(2), bb(2))); bb(modti3(bb(2), bb(2))); - bb(udivsi3(bb(2), bb(2))); something_with_a_dtor(&|| assert_eq!(bb(1), 1)); From 80d022e6f3c6c8b3ddb7f66a32177bd76916d7f3 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Tue, 21 May 2024 01:55:46 -0400 Subject: [PATCH 2/4] Add f16 and f128 intrinsics to the example test --- examples/intrinsics.rs | 134 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 128 insertions(+), 6 deletions(-) diff --git a/examples/intrinsics.rs b/examples/intrinsics.rs index 201c9a7e0..e4fcb3e35 100644 --- a/examples/intrinsics.rs +++ b/examples/intrinsics.rs @@ -28,13 +28,36 @@ extern "C" {} // have an additional comment: the function name is the ARM name for the intrinsic and the comment // in the non-ARM name for the intrinsic. mod intrinsics { + /* f16 operations */ + + pub fn extendhfsf(x: f16) -> f32 { + x as f32 + } + + pub fn extendhfdf(x: f16) -> f64 { + x as f64 + } + + #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] + pub fn extendhftf(x: f16) -> f128 { + x as f128 + } + /* f32 operations */ + pub fn truncsfhf(x: f32) -> f16 { + x as f16 + } + // extendsfdf2 pub fn aeabi_f2d(x: f32) -> f64 { x as f64 } + pub fn extendsftf(x: f32) -> f128 { + x as f128 + } + // fixsfsi pub fn aeabi_f2iz(x: f32) -> i32 { x as i32 @@ -152,6 +175,75 @@ mod intrinsics { a - b } + /* f128 operations */ + + #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] + pub fn trunctfhf(x: f128) -> f16 { + x as f16 + } + + pub fn trunctfsf(x: f128) -> f32 { + x as f32 + } + + pub fn trunctfdf(x: f128) -> f64 { + x as f64 + } + + #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] + pub fn fixtfsi(x: f128) -> i32 { + x as i32 + } + + #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] + pub fn fixtfdi(x: f128) -> i64 { + x as i64 + } + + #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] + pub fn fixtfti(x: f128) -> i128 { + x as i128 + } + + #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] + pub fn fixunstfsi(x: f128) -> u32 { + x as u32 + } + + #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] + pub fn fixunstfdi(x: f128) -> u64 { + x as u64 + } + + #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] + pub fn fixunstfti(x: f128) -> u128 { + x as u128 + } + + pub fn addtf(a: f128, b: f128) -> f128 { + a + b + } + + pub fn eqtf(a: f128, b: f128) -> bool { + a == b + } + + pub fn gttf(a: f128, b: f128) -> bool { + a > b + } + + pub fn lttf(a: f128, b: f128) -> bool { + a < b + } + + pub fn multf(a: f128, b: f128) -> f128 { + a * b + } + + pub fn subtf(a: f128, b: f128) -> f128 { + a - b + } + /* i32 operations */ // floatsidf @@ -288,6 +380,9 @@ fn run() { use core::hint::black_box as bb; use intrinsics::*; + // FIXME(f16_f128): some PPC f128 <-> int conversion functions have the wrong names + + bb(addtf(bb(2.), bb(2.))); bb(aeabi_d2f(bb(2.))); bb(aeabi_d2i(bb(2.))); bb(aeabi_d2l(bb(2.))); @@ -327,18 +422,45 @@ fn run() { bb(aeabi_ul2d(bb(2))); bb(aeabi_ul2f(bb(2))); bb(aeabi_uldivmod(bb(2), bb(3))); + bb(ashlti3(bb(2), bb(2))); + bb(ashrti3(bb(2), bb(2))); + bb(divti3(bb(2), bb(2))); + bb(eqtf(bb(2.), bb(2.))); + bb(extendhfdf(bb(2.))); + bb(extendhfsf(bb(2.))); + #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] + bb(extendhftf(bb(2.))); + bb(extendsftf(bb(2.))); + #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] + bb(fixtfdi(bb(2.))); + #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] + bb(fixtfsi(bb(2.))); + #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] + bb(fixtfti(bb(2.))); + #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] + bb(fixunstfdi(bb(2.))); + #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] + bb(fixunstfsi(bb(2.))); + #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] + bb(fixunstfti(bb(2.))); + bb(gttf(bb(2.), bb(2.))); + bb(lshrti3(bb(2), bb(2))); + bb(lttf(bb(2.), bb(2.))); bb(moddi3(bb(2), bb(3))); + bb(modti3(bb(2), bb(2))); bb(mulodi4(bb(2), bb(3))); - bb(umoddi3(bb(2), bb(3))); bb(muloti4(bb(2), bb(2))); + bb(multf(bb(2.), bb(2.))); bb(multi3(bb(2), bb(2))); - bb(ashlti3(bb(2), bb(2))); - bb(ashrti3(bb(2), bb(2))); - bb(lshrti3(bb(2), bb(2))); + bb(subtf(bb(2.), bb(2.))); + bb(truncsfhf(bb(2.))); + bb(trunctfdf(bb(2.))); + #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] + bb(trunctfhf(bb(2.))); + bb(trunctfsf(bb(2.))); bb(udivti3(bb(2), bb(2))); + bb(umoddi3(bb(2), bb(3))); bb(umodti3(bb(2), bb(2))); - bb(divti3(bb(2), bb(2))); - bb(modti3(bb(2), bb(2))); something_with_a_dtor(&|| assert_eq!(bb(1), 1)); From 32c99b0368e18d171ee9f57f5aef33e53ddf4ba0 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Tue, 21 May 2024 01:59:00 -0400 Subject: [PATCH 3/4] Update outdated contribution guidelines --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 8233c669c..9a847da3f 100644 --- a/README.md +++ b/README.md @@ -52,17 +52,17 @@ features = ["c"] 2. Fork this repository. 3. Port the intrinsic(s) and their corresponding [unit tests][1] from their [C implementation][2] to Rust. -4. Implement a [test generator][3] to compare the behavior of the ported intrinsic(s) - with their implementation on the testing host. Note that randomized compiler-builtin tests - should be run using `cargo test --features gen-tests`. -4. Send a Pull Request (PR). -5. Once the PR passes our extensive [testing infrastructure][4], we'll merge it! -6. Celebrate :tada: +4. Add a test to compare the behavior of the ported intrinsic(s) with their + implementation on the testing host. +5. Add the intrinsic to `examples/intrinsics.rs` to verify it can be linked on + all targets. +6. Send a Pull Request (PR). +7. Once the PR passes our extensive [testing infrastructure][4], we'll merge it! +8. Celebrate :tada: [1]: https://github.com/rust-lang/llvm-project/tree/9e3de9490ff580cd484fbfa2908292b4838d56e7/compiler-rt/test/builtins/Unit [2]: https://github.com/rust-lang/llvm-project/tree/9e3de9490ff580cd484fbfa2908292b4838d56e7/compiler-rt/lib/builtins -[3]: https://github.com/rust-lang/compiler-builtins/blob/0ba07e49264a54cb5bbd4856fcea083bb3fbec15/build.rs#L180-L265 -[4]: https://github.com/rust-lang/compiler-builtins/actions +[3]: https://github.com/rust-lang/compiler-builtins/actions ### Porting Reminders From 4f4443fbedee4c98432da164bd2867a9f75ed786 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Tue, 21 May 2024 02:02:21 -0400 Subject: [PATCH 4/4] Add some missing functions to examples/intrinsics --- examples/intrinsics.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/examples/intrinsics.rs b/examples/intrinsics.rs index e4fcb3e35..8bb707673 100644 --- a/examples/intrinsics.rs +++ b/examples/intrinsics.rs @@ -68,6 +68,10 @@ mod intrinsics { x as i64 } + pub fn fixsfti(x: f32) -> i128 { + x as i128 + } + // fixunssfsi pub fn aeabi_f2uiz(x: f32) -> u32 { x as u32 @@ -78,6 +82,10 @@ mod intrinsics { x as u64 } + pub fn fixunssfti(x: f32) -> u128 { + x as u128 + } + // addsf3 pub fn aeabi_fadd(a: f32, b: f32) -> f32 { a + b @@ -130,6 +138,10 @@ mod intrinsics { x as i64 } + pub fn fixdfti(x: f64) -> i128 { + x as i128 + } + // fixunsdfsi pub fn aeabi_d2uiz(x: f64) -> u32 { x as u32 @@ -140,6 +152,10 @@ mod intrinsics { x as u64 } + pub fn fixunsdfti(x: f64) -> u128 { + x as u128 + } + // adddf3 pub fn aeabi_dadd(a: f64, b: f64) -> f64 { a + b @@ -431,12 +447,16 @@ fn run() { #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] bb(extendhftf(bb(2.))); bb(extendsftf(bb(2.))); + bb(fixdfti(bb(2.))); + bb(fixsfti(bb(2.))); #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] bb(fixtfdi(bb(2.))); #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] bb(fixtfsi(bb(2.))); #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] bb(fixtfti(bb(2.))); + bb(fixunsdfti(bb(2.))); + bb(fixunssfti(bb(2.))); #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] bb(fixunstfdi(bb(2.))); #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))]