diff --git a/c2rust-transpile/src/translator/builtins.rs b/c2rust-transpile/src/translator/builtins.rs index f90513b4bf..f13bd5f8cb 100644 --- a/c2rust-transpile/src/translator/builtins.rs +++ b/c2rust-transpile/src/translator/builtins.rs @@ -380,16 +380,31 @@ impl<'c> Translation<'c> { }) } - "__builtin_ia32_pause" | "__builtin_arm_yield" => { - // `spin_loop()` is implemented as `_mm_pause()` (the `pause` instruction) on `x86`/`x86_64`, - // but it's the safe and cross-platform version of it, so prefer it. - // On `arm`, it's implemented as `yield`, although on `aarch64`, - // it's implemented as `isb` instead as this is more efficient. - // See . - // `core::arch::aarch64::__yield()` could be used instead, - // but it's unstable (`#![feature(stdarch_arm_hints)]`), so it's not ideal. - let spin_loop = mk().abs_path_expr(vec!["core", "hint", "spin_loop"]); - let call = mk().call_expr(spin_loop, vec![]); + "__builtin_ia32_pause" => { + let fn_name = "_mm_pause"; + self.import_simd_function(fn_name)?; + let ident = mk().ident_expr(fn_name); + let call = mk().call_expr(ident, vec![]); + self.convert_side_effects_expr( + ctx, + WithStmts::new_val(call), + "Builtin is not supposed to be used", + ) + } + + "__builtin_arm_yield" => { + let fn_name = "__yield"; + self.use_feature("stdsimd"); + // TODO See #1298. + // In Rust 1.7, `#![feature(stdsimd)]` was removed and split into (at least): + // `#![feature("stdarch_arm_hints")]` and + // `#![cfg_attr(target_arch = "arm", feature(stdarch_arm_neon_intrinsics))]`. + // self.use_feature("stdarch_arm_hints"); + // self.use_feature("stdarch_arm_neon_intrinsics"); // TODO need to add `cfg_attr` support. + self.import_arch_function("arm", fn_name); + self.import_arch_function("aarch64", fn_name); + let ident = mk().ident_expr(fn_name); + let call = mk().call_expr(ident, vec![]); self.convert_side_effects_expr( ctx, WithStmts::new_val(call), diff --git a/c2rust-transpile/src/translator/simd.rs b/c2rust-transpile/src/translator/simd.rs index 0363b0ff66..d203bf451a 100644 --- a/c2rust-transpile/src/translator/simd.rs +++ b/c2rust-transpile/src/translator/simd.rs @@ -147,6 +147,13 @@ impl<'c> Translation<'c> { }) } + /// Import a function from [`core::arch`] with a `#[cfg(target_arch = "{arch_name})]`. + pub fn import_arch_function(&self, arch_name: &str, name: &str) { + self.with_cur_file_item_store(|item_store| { + add_arch_use(item_store, arch_name, name); + }); + } + /// Determine if a particular function name is an SIMD primitive. If so an appropriate /// use statement is generated, `true` is returned, and no further processing will need to be done. pub fn import_simd_function(&self, name: &str) -> TranslationResult { diff --git a/c2rust-transpile/tests/snapshots/arch-specific/dummy2.aarch64.rs b/c2rust-transpile/tests/snapshots/arch-specific/dummy2.aarch64.rs deleted file mode 100644 index d5e9115dc0..0000000000 --- a/c2rust-transpile/tests/snapshots/arch-specific/dummy2.aarch64.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![allow( - dead_code, - mutable_transmutes, - non_camel_case_types, - non_snake_case, - non_upper_case_globals, - unused_assignments, - unused_mut -)] diff --git a/c2rust-transpile/tests/snapshots/arch-specific/dummy2.c b/c2rust-transpile/tests/snapshots/arch-specific/dummy2.c deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/c2rust-transpile/tests/snapshots/arch-specific/dummy2.x86_64.rs b/c2rust-transpile/tests/snapshots/arch-specific/dummy2.x86_64.rs deleted file mode 100644 index d5e9115dc0..0000000000 --- a/c2rust-transpile/tests/snapshots/arch-specific/dummy2.x86_64.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![allow( - dead_code, - mutable_transmutes, - non_camel_case_types, - non_snake_case, - non_upper_case_globals, - unused_assignments, - unused_mut -)] diff --git a/c2rust-transpile/tests/snapshots/spin.rs b/c2rust-transpile/tests/snapshots/arch-specific/spin.aarch64.rs similarity index 56% rename from c2rust-transpile/tests/snapshots/spin.rs rename to c2rust-transpile/tests/snapshots/arch-specific/spin.aarch64.rs index 756149372c..439aec9679 100644 --- a/c2rust-transpile/tests/snapshots/spin.rs +++ b/c2rust-transpile/tests/snapshots/arch-specific/spin.aarch64.rs @@ -7,7 +7,12 @@ unused_assignments, unused_mut )] +#![feature(stdsimd)] +#[cfg(target_arch = "arm")] +pub use core::arch::arm::__yield; +#[cfg(target_arch = "aarch64")] +pub use core::arch::aarch64::__yield; #[no_mangle] pub unsafe extern "C" fn spin() { - ::core::hint::spin_loop(); + __yield(); } diff --git a/c2rust-transpile/tests/snapshots/spin.c b/c2rust-transpile/tests/snapshots/arch-specific/spin.c similarity index 100% rename from c2rust-transpile/tests/snapshots/spin.c rename to c2rust-transpile/tests/snapshots/arch-specific/spin.c diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@spin.c.snap b/c2rust-transpile/tests/snapshots/arch-specific/spin.x86_64.rs similarity index 55% rename from c2rust-transpile/tests/snapshots/snapshots__transpile@spin.c.snap rename to c2rust-transpile/tests/snapshots/arch-specific/spin.x86_64.rs index 3fcad2fc11..5174834bba 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@spin.c.snap +++ b/c2rust-transpile/tests/snapshots/arch-specific/spin.x86_64.rs @@ -1,8 +1,3 @@ ---- -source: c2rust-transpile/tests/snapshots.rs -expression: cat tests/snapshots/spin.rs -input_file: c2rust-transpile/tests/snapshots/spin.c ---- #![allow( dead_code, mutable_transmutes, @@ -12,7 +7,12 @@ input_file: c2rust-transpile/tests/snapshots/spin.c unused_assignments, unused_mut )] +#![feature(stdsimd)] +#[cfg(target_arch = "x86")] +pub use core::arch::x86::_mm_pause; +#[cfg(target_arch = "x86_64")] +pub use core::arch::x86_64::_mm_pause; #[no_mangle] pub unsafe extern "C" fn spin() { - ::core::hint::spin_loop(); + _mm_pause(); } diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile-aarch64@dummy2.c.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile-aarch64@dummy2.c.snap deleted file mode 100644 index 622e760b20..0000000000 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile-aarch64@dummy2.c.snap +++ /dev/null @@ -1,14 +0,0 @@ ---- -source: c2rust-transpile/tests/snapshots.rs -expression: cat tests/snapshots/arch-specific/dummy2.aarch64.rs -input_file: c2rust-transpile/tests/snapshots/arch-specific/dummy2.c ---- -#![allow( - dead_code, - mutable_transmutes, - non_camel_case_types, - non_snake_case, - non_upper_case_globals, - unused_assignments, - unused_mut -)] diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile-aarch64@spin.c.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile-aarch64@spin.c.snap new file mode 100644 index 0000000000..43cf7cfef3 --- /dev/null +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile-aarch64@spin.c.snap @@ -0,0 +1,23 @@ +--- +source: c2rust-transpile/tests/snapshots.rs +expression: cat tests/snapshots/arch-specific/spin.aarch64.rs +input_file: c2rust-transpile/tests/snapshots/arch-specific/spin.c +--- +#![allow( + dead_code, + mutable_transmutes, + non_camel_case_types, + non_snake_case, + non_upper_case_globals, + unused_assignments, + unused_mut +)] +#![feature(stdsimd)] +#[cfg(target_arch = "arm")] +pub use core::arch::arm::__yield; +#[cfg(target_arch = "aarch64")] +pub use core::arch::aarch64::__yield; +#[no_mangle] +pub unsafe extern "C" fn spin() { + __yield(); +} diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile-x86_64@dummy2.c.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile-x86_64@dummy2.c.snap deleted file mode 100644 index 0f13405b66..0000000000 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile-x86_64@dummy2.c.snap +++ /dev/null @@ -1,14 +0,0 @@ ---- -source: c2rust-transpile/tests/snapshots.rs -expression: cat tests/snapshots/arch-specific/dummy2.x86_64.rs -input_file: c2rust-transpile/tests/snapshots/arch-specific/dummy2.c ---- -#![allow( - dead_code, - mutable_transmutes, - non_camel_case_types, - non_snake_case, - non_upper_case_globals, - unused_assignments, - unused_mut -)] diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile-x86_64@spin.c.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile-x86_64@spin.c.snap new file mode 100644 index 0000000000..3821a93e89 --- /dev/null +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile-x86_64@spin.c.snap @@ -0,0 +1,23 @@ +--- +source: c2rust-transpile/tests/snapshots.rs +expression: cat tests/snapshots/arch-specific/spin.x86_64.rs +input_file: c2rust-transpile/tests/snapshots/arch-specific/spin.c +--- +#![allow( + dead_code, + mutable_transmutes, + non_camel_case_types, + non_snake_case, + non_upper_case_globals, + unused_assignments, + unused_mut +)] +#![feature(stdsimd)] +#[cfg(target_arch = "x86")] +pub use core::arch::x86::_mm_pause; +#[cfg(target_arch = "x86_64")] +pub use core::arch::x86_64::_mm_pause; +#[no_mangle] +pub unsafe extern "C" fn spin() { + _mm_pause(); +}