Skip to content

test using multiple c-variadic ABIs in the same program #144379

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 112 additions & 0 deletions tests/ui/c-variadic/same-program-multiple-abis.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#![feature(extended_varargs_abi_support)]
//@ run-pass
//@ only-x86_64

// Check that multiple c-variadic calling conventions can be used in the same program.
//
// Clang and gcc reject defining functions with a non-default calling convention and a variable
// argument list, so C programs that use multiple c-variadic calling conventions are unlikely
// to come up. Here we validate that our codegen backends do in fact generate correct code.

extern "sysv64" {
fn variadic_sysv64(_: u32, _: ...) -> u32;
}

extern "win64" {
fn variadic_win64(_: u32, _: ...) -> u32;
}

fn main() {
unsafe {
assert_eq!(variadic_win64(1, 2, 3), 1 + 2 + 3);
assert_eq!(variadic_sysv64(1, 2, 3), 1 + 2 + 3);
}
}

// This assembly was generated using https://godbolt.org/z/dbTGanoh6, and corresponds to the
// following code compiled for the `x86_64-unknown-linux-gnu` and `x86_64-pc-windows-gnu`
// targets, respectively:
//
// ```rust
// #![feature(c_variadic)]
//
// #[unsafe(no_mangle)]
// unsafe extern "C" fn variadic(a: u32, mut args: ...) -> u32 {
// let b = args.arg::<u32>();
// let c = args.arg::<u32>();
//
// a + b + c
// }
// ```
core::arch::global_asm!(
r#"
{variadic_sysv64}:
sub rsp, 88
test al, al
je .LBB0_7
movaps xmmword ptr [rsp - 48], xmm0
movaps xmmword ptr [rsp - 32], xmm1
movaps xmmword ptr [rsp - 16], xmm2
movaps xmmword ptr [rsp], xmm3
movaps xmmword ptr [rsp + 16], xmm4
movaps xmmword ptr [rsp + 32], xmm5
movaps xmmword ptr [rsp + 48], xmm6
movaps xmmword ptr [rsp + 64], xmm7
.LBB0_7:
mov qword ptr [rsp - 88], rsi
mov qword ptr [rsp - 80], rdx
mov qword ptr [rsp - 72], rcx
mov qword ptr [rsp - 64], r8
mov qword ptr [rsp - 56], r9
movabs rax, 206158430216
mov qword ptr [rsp - 120], rax
lea rax, [rsp + 96]
mov qword ptr [rsp - 112], rax
lea rax, [rsp - 96]
mov qword ptr [rsp - 104], rax
mov edx, 8
cmp rdx, 41
jae .LBB0_1
mov rax, qword ptr [rsp - 104]
mov ecx, 8
add rcx, 8
mov dword ptr [rsp - 120], ecx
mov eax, dword ptr [rax + rdx]
cmp edx, 32
ja .LBB0_2
add rcx, qword ptr [rsp - 104]
add edx, 16
mov dword ptr [rsp - 120], edx
add eax, edi
add eax, dword ptr [rcx]
add rsp, 88
ret
.LBB0_1:
mov rax, qword ptr [rsp - 112]
lea rcx, [rax + 8]
mov qword ptr [rsp - 112], rcx
mov eax, dword ptr [rax]
.LBB0_2:
mov rcx, qword ptr [rsp - 112]
lea rdx, [rcx + 8]
mov qword ptr [rsp - 112], rdx
add eax, edi
add eax, dword ptr [rcx]
add rsp, 88
ret

{variadic_win64}:
push rax
mov qword ptr [rsp + 40], r9
mov qword ptr [rsp + 24], rdx
mov qword ptr [rsp + 32], r8
lea rax, [rsp + 40]
mov qword ptr [rsp], rax
lea eax, [rdx + rcx]
add eax, r8d
pop rcx
ret
"#,
variadic_win64 = sym variadic_win64,
variadic_sysv64 = sym variadic_sysv64,
);
Loading