Skip to content

Commit e9ab558

Browse files
committed
va_arg: use emit_ptr_va_arg for mips
1 parent 328d053 commit e9ab558

2 files changed

Lines changed: 31 additions & 16 deletions

File tree

compiler/rustc_codegen_llvm/src/va_arg.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1171,14 +1171,29 @@ pub(super) fn emit_va_arg<'ll, 'tcx>(
11711171
AllowHigherAlign::Yes,
11721172
ForceRightAdjust::No,
11731173
),
1174+
Arch::Mips | Arch::Mips32r6 | Arch::Mips64 | Arch::Mips64r6 => emit_ptr_va_arg(
1175+
bx,
1176+
addr,
1177+
target_ty,
1178+
PassMode::Direct,
1179+
match &target.llvm_abiname {
1180+
LlvmAbi::N32 | LlvmAbi::N64 => SlotSize::Bytes8,
1181+
LlvmAbi::O32 => SlotSize::Bytes4,
1182+
other => bug!("unexpected LLVM ABI {other}"),
1183+
},
1184+
AllowHigherAlign::Yes,
1185+
// In big-endian mode the actual value is stored in the right side of the slot, meaning
1186+
// that when the value is smaller than a slot, we need to adjust the pointer we read
1187+
// to somewhere in the middle of the slot.
1188+
match bx.tcx().sess.target.endian {
1189+
Endian::Big => ForceRightAdjust::Yes,
1190+
Endian::Little => ForceRightAdjust::No,
1191+
},
1192+
),
11741193

11751194
Arch::Bpf => bug!("bpf does not support c-variadic functions"),
11761195
Arch::SpirV => bug!("spirv does not support c-variadic functions"),
11771196

1178-
Arch::Mips | Arch::Mips32r6 | Arch::Mips64 | Arch::Mips64r6 => {
1179-
// FIXME: port MipsTargetLowering::lowerVAARG.
1180-
bx.va_arg(addr.immediate(), bx.cx.layout_of(target_ty).llvm_type(bx.cx))
1181-
}
11821197
Arch::Sparc | Arch::Avr | Arch::M68k | Arch::Msp430 => {
11831198
// Clang uses the LLVM implementation for these architectures.
11841199
bx.va_arg(addr.immediate(), bx.cx.layout_of(target_ty).llvm_type(bx.cx))

tests/assembly-llvm/c-variadic-mips.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
//
44
//@ revisions: MIPS MIPS64 MIPS64EL
55
//@ [MIPS] compile-flags: -Copt-level=3 --target mips-unknown-linux-gnu
6+
//@ [MIPS] needs-llvm-components: mips
67
//@ [MIPS64] compile-flags: -Copt-level=3 --target mipsisa64r6-unknown-linux-gnuabi64
8+
//@ [MIPS64] needs-llvm-components: mips
79
//@ [MIPS64EL] compile-flags: -Copt-level=3 --target mips64el-unknown-linux-gnuabi64
8-
//@ needs-llvm-components: mips
10+
//@ [MIPS64EL] needs-llvm-components: mips
911
#![feature(c_variadic, no_core, lang_items, intrinsics, rustc_attrs, asm_experimental_arch)]
1012
#![no_core]
1113
#![crate_type = "lib"]
@@ -88,9 +90,9 @@ unsafe extern "C" fn read_i32(ap: &mut VaList<'_>) -> i32 {
8890
// MIPS64EL: ld $1, 0($4)
8991
// MIPS64EL-NEXT: daddiu $2, $1, 8
9092
// MIPS64EL-NEXT: sd $2, 0($4)
91-
// MIPS64EL-NEXT: lw $1, 0($1)
93+
// MIPS64EL-NEXT: lw $2, 0($1)
9294
// MIPS64EL-NEXT: jr $ra
93-
// MIPS64EL-NEXT: sll $2, $1, 0
95+
// MIPS64EL-NEXT: nop
9496
va_arg(ap)
9597
}
9698

@@ -99,17 +101,15 @@ unsafe extern "C" fn read_i64(ap: &mut VaList<'_>) -> i64 {
99101
// CHECK-LABEL: read_i64
100102
//
101103
// MIPS: lw $1, 0($4)
102-
// MIPS-NEXT: addiu $2, $zero, 4
103-
// MIPS-NEXT: addiu $1, $1, 7
104-
// MIPS-NEXT: move $3, $1
105-
// MIPS-NEXT: ins $3, $2, 0, 3
106104
// MIPS-NEXT: addiu $2, $zero, -8
105+
// MIPS-NEXT: addiu $1, $1, 7
106+
// MIPS-NEXT: and $2, $1, $2
107+
// MIPS-NEXT: addiu $3, $2, 8
107108
// MIPS-NEXT: sw $3, 0($4)
108-
// MIPS-NEXT: and $1, $1, $2
109-
// MIPS-NEXT: lw $2, 0($1)
110-
// MIPS-NEXT: addiu $1, $3, 4
111-
// MIPS-NEXT: sw $1, 0($4)
112-
// MIPS-NEXT: lw $3, 0($3)
109+
// MIPS-NEXT: addiu $3, $zero, 4
110+
// MIPS-NEXT: lw $2, 0($2)
111+
// MIPS-NEXT: ins $1, $3, 0, 3
112+
// MIPS-NEXT: lw $3, 0($1)
113113
// MIPS-NEXT: jr $ra
114114
// MIPS-NEXT: nop
115115
//

0 commit comments

Comments
 (0)