| //@ run-pass | |
| // Checks if the correct registers are being used to pass arguments | |
| // when the sysv64 ABI is specified. | |
| //@ ignore-android | |
| //@ ignore-arm | |
| //@ ignore-aarch64 | |
| //@ needs-asm-support | |
| #[cfg(target_arch = "x86_64")] | |
| pub extern "sysv64" fn all_the_registers( | |
| rdi: i64, | |
| rsi: i64, | |
| rdx: i64, | |
| rcx: i64, | |
| r8: i64, | |
| r9: i64, | |
| xmm0: f32, | |
| xmm1: f32, | |
| xmm2: f32, | |
| xmm3: f32, | |
| xmm4: f32, | |
| xmm5: f32, | |
| xmm6: f32, | |
| xmm7: f32, | |
| ) -> i64 { | |
| assert_eq!(rdi, 1); | |
| assert_eq!(rsi, 2); | |
| assert_eq!(rdx, 3); | |
| assert_eq!(rcx, 4); | |
| assert_eq!(r8, 5); | |
| assert_eq!(r9, 6); | |
| assert_eq!(xmm0, 1.0f32); | |
| assert_eq!(xmm1, 2.0f32); | |
| assert_eq!(xmm2, 4.0f32); | |
| assert_eq!(xmm3, 8.0f32); | |
| assert_eq!(xmm4, 16.0f32); | |
| assert_eq!(xmm5, 32.0f32); | |
| assert_eq!(xmm6, 64.0f32); | |
| assert_eq!(xmm7, 128.0f32); | |
| 42 | |
| } | |
| // this struct contains 8 i64's, while only 6 can be passed in registers. | |
| #[cfg(target_arch = "x86_64")] | |
| #[derive(PartialEq, Eq, Debug)] | |
| pub struct LargeStruct(i64, i64, i64, i64, i64, i64, i64, i64); | |
| #[cfg(target_arch = "x86_64")] | |
| #[inline(never)] | |
| #[allow(improper_ctypes_definitions)] | |
| pub extern "sysv64" fn large_struct_by_val(mut foo: LargeStruct) -> LargeStruct { | |
| foo.0 *= 1; | |
| foo.1 *= 2; | |
| foo.2 *= 3; | |
| foo.3 *= 4; | |
| foo.4 *= 5; | |
| foo.5 *= 6; | |
| foo.6 *= 7; | |
| foo.7 *= 8; | |
| foo | |
| } | |
| #[cfg(target_arch = "x86_64")] | |
| pub fn main() { | |
| use std::arch::asm; | |
| let result: i64; | |
| unsafe { | |
| asm!("mov rdi, 1", | |
| "mov rsi, 2", | |
| "mov rdx, 3", | |
| "mov rcx, 4", | |
| "mov r8, 5", | |
| "mov r9, 6", | |
| "mov eax, 0x3F800000", | |
| "movd xmm0, eax", | |
| "mov eax, 0x40000000", | |
| "movd xmm1, eax", | |
| "mov eax, 0x40800000", | |
| "movd xmm2, eax", | |
| "mov eax, 0x41000000", | |
| "movd xmm3, eax", | |
| "mov eax, 0x41800000", | |
| "movd xmm4, eax", | |
| "mov eax, 0x42000000", | |
| "movd xmm5, eax", | |
| "mov eax, 0x42800000", | |
| "movd xmm6, eax", | |
| "mov eax, 0x43000000", | |
| "movd xmm7, eax", | |
| "call {0}", | |
| sym all_the_registers, | |
| out("rax") result, | |
| clobber_abi("sysv64"), | |
| ); | |
| } | |
| assert_eq!(result, 42); | |
| assert_eq!( | |
| large_struct_by_val(LargeStruct(1, 2, 3, 4, 5, 6, 7, 8)), | |
| LargeStruct(1, 4, 9, 16, 25, 36, 49, 64) | |
| ); | |
| } | |
| #[cfg(not(target_arch = "x86_64"))] | |
| pub fn main() {} |