Skip to content

Commit aea74c4

Browse files
committed
test using multiple c-variadic ABIs in the same program
1 parent 29a5872 commit aea74c4

File tree

1 file changed

+113
-0
lines changed

1 file changed

+113
-0
lines changed
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#![feature(extended_varargs_abi_support)]
2+
//@ run-pass
3+
//@ only-x86_64
4+
5+
// Check that multiple c-variadic calling conventions can be used in the same program.
6+
//
7+
// Clang and gcc reject defining functions with a non-default calling convention and a variable
8+
// argument list, so C programs that use multiple c-variadic calling conventions are unlikely
9+
// to come up. Here we validate that our codegen backends do in fact generate correct code.
10+
11+
extern "sysv64" {
12+
fn variadic_sysv64(_: u32, _: ...) -> u32;
13+
}
14+
15+
extern "win64" {
16+
fn variadic_win64(_: u32, _: ...) -> u32;
17+
}
18+
19+
fn main() {
20+
unsafe {
21+
assert_eq!(variadic_win64(1, 2, 3), 1 + 2 + 3);
22+
assert_eq!(variadic_sysv64(1, 2, 3), 1 + 2 + 3);
23+
}
24+
}
25+
26+
// This assembly was generated using https://godbolt.org/z/dbTGanoh6, and corresponds to this C:
27+
//
28+
// ```c
29+
// #include <stdarg.h>
30+
// #include <stdint.h>
31+
//
32+
// uint32_t variadic(uint32_t a, ...) {
33+
// va_list args;
34+
// va_start(args, a);
35+
//
36+
// uint32_t b = va_arg(args, uint32_t);
37+
// uint32_t c = va_arg(args, uint32_t);
38+
//
39+
// va_end(args);
40+
//
41+
// return a + b + c;
42+
// }
43+
// ```
44+
core::arch::global_asm!(
45+
r#"
46+
variadic_sysv64:
47+
sub rsp, 88
48+
test al, al
49+
je .LBB0_7
50+
movaps xmmword ptr [rsp - 48], xmm0
51+
movaps xmmword ptr [rsp - 32], xmm1
52+
movaps xmmword ptr [rsp - 16], xmm2
53+
movaps xmmword ptr [rsp], xmm3
54+
movaps xmmword ptr [rsp + 16], xmm4
55+
movaps xmmword ptr [rsp + 32], xmm5
56+
movaps xmmword ptr [rsp + 48], xmm6
57+
movaps xmmword ptr [rsp + 64], xmm7
58+
.LBB0_7:
59+
mov qword ptr [rsp - 88], rsi
60+
mov qword ptr [rsp - 80], rdx
61+
mov qword ptr [rsp - 72], rcx
62+
mov qword ptr [rsp - 64], r8
63+
mov qword ptr [rsp - 56], r9
64+
movabs rax, 206158430216
65+
mov qword ptr [rsp - 120], rax
66+
lea rax, [rsp + 96]
67+
mov qword ptr [rsp - 112], rax
68+
lea rax, [rsp - 96]
69+
mov qword ptr [rsp - 104], rax
70+
mov edx, 8
71+
cmp rdx, 41
72+
jae .LBB0_1
73+
mov rax, qword ptr [rsp - 104]
74+
mov ecx, 8
75+
add rcx, 8
76+
mov dword ptr [rsp - 120], ecx
77+
mov eax, dword ptr [rax + rdx]
78+
cmp edx, 32
79+
ja .LBB0_2
80+
add rcx, qword ptr [rsp - 104]
81+
add edx, 16
82+
mov dword ptr [rsp - 120], edx
83+
add eax, edi
84+
add eax, dword ptr [rcx]
85+
add rsp, 88
86+
ret
87+
.LBB0_1:
88+
mov rax, qword ptr [rsp - 112]
89+
lea rcx, [rax + 8]
90+
mov qword ptr [rsp - 112], rcx
91+
mov eax, dword ptr [rax]
92+
.LBB0_2:
93+
mov rcx, qword ptr [rsp - 112]
94+
lea rdx, [rcx + 8]
95+
mov qword ptr [rsp - 112], rdx
96+
add eax, edi
97+
add eax, dword ptr [rcx]
98+
add rsp, 88
99+
ret
100+
101+
variadic_win64:
102+
push rax
103+
mov qword ptr [rsp + 40], r9
104+
mov qword ptr [rsp + 24], rdx
105+
mov qword ptr [rsp + 32], r8
106+
lea rax, [rsp + 40]
107+
mov qword ptr [rsp], rax
108+
lea eax, [rdx + rcx]
109+
add eax, r8d
110+
pop rcx
111+
ret
112+
"#
113+
);

0 commit comments

Comments
 (0)