mirror of
https://github.com/rust-lang/rust
synced 2024-11-05 20:45:15 +00:00
107 lines
2.5 KiB
Rust
107 lines
2.5 KiB
Rust
//@ 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() {}
|