diff options
| author | Tobias Decking <Tobias.Decking@gmail.com> | 2024-06-20 20:11:16 +0200 |
|---|---|---|
| committer | Tobias Decking <Tobias.Decking@gmail.com> | 2024-06-21 15:16:49 +0200 |
| commit | 9afd75259155bdfb0ca707bf5ac6ea5faf50812f (patch) | |
| tree | 7f3c18f2ca0a2ef2af64e0260e4275e9d10aa051 /src/tools/miri/tests | |
| parent | 66ad792c4ef99dd9e3d3e5303eaaeec867857cae (diff) | |
| download | rust-9afd75259155bdfb0ca707bf5ac6ea5faf50812f.tar.gz rust-9afd75259155bdfb0ca707bf5ac6ea5faf50812f.zip | |
Implement LLVM x86 adx intrinsics
Diffstat (limited to 'src/tools/miri/tests')
| -rw-r--r-- | src/tools/miri/tests/pass/shims/x86/intrinsics-x86-adx.rs | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-adx.rs b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-adx.rs new file mode 100644 index 00000000000..431e7f2c5eb --- /dev/null +++ b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-adx.rs @@ -0,0 +1,70 @@ +// Ignore everything except x86 and x86_64 +// Any new targets that are added to CI should be ignored here. +// (We cannot use `cfg`-based tricks here since the `target-feature` flags below only work on x86.) +//@ignore-target-aarch64 +//@ignore-target-arm +//@ignore-target-avr +//@ignore-target-s390x +//@ignore-target-thumbv7em +//@ignore-target-wasm32 +//@compile-flags: -C target-feature=+adx + +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +mod x86 { + #[cfg(target_arch = "x86")] + use core::arch::x86 as arch; + #[cfg(target_arch = "x86_64")] + use core::arch::x86_64 as arch; + + fn adc(c_in: u8, a: u32, b: u32) -> (u8, u32) { + let mut sum = 0; + // SAFETY: There are no safety requirements for calling `_addcarry_u32`. + // It's just unsafe for API consistency with other intrinsics. + let c_out = unsafe { arch::_addcarryx_u32(c_in, a, b, &mut sum) }; + (c_out, sum) + } + + pub fn main() { + assert_eq!(adc(0, 1, 1), (0, 2)); + assert_eq!(adc(1, 1, 1), (0, 3)); + assert_eq!(adc(2, 1, 1), (0, 3)); // any non-zero carry acts as 1! + assert_eq!(adc(u8::MAX, 1, 1), (0, 3)); + assert_eq!(adc(0, u32::MAX, u32::MAX), (1, u32::MAX - 1)); + assert_eq!(adc(1, u32::MAX, u32::MAX), (1, u32::MAX)); + assert_eq!(adc(2, u32::MAX, u32::MAX), (1, u32::MAX)); + assert_eq!(adc(u8::MAX, u32::MAX, u32::MAX), (1, u32::MAX)); + } +} + +#[cfg(target_arch = "x86_64")] +mod x86_64 { + use core::arch::x86_64 as arch; + + fn adc(c_in: u8, a: u64, b: u64) -> (u8, u64) { + let mut sum = 0; + // SAFETY: There are no safety requirements for calling `_addcarry_u64`. + // It's just unsafe for API consistency with other intrinsics. + let c_out = unsafe { arch::_addcarryx_u64(c_in, a, b, &mut sum) }; + (c_out, sum) + } + + pub fn main() { + assert_eq!(adc(0, 1, 1), (0, 2)); + assert_eq!(adc(1, 1, 1), (0, 3)); + assert_eq!(adc(2, 1, 1), (0, 3)); // any non-zero carry acts as 1! + assert_eq!(adc(u8::MAX, 1, 1), (0, 3)); + assert_eq!(adc(0, u64::MAX, u64::MAX), (1, u64::MAX - 1)); + assert_eq!(adc(1, u64::MAX, u64::MAX), (1, u64::MAX)); + assert_eq!(adc(2, u64::MAX, u64::MAX), (1, u64::MAX)); + assert_eq!(adc(u8::MAX, u64::MAX, u64::MAX), (1, u64::MAX)); + } +} + +fn main() { + assert!(is_x86_feature_detected!("adx")); + + #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] + x86::main(); + #[cfg(target_arch = "x86_64")] + x86_64::main(); +} |
