Skip to content

Commit 8616c8b

Browse files
committed
c-variadic: add assembly test files
1 parent 6ee5c2a commit 8616c8b

8 files changed

Lines changed: 1485 additions & 0 deletions

File tree

Lines changed: 294 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,294 @@
1+
//@ add-minicore
2+
//@ assembly-output: emit-asm
3+
//
4+
//@ revisions: AARCH64_LINUX AARCH64_DARWIN AARCH64_BE ARM64EC_MSVC
5+
//@ [AARCH64_LINUX] compile-flags: -Copt-level=3 --target aarch64-unknown-linux-gnu
6+
//@ [AARCH64_LINUX] needs-llvm-components: aarch64
7+
//@ [AARCH64_BE] compile-flags: -Copt-level=3 --target aarch64_be-unknown-linux-gnu
8+
//@ [AARCH64_BE] needs-llvm-components: aarch64
9+
//@ [AARCH64_DARWIN] compile-flags: -Copt-level=3 --target aarch64-apple-darwin
10+
//@ [AARCH64_DARWIN] needs-llvm-components: aarch64
11+
//@ [ARM64EC_MSVC] compile-flags: -Copt-level=3 --target arm64ec-pc-windows-msvc
12+
//@ [ARM64EC_MSVC] needs-llvm-components: aarch64
13+
#![feature(c_variadic, no_core, lang_items, intrinsics, rustc_attrs)]
14+
#![no_core]
15+
#![crate_type = "lib"]
16+
17+
// Check that the assembly that rustc generates matches what clang emits.
18+
19+
// For aarch64-unknown-linux-gnu LLVM canonicalizes a comparison, leading to slightly different
20+
// assembly.
21+
//
22+
// For aarch64-apple-darwin LLVM is able to optimize our output better, because we effectively
23+
// desugar va_arg early, hence we don't actually match Clang there.
24+
25+
extern crate minicore;
26+
use minicore::*;
27+
28+
#[lang = "va_arg_safe"]
29+
pub unsafe trait VaArgSafe {}
30+
31+
unsafe impl VaArgSafe for i32 {}
32+
unsafe impl VaArgSafe for i64 {}
33+
unsafe impl VaArgSafe for i128 {}
34+
unsafe impl VaArgSafe for f64 {}
35+
unsafe impl<T> VaArgSafe for *const T {}
36+
37+
#[repr(transparent)]
38+
struct VaListInner {
39+
ptr: *const c_void,
40+
}
41+
42+
#[repr(transparent)]
43+
#[lang = "va_list"]
44+
pub struct VaList<'a> {
45+
inner: VaListInner,
46+
_marker: PhantomData<&'a mut ()>,
47+
}
48+
49+
#[rustc_intrinsic]
50+
#[rustc_nounwind]
51+
pub const unsafe fn va_arg<T: VaArgSafe>(ap: &mut VaList<'_>) -> T;
52+
53+
#[unsafe(no_mangle)]
54+
unsafe extern "C" fn read_f64(ap: &mut VaList<'_>) -> f64 {
55+
// AARCH64_LINUX-LABEL: read_f64:
56+
// AARCH64_LINUX: ldrsw x8, [x0, #28]
57+
// AARCH64_LINUX-NEXT: tbz w8, #31, .LBB0_2
58+
// AARCH64_LINUX-NEXT: add w9, w8, #16
59+
// AARCH64_LINUX-NEXT: cmn w8, #16
60+
// AARCH64_LINUX-NEXT: str w9, [x0, #28]
61+
// AARCH64_LINUX-NEXT: b.ls .LBB0_3
62+
// AARCH64_LINUX-NEXT: .LBB0_2:
63+
// AARCH64_LINUX-NEXT: ldr x8, [x0]
64+
// AARCH64_LINUX-NEXT: ldr d0, [x8]
65+
// AARCH64_LINUX-NEXT: add x9, x8, #8
66+
// AARCH64_LINUX-NEXT: str x9, [x0]
67+
// AARCH64_LINUX-NEXT: ret
68+
// AARCH64_LINUX-NEXT: .LBB0_3
69+
// AARCH64_LINUX-NEXT: ldr x9, [x0, #16]
70+
// AARCH64_LINUX-NEXT: add x8, x9, x8
71+
// AARCH64_LINUX-NEXT: ldr d0, [x8]
72+
// AARCH64_LINUX-NEXT: ret
73+
74+
// AARCH64_BE-LABEL: read_f64:
75+
// AARCH64_BE: ldrsw x8, [x0, #28]
76+
// AARCH64_BE-NEXT: tbz w8, #31, .LBB0_2
77+
// AARCH64_BE-NEXT: add w9, w8, #16
78+
// AARCH64_BE-NEXT: cmn w8, #16
79+
// AARCH64_BE-NEXT: str w9, [x0, #28]
80+
// AARCH64_BE-NEXT: b.ls .LBB0_3
81+
// AARCH64_BE-NEXT: .LBB0_2:
82+
// AARCH64_BE-NEXT: ldr x8, [x0]
83+
// AARCH64_BE-NEXT: ldr d0, [x8]
84+
// AARCH64_BE-NEXT: add x9, x8, #8
85+
// AARCH64_BE-NEXT: str x9, [x0]
86+
// AARCH64_BE-NEXT: ret
87+
// AARCH64_BE-NEXT: .LBB0_3:
88+
// AARCH64_BE-NEXT: ldr x9, [x0, #16]
89+
// AARCH64_BE-NEXT: add x8, x9, x8
90+
// AARCH64_BE-NEXT: ldr d0, [x8, #8]!
91+
// AARCH64_BE-NEXT: ret
92+
93+
// ARM64EC_MSVC-LABEL: read_f64 = "#read_f64"
94+
// ARM64EC_MSVC: ldr x8, [x0]
95+
// ARM64EC_MSVC-NEXT: ldr d0, [x8], #8
96+
// ARM64EC_MSVC-NEXT: str x8, [x0]
97+
// ARM64EC_MSVC-NEXT: ret
98+
99+
// AARCH64_DARWIN-LABEL: _read_f64:
100+
// AARCH64_DARWIN: ldr x8, [x0]
101+
// AARCH64_DARWIN-NEXT: ldr d0, [x8], #8
102+
// AARCH64_DARWIN-NEXT: str x8, [x0]
103+
// AARCH64_DARWIN-NEXT: ret
104+
va_arg(ap)
105+
}
106+
107+
#[unsafe(no_mangle)]
108+
unsafe extern "C" fn read_i32(ap: &mut VaList<'_>) -> i32 {
109+
// AARCH64_LINUX-LABEL: read_i32:
110+
// AARCH64_LINUX: ldrsw x8, [x0, #24]
111+
// AARCH64_LINUX-NEXT: tbz w8, #31, .LBB1_2
112+
// AARCH64_LINUX-NEXT: add w9, w8, #8
113+
// AARCH64_LINUX-NEXT: cmn w8, #8
114+
// AARCH64_LINUX-NEXT: str w9, [x0, #24]
115+
// AARCH64_LINUX-NEXT: b.ls .LBB1_3
116+
// AARCH64_LINUX-NEXT: .LBB1_2:
117+
// AARCH64_LINUX-NEXT: ldr x8, [x0]
118+
// AARCH64_LINUX-NEXT: add x9, x8, #8
119+
// AARCH64_LINUX-NEXT: str x9, [x0]
120+
// AARCH64_LINUX-NEXT: ldr w0, [x8]
121+
// AARCH64_LINUX-NEXT: ret
122+
// AARCH64_LINUX-NEXT: .LBB1_3
123+
// AARCH64_LINUX-NEXT: ldr x9, [x0, #8]
124+
// AARCH64_LINUX-NEXT: add x8, x9, x8
125+
// AARCH64_LINUX-NEXT: ldr w0, [x8]
126+
// AARCH64_LINUX-NEXT: ret
127+
128+
// AARCH64_BE-LABEL: read_i32:
129+
// AARCH64_BE: ldrsw x8, [x0, #24]
130+
// AARCH64_BE-NEXT: tbz w8, #31, .LBB1_2
131+
// AARCH64_BE-NEXT: add w9, w8, #8
132+
// AARCH64_BE-NEXT: cmn w8, #8
133+
// AARCH64_BE-NEXT: str w9, [x0, #24]
134+
// AARCH64_BE-NEXT: b.ls .LBB1_3
135+
// AARCH64_BE-NEXT: .LBB1_2:
136+
// AARCH64_BE-NEXT: ldr x8, [x0]
137+
// AARCH64_BE-NEXT: add x9, x8, #8
138+
// AARCH64_BE-NEXT: str x9, [x0]
139+
// AARCH64_BE-NEXT: ldr w0, [x8]
140+
// AARCH64_BE-NEXT: ret
141+
// AARCH64_BE-NEXT: .LBB1_3:
142+
// AARCH64_BE-NEXT: ldr x9, [x0, #8]
143+
// AARCH64_BE-NEXT: add x8, x9, x8
144+
// AARCH64_BE-NEXT: ldr w0, [x8, #4]!
145+
// AARCH64_BE-NEXT: ret
146+
147+
// ARM64EC_MSVC-LABEL: read_i32 = "#read_i32"
148+
// ARM64EC_MSVC: ldr x9, [x0]
149+
// ARM64EC_MSVC-NEXT: mov x8, x0
150+
// ARM64EC_MSVC-NEXT: ldr w0, [x9], #8
151+
// ARM64EC_MSVC-NEXT: str x9, [x8]
152+
// ARM64EC_MSVC-NEXT: ret
153+
154+
// AARCH64_DARWIN-LABEL: _read_i32:
155+
// AARCH64_DARWIN: ldr x9, [x0]
156+
// AARCH64_DARWIN-NEXT: ldr w8, [x9], #8
157+
// AARCH64_DARWIN-NEXT: str x9, [x0]
158+
// AARCH64_DARWIN-NEXT: mov x0, x8
159+
// AARCH64_DARWIN-NEXT: ret
160+
va_arg(ap)
161+
}
162+
163+
#[unsafe(no_mangle)]
164+
unsafe extern "C" fn read_i64(ap: &mut VaList<'_>) -> i64 {
165+
// AARCH64_LINUX-LABEL: read_i64:
166+
// AARCH64_LINUX: ldrsw x8, [x0, #24]
167+
// AARCH64_LINUX-NEXT: tbz w8, #31, .LBB2_2
168+
// AARCH64_LINUX-NEXT: add w9, w8, #8
169+
// AARCH64_LINUX-NEXT: cmn w8, #8
170+
// AARCH64_LINUX-NEXT: str w9, [x0, #24]
171+
// AARCH64_LINUX-NEXT: b.ls .LBB2_3
172+
// AARCH64_LINUX-NEXT: .LBB2_2:
173+
// AARCH64_LINUX-NEXT: ldr x8, [x0]
174+
// AARCH64_LINUX-NEXT: add x9, x8, #8
175+
// AARCH64_LINUX-NEXT: str x9, [x0]
176+
// AARCH64_LINUX-NEXT: ldr x0, [x8]
177+
// AARCH64_LINUX-NEXT: ret
178+
// AARCH64_LINUX-NEXT: .LBB2_3
179+
// AARCH64_LINUX-NEXT: ldr x9, [x0, #8]
180+
// AARCH64_LINUX-NEXT: add x8, x9, x8
181+
// AARCH64_LINUX-NEXT: ldr x0, [x8]
182+
// AARCH64_LINUX-NEXT: ret
183+
184+
// AARCH64_BE-LABEL: read_i64:
185+
// AARCH64_BE: ldrsw x8, [x0, #24]
186+
// AARCH64_BE-NEXT: tbz w8, #31, .LBB2_2
187+
// AARCH64_BE-NEXT: add w9, w8, #8
188+
// AARCH64_BE-NEXT: cmn w8, #8
189+
// AARCH64_BE-NEXT: str w9, [x0, #24]
190+
// AARCH64_BE-NEXT: b.ls .LBB2_3
191+
// AARCH64_BE-NEXT: .LBB2_2:
192+
// AARCH64_BE-NEXT: ldr x8, [x0]
193+
// AARCH64_BE-NEXT: add x9, x8, #8
194+
// AARCH64_BE-NEXT: str x9, [x0]
195+
// AARCH64_BE-NEXT: ldr x0, [x8]
196+
// AARCH64_BE-NEXT: ret
197+
// AARCH64_BE-NEXT: .LBB2_3:
198+
// AARCH64_BE-NEXT: ldr x9, [x0, #8]
199+
// AARCH64_BE-NEXT: add x8, x9, x8
200+
// AARCH64_BE-NEXT: ldr x0, [x8]
201+
// AARCH64_BE-NEXT: ret
202+
203+
// ARM64EC_MSVC-LABEL: read_ptr = "#read_ptr"
204+
// ARM64EC_MSVC-LABEL: read_i64 = "#read_i64"
205+
// ARM64EC_MSVC: ldr x9, [x0]
206+
// ARM64EC_MSVC-NEXT: mov x8, x0
207+
// ARM64EC_MSVC-NEXT: ldr x0, [x9], #8
208+
// ARM64EC_MSVC-NEXT: str x9, [x8]
209+
// ARM64EC_MSVC-NEXT: ret
210+
211+
// AARCH64_DARWIN-LABEL: _read_i64:
212+
// AARCH64_DARWIN: ldr x9, [x0]
213+
// AARCH64_DARWIN-NEXT: ldr x8, [x9], #8
214+
// AARCH64_DARWIN-NEXT: str x9, [x0]
215+
// AARCH64_DARWIN-NEXT: mov x0, x8
216+
// AARCH64_DARWIN-NEXT: ret
217+
va_arg(ap)
218+
}
219+
220+
#[unsafe(no_mangle)]
221+
unsafe extern "C" fn read_i128(ap: &mut VaList<'_>) -> i128 {
222+
// AARCH64_LINUX-LABEL: read_i128:
223+
// AARCH64_LINUX: ldrsw x8, [x0, #24]
224+
// AARCH64_LINUX-NEXT: tbz w8, #31, .LBB3_2
225+
// AARCH64_LINUX-NEXT: add x8, x8, #15
226+
// AARCH64_LINUX-NEXT: and x8, x8, #0xfffffffffffffff0
227+
// AARCH64_LINUX-NEXT: add w9, w8, #16
228+
// AARCH64_LINUX-NEXT: cmp w9, #0
229+
// AARCH64_LINUX-NEXT: str w9, [x0, #24]
230+
// AARCH64_LINUX-NEXT: b.le .LBB3_3
231+
// AARCH64_LINUX-NEXT: .LBB3_2:
232+
// AARCH64_LINUX-NEXT: ldr x8, [x0]
233+
// AARCH64_LINUX-NEXT: add x8, x8, #15
234+
// AARCH64_LINUX-NEXT: and x8, x8, #0xfffffffffffffff0
235+
// AARCH64_LINUX-NEXT: add x9, x8, #16
236+
// AARCH64_LINUX-NEXT: str x9, [x0]
237+
// AARCH64_LINUX-NEXT: ldp x0, x1, [x8]
238+
// AARCH64_LINUX-NEXT: ret
239+
// AARCH64_LINUX-NEXT: .LBB3_3
240+
// AARCH64_LINUX-NEXT: ldr x9, [x0, #8]
241+
// AARCH64_LINUX-NEXT: add x8, x9, x8
242+
// AARCH64_LINUX-NEXT: ldp x0, x1, [x8]
243+
// AARCH64_LINUX-NEXT: ret
244+
245+
// AARCH64_BE-LABEL: read_i128:
246+
// AARCH64_BE: ldrsw x8, [x0, #24]
247+
// AARCH64_BE-NEXT: tbz w8, #31, .LBB3_2
248+
// AARCH64_BE-NEXT: add x8, x8, #15
249+
// AARCH64_BE-NEXT: and x8, x8, #0xfffffffffffffff0
250+
// AARCH64_BE-NEXT: add w9, w8, #16
251+
// AARCH64_BE-NEXT: cmp w9, #0
252+
// AARCH64_BE-NEXT: str w9, [x0, #24]
253+
// AARCH64_BE-NEXT: b.le .LBB3_3
254+
// AARCH64_BE-NEXT: .LBB3_2:
255+
// AARCH64_BE-NEXT: ldr x8, [x0]
256+
// AARCH64_BE-NEXT: add x8, x8, #15
257+
// AARCH64_BE-NEXT: and x8, x8, #0xfffffffffffffff0
258+
// AARCH64_BE-NEXT: add x9, x8, #16
259+
// AARCH64_BE-NEXT: str x9, [x0]
260+
// AARCH64_BE-NEXT: ldp x0, x1, [x8]
261+
// AARCH64_BE-NEXT: ret
262+
// AARCH64_BE-NEXT: .LBB3_3:
263+
// AARCH64_BE-NEXT: ldr x9, [x0, #8]
264+
// AARCH64_BE-NEXT: add x8, x9, x8
265+
// AARCH64_BE-NEXT: ldp x0, x1, [x8]
266+
// AARCH64_BE-NEXT: ret
267+
268+
// ARM64EC_MSVC-LABEL: read_i128 = "#read_i128"
269+
// ARM64EC_MSVC: ldr x9, [x0]
270+
// ARM64EC_MSVC-NEXT: mov x8, x0
271+
// ARM64EC_MSVC-NEXT: ldp x0, x1, [x9], #16
272+
// ARM64EC_MSVC-NEXT: str x9, [x8]
273+
// ARM64EC_MSVC-NEXT: ret
274+
275+
// AARCH64_DARWIN-LABEL: _read_i128:
276+
// AARCH64_DARWIN: ldr x8, [x0]
277+
// AARCH64_DARWIN-NEXT: add x8, x8, #15
278+
// AARCH64_DARWIN-NEXT: and x9, x8, #0xfffffffffffffff0
279+
// AARCH64_DARWIN-NEXT: ldr x1, [x9, #8]
280+
// AARCH64_DARWIN-NEXT: ldr x8, [x9], #16
281+
// AARCH64_DARWIN-NEXT: str x9, [x0]
282+
// AARCH64_DARWIN-NEXT: mov x0, x8
283+
// AARCH64_DARWIN-NEXT: ret
284+
va_arg(ap)
285+
}
286+
287+
#[unsafe(no_mangle)]
288+
unsafe extern "C" fn read_ptr(ap: &mut VaList<'_>) -> *const u8 {
289+
// AARCH64_LINUX-CHECK: read_ptr = read_i64
290+
// AARCH64_BE-CHECK: read_ptr = read_i64
291+
// ARM64EC_MSVC: "#read_ptr" = "#read_i64"
292+
// AARCH64_DARWIN-CHECK: _read_ptr = _read_i64
293+
va_arg(ap)
294+
}

0 commit comments

Comments
 (0)