From 933281088cdd3b20f5b6d4266fb42b9cddf60d18 Mon Sep 17 00:00:00 2001 From: Bee Date: Wed, 4 Nov 2026 17:35:59 +0000 Subject: [PATCH] Use `emit_ptr_va_arg` for `va_arg` on M68k --- compiler/rustc_codegen_llvm/src/builder.rs | 4 -- compiler/rustc_codegen_llvm/src/va_arg.rs | 16 +++--- tests/assembly-llvm/c-variadic/m68k.rs | 67 ++++++++++++++++++++++ 3 files changed, 76 insertions(+), 11 deletions(-) create mode 100644 tests/assembly-llvm/c-variadic/m68k.rs diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index ed5da8e69246f..e02d561f52507 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -1838,10 +1838,6 @@ impl<'a, 'll, CX: Borrow>> GenericBuilder<'a, 'll, CX> { Cow::Owned(casted_args) } - - pub(crate) fn va_arg(&mut self, list: &'ll Value, ty: Type<'ll>) -> &'ll Value { - unsafe { llvm::LLVMBuildVAArg(self.llbuilder(), list, ty, UNNAMED) } - } } impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs index bef94359fa2e5..542e2fba1f807 100644 --- a/compiler/rustc_codegen_llvm/src/va_arg.rs +++ b/compiler/rustc_codegen_llvm/src/va_arg.rs @@ -1313,17 +1313,19 @@ pub(super) fn emit_va_arg<'ll, 'tcx>( AllowHigherAlign::No, ForceRightAdjust::No, ), + Arch::M68k => emit_ptr_va_arg( + bx, + addr, + layout, + PassMode::Direct, + SlotSize::Bytes4, + AllowHigherAlign::No, + ForceRightAdjust::Yes, + ), Arch::Bpf => bug!("bpf does not support c-variadic functions"), Arch::SpirV => bug!("spirv does not support c-variadic functions"), - Arch::M68k => { - std::assert_matches!(stability, CVariadicStatus::Unstable { .. }); - - // Clang uses the LLVM implementation for these architectures. - bx.va_arg(addr.immediate(), layout.llvm_type(bx.cx)) - } - Arch::Other(ref arch) => { std::assert_matches!(stability, CVariadicStatus::Unstable { .. }); diff --git a/tests/assembly-llvm/c-variadic/m68k.rs b/tests/assembly-llvm/c-variadic/m68k.rs new file mode 100644 index 0000000000000..2e6898afa79b1 --- /dev/null +++ b/tests/assembly-llvm/c-variadic/m68k.rs @@ -0,0 +1,67 @@ +//@ add-minicore +//@ assembly-output: emit-asm +// +//@ compile-flags: -Copt-level=3 --target=m68k-unknown-linux-gnu +//@ needs-llvm-components: m68k +#![feature(c_variadic_experimental_arch, no_core, lang_items, intrinsics, rustc_attrs)] +#![no_core] +#![crate_type = "lib"] + +extern crate minicore; +use minicore::ffi::VaList; +use minicore::*; + +// This checks `va_arg` does the same thing as GCC. + +#[unsafe(no_mangle)] +unsafe extern "C" fn read_f64(ap: &mut VaList<'_>) -> f64 { + // CHECK-LABEL: read_f64 + // + // CHECK: move.l (4,%sp), %a0 + // CHECK-NEXT: move.l (%a0), %d0 + // CHECK-NEXT: move.l %d0, %d1 + // CHECK-NEXT: add.l #8, %d1 + // CHECK-NEXT: move.l %d1, (%a0) + // CHECK-NEXT: move.l %d0, %a0 + // CHECK-NEXT: move.l (%a0), %d0 + // CHECK-NEXT: move.l (4,%a0), %d1 + // CHECK-NEXT: rts + ap.next_arg() +} + +#[unsafe(no_mangle)] +unsafe extern "C" fn read_i32(ap: &mut VaList<'_>) -> i32 { + // CHECK-LABEL: read_i32 + // + // CHECK: move.l (4,%sp), %a0 + // CHECK-NEXT: move.l (%a0), %d0 + // CHECK-NEXT: move.l %d0, %d1 + // CHECK-NEXT: add.l #4, %d1 + // CHECK-NEXT: move.l %d1, (%a0) + // CHECK-NEXT: move.l %d0, %a0 + // CHECK-NEXT: move.l (%a0), %d0 + // CHECK-NEXT: rts + ap.next_arg() +} + +#[unsafe(no_mangle)] +unsafe extern "C" fn read_i64(ap: &mut VaList<'_>) -> i64 { + // CHECK-LABEL: read_i64 + // + // CHECK: move.l (4,%sp), %a0 + // CHECK-NEXT: move.l (%a0), %d0 + // CHECK-NEXT: move.l %d0, %d1 + // CHECK-NEXT: add.l #8, %d1 + // CHECK-NEXT: move.l %d1, (%a0) + // CHECK-NEXT: move.l %d0, %a0 + // CHECK-NEXT: move.l (%a0), %d0 + // CHECK-NEXT: move.l (4,%a0), %d1 + // CHECK-NEXT: rts + ap.next_arg() +} + +#[unsafe(no_mangle)] +unsafe extern "C" fn read_ptr(ap: &mut VaList<'_>) -> *const u8 { + // CHECK: read_ptr = read_i32 + ap.next_arg() +}