blob: 46b59395485c53eb0680d52845ad289a863b5012 [file] [log] [blame]
//@ run-pass
//@ only-x86_64
//@ only-linux
#![feature(c_variadic)]
#[repr(C)]
#[derive(Debug, PartialEq)]
struct Data(i32, f64);
#[unsafe(naked)]
unsafe extern "C" fn c_variadic(_: ...) -> Data {
// This assembly was generated with GCC, because clang/LLVM is unable to
// optimize out the spilling of all registers to the stack.
core::arch::naked_asm!(
" sub rsp, 96",
" mov QWORD PTR [rsp-88], rdi",
" test al, al",
" je .L7",
" movaps XMMWORD PTR [rsp-40], xmm0",
".L7:",
" lea rax, [rsp+104]",
" mov rcx, QWORD PTR [rsp-40]",
" mov DWORD PTR [rsp-112], 0",
" mov QWORD PTR [rsp-104], rax",
" lea rax, [rsp-88]",
" mov QWORD PTR [rsp-96], rax",
" movq xmm0, rcx",
" mov eax, DWORD PTR [rsp-88]",
" mov DWORD PTR [rsp-108], 48",
" add rsp, 96",
" ret",
)
}
fn main() {
unsafe {
assert_eq!(c_variadic(1, 2.0), Data(1, 2.0));
assert_eq!(c_variadic(123, 4.56), Data(123, 4.56));
}
}