|
| 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. |
| 27 | +core::arch::global_asm!( |
| 28 | + r#" |
| 29 | +variadic_sysv64: |
| 30 | + sub rsp, 88 |
| 31 | + test al, al |
| 32 | + je .LBB0_7 |
| 33 | + movaps xmmword ptr [rsp - 48], xmm0 |
| 34 | + movaps xmmword ptr [rsp - 32], xmm1 |
| 35 | + movaps xmmword ptr [rsp - 16], xmm2 |
| 36 | + movaps xmmword ptr [rsp], xmm3 |
| 37 | + movaps xmmword ptr [rsp + 16], xmm4 |
| 38 | + movaps xmmword ptr [rsp + 32], xmm5 |
| 39 | + movaps xmmword ptr [rsp + 48], xmm6 |
| 40 | + movaps xmmword ptr [rsp + 64], xmm7 |
| 41 | +.LBB0_7: |
| 42 | + mov qword ptr [rsp - 88], rsi |
| 43 | + mov qword ptr [rsp - 80], rdx |
| 44 | + mov qword ptr [rsp - 72], rcx |
| 45 | + mov qword ptr [rsp - 64], r8 |
| 46 | + mov qword ptr [rsp - 56], r9 |
| 47 | + movabs rax, 206158430216 |
| 48 | + mov qword ptr [rsp - 120], rax |
| 49 | + lea rax, [rsp + 96] |
| 50 | + mov qword ptr [rsp - 112], rax |
| 51 | + lea rax, [rsp - 96] |
| 52 | + mov qword ptr [rsp - 104], rax |
| 53 | + mov edx, 8 |
| 54 | + cmp rdx, 41 |
| 55 | + jae .LBB0_1 |
| 56 | + mov rax, qword ptr [rsp - 104] |
| 57 | + mov ecx, 8 |
| 58 | + add rcx, 8 |
| 59 | + mov dword ptr [rsp - 120], ecx |
| 60 | + mov eax, dword ptr [rax + rdx] |
| 61 | + cmp edx, 32 |
| 62 | + ja .LBB0_2 |
| 63 | + add rcx, qword ptr [rsp - 104] |
| 64 | + add edx, 16 |
| 65 | + mov dword ptr [rsp - 120], edx |
| 66 | + add eax, edi |
| 67 | + add eax, dword ptr [rcx] |
| 68 | + add rsp, 88 |
| 69 | + ret |
| 70 | +.LBB0_1: |
| 71 | + mov rax, qword ptr [rsp - 112] |
| 72 | + lea rcx, [rax + 8] |
| 73 | + mov qword ptr [rsp - 112], rcx |
| 74 | + mov eax, dword ptr [rax] |
| 75 | +.LBB0_2: |
| 76 | + mov rcx, qword ptr [rsp - 112] |
| 77 | + lea rdx, [rcx + 8] |
| 78 | + mov qword ptr [rsp - 112], rdx |
| 79 | + add eax, edi |
| 80 | + add eax, dword ptr [rcx] |
| 81 | + add rsp, 88 |
| 82 | + ret |
| 83 | +
|
| 84 | +variadic_win64: |
| 85 | + push rax |
| 86 | + mov qword ptr [rsp + 40], r9 |
| 87 | + mov qword ptr [rsp + 24], rdx |
| 88 | + mov qword ptr [rsp + 32], r8 |
| 89 | + lea rax, [rsp + 40] |
| 90 | + mov qword ptr [rsp], rax |
| 91 | + lea eax, [rdx + rcx] |
| 92 | + add eax, r8d |
| 93 | + pop rcx |
| 94 | + ret |
| 95 | + "# |
| 96 | +); |
0 commit comments