From 94fbb2178ae5960894aaae199233b0d3ac020d79 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sun, 27 Jul 2025 21:21:07 +0200 Subject: [PATCH] implement `va_arg` for arm in rustc itself --- compiler/rustc_codegen_llvm/src/va_arg.rs | 15 +++++++++++++ tests/assembly-llvm/c-variadic-arm.rs | 26 +++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 tests/assembly-llvm/c-variadic-arm.rs diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs index 7eb5d3020588..ab08125217ff 100644 --- a/compiler/rustc_codegen_llvm/src/va_arg.rs +++ b/compiler/rustc_codegen_llvm/src/va_arg.rs @@ -908,6 +908,21 @@ pub(super) fn emit_va_arg<'ll, 'tcx>( ) } "aarch64" => emit_aapcs_va_arg(bx, addr, target_ty), + "arm" => { + // Types wider than 16 bytes are not currently supported. Clang has special logic for + // such types, but `VaArgSafe` is not implemented for any type that is this large. + assert!(bx.cx.size_of(target_ty).bytes() <= 16); + + emit_ptr_va_arg( + bx, + addr, + target_ty, + PassMode::Direct, + SlotSize::Bytes4, + AllowHigherAlign::Yes, + ForceRightAdjust::No, + ) + } "s390x" => emit_s390x_va_arg(bx, addr, target_ty), "powerpc" => emit_powerpc_va_arg(bx, addr, target_ty), "powerpc64" | "powerpc64le" => emit_ptr_va_arg( diff --git a/tests/assembly-llvm/c-variadic-arm.rs b/tests/assembly-llvm/c-variadic-arm.rs new file mode 100644 index 000000000000..2ef307405e13 --- /dev/null +++ b/tests/assembly-llvm/c-variadic-arm.rs @@ -0,0 +1,26 @@ +//@ assembly-output: emit-asm +//@ compile-flags: -Copt-level=3 +//@ only-arm +//@ ignore-thumb +//@ ignore-android +#![no_std] +#![crate_type = "lib"] +#![feature(c_variadic)] + +// Check that the assembly that rustc generates matches what clang emits. + +#[unsafe(no_mangle)] +unsafe extern "C" fn variadic(a: f64, mut args: ...) -> f64 { + // CHECK-LABEL: variadic + // CHECK: sub sp, sp + + // CHECK: vldr + // CHECK: vadd.f64 + // CHECK: vldr + // CHECK: vadd.f64 + let b = args.arg::(); + let c = args.arg::(); + a + b + c + + // CHECK: add sp, sp +}