Skip to content

Commit db6dcea

Browse files
committed
Unrolled build for #165467 in rollup 165510
Rollup merge of #165467 - beetrees:va-arg-msp430, r=folkertdev Use `emit_ptr_va_arg` for `va_arg` on MSP430 This avoids needing to use the LLVM `va_arg` instruction. The implementation matches LLVM and GCC (checked by comparing the assembly), with the exception that GCC doesn't seem to align the `va_list` pointer before a `va_arg(va, void*)` - AFAICT this is a GCC bug as GCC does align pointers when passing them to C-variadic functions. This PR always correctly aligns the pointer, matching LLVM and the spec. cc @cr1901 r? @folkertdev
2 parents 712e1d3 + 1e6c9e4 commit db6dcea

2 files changed

Lines changed: 95 additions & 1 deletion

File tree

‎compiler/rustc_codegen_llvm/src/va_arg.rs‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1295,11 +1295,20 @@ pub(super) fn emit_va_arg<'ll, 'tcx>(
12951295
Endian::Little => ForceRightAdjust::No,
12961296
},
12971297
),
1298+
Arch::Msp430 => emit_ptr_va_arg(
1299+
bx,
1300+
addr,
1301+
layout,
1302+
PassMode::Direct,
1303+
SlotSize::Bytes1,
1304+
AllowHigherAlign::Yes,
1305+
ForceRightAdjust::No,
1306+
),
12981307

12991308
Arch::Bpf => bug!("bpf does not support c-variadic functions"),
13001309
Arch::SpirV => bug!("spirv does not support c-variadic functions"),
13011310

1302-
Arch::Avr | Arch::M68k | Arch::Msp430 => {
1311+
Arch::Avr | Arch::M68k => {
13031312
std::assert_matches!(stability, CVariadicStatus::Unstable { .. });
13041313

13051314
// Clang uses the LLVM implementation for these architectures.
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
//@ add-minicore
2+
//@ assembly-output: emit-asm
3+
//
4+
//@ compile-flags: -Copt-level=3 --target=msp430-none-elf
5+
//@ needs-llvm-components: msp430
6+
#![feature(c_variadic_experimental_arch, no_core, lang_items, intrinsics, rustc_attrs)]
7+
#![no_core]
8+
#![crate_type = "lib"]
9+
10+
extern crate minicore;
11+
use minicore::ffi::VaList;
12+
use minicore::*;
13+
14+
#[unsafe(no_mangle)]
15+
unsafe extern "C" fn read_f64(ap: &mut VaList<'_>) -> f64 {
16+
// CHECK-LABEL: read_f64
17+
//
18+
// CHECK: mov #1, r15
19+
// CHECK-NEXT: add 0(r12), r15
20+
// CHECK-NEXT: and #-2, r15
21+
// CHECK-NEXT: mov r15, r13
22+
// CHECK-NEXT: add #8, r13
23+
// CHECK-NEXT: mov r13, 0(r12)
24+
// CHECK-NEXT: mov 0(r15), r12
25+
// CHECK-NEXT: mov 2(r15), r13
26+
// CHECK-NEXT: mov 4(r15), r14
27+
// CHECK-NEXT: mov 6(r15), r15
28+
// CHECK-NEXT: ret
29+
ap.next_arg()
30+
}
31+
32+
#[unsafe(no_mangle)]
33+
unsafe extern "C" fn read_i16(ap: &mut VaList<'_>) -> i16 {
34+
// CHECK-LABEL: read_i16
35+
//
36+
// CHECK: mov #1, r13
37+
// CHECK-NEXT: add 0(r12), r13
38+
// CHECK-NEXT: and #-2, r13
39+
// CHECK-NEXT: mov r13, r14
40+
// CHECK-NEXT: incd r14
41+
// CHECK-NEXT: mov r14, 0(r12)
42+
// CHECK-NEXT: mov 0(r13), r12
43+
// CHECK-NEXT: ret
44+
ap.next_arg()
45+
}
46+
47+
#[unsafe(no_mangle)]
48+
unsafe extern "C" fn read_i32(ap: &mut VaList<'_>) -> i32 {
49+
// CHECK-LABEL: read_i32
50+
//
51+
// CHECK: mov #1, r13
52+
// CHECK-NEXT: add 0(r12), r13
53+
// CHECK-NEXT: and #-2, r13
54+
// CHECK-NEXT: mov r13, r14
55+
// CHECK-NEXT: add #4, r14
56+
// CHECK-NEXT: mov r14, 0(r12)
57+
// CHECK-NEXT: mov 0(r13), r12
58+
// CHECK-NEXT: mov 2(r13), r13
59+
// CHECK-NEXT: ret
60+
ap.next_arg()
61+
}
62+
63+
#[unsafe(no_mangle)]
64+
unsafe extern "C" fn read_i64(ap: &mut VaList<'_>) -> i64 {
65+
// CHECK-LABEL: read_i64
66+
//
67+
// CHECK: mov #1, r15
68+
// CHECK-NEXT: add 0(r12), r15
69+
// CHECK-NEXT: and #-2, r15
70+
// CHECK-NEXT: mov r15, r13
71+
// CHECK-NEXT: add #8, r13
72+
// CHECK-NEXT: mov r13, 0(r12)
73+
// CHECK-NEXT: mov 0(r15), r12
74+
// CHECK-NEXT: mov 2(r15), r13
75+
// CHECK-NEXT: mov 4(r15), r14
76+
// CHECK-NEXT: mov 6(r15), r15
77+
// CHECK-NEXT: ret
78+
ap.next_arg()
79+
}
80+
81+
#[unsafe(no_mangle)]
82+
unsafe extern "C" fn read_ptr(ap: &mut VaList<'_>) -> *const u8 {
83+
// CHECK: read_ptr = read_i16
84+
ap.next_arg()
85+
}

0 commit comments

Comments
 (0)