1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
//@ 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));
}
}
|