Skip to content

Commit 51cf09f

Browse files
committed
c-variadic: add mips assembly test
1 parent 5d97cbf commit 51cf09f

1 file changed

Lines changed: 137 additions & 0 deletions

File tree

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
//@ add-minicore
2+
//@ assembly-output: emit-asm
3+
//
4+
//@ revisions: mips mips64 mips64el
5+
//@ [mips] compile-flags: -Copt-level=3 --target mips-unknown-linux-gnu
6+
//@ [mips64] compile-flags: -Copt-level=3 --target mipsisa64r6-unknown-linux-gnuabi64
7+
//@ [mips64el] compile-flags: -Copt-level=3 --target mips64el-unknown-linux-gnuabi64
8+
//@ needs-llvm-components: mips
9+
#![feature(c_variadic, no_core, lang_items, intrinsics, rustc_attrs, asm_experimental_arch)]
10+
#![no_core]
11+
#![crate_type = "lib"]
12+
13+
// Check that the assembly that rustc generates matches what clang emits.
14+
15+
extern crate minicore;
16+
use minicore::*;
17+
18+
#[lang = "va_arg_safe"]
19+
pub unsafe trait VaArgSafe {}
20+
21+
unsafe impl VaArgSafe for i32 {}
22+
unsafe impl VaArgSafe for i64 {}
23+
unsafe impl VaArgSafe for f64 {}
24+
unsafe impl<T> VaArgSafe for *const T {}
25+
26+
#[repr(transparent)]
27+
struct VaListInner {
28+
ptr: *const c_void,
29+
}
30+
31+
#[repr(transparent)]
32+
#[lang = "va_list"]
33+
pub struct VaList<'a> {
34+
inner: VaListInner,
35+
_marker: PhantomData<&'a mut ()>,
36+
}
37+
38+
#[rustc_intrinsic]
39+
#[rustc_nounwind]
40+
pub const unsafe fn va_arg<T: VaArgSafe>(ap: &mut VaList<'_>) -> T;
41+
42+
#[unsafe(no_mangle)]
43+
unsafe extern "C" fn read_f64(ap: &mut VaList<'_>) -> f64 {
44+
// CHECK-LABEL: read_f64
45+
//
46+
// mips: lw $1, 0($4)
47+
// mips-NEXT: addiu $2, $zero, -8
48+
// mips-NEXT: addiu $1, $1, 7
49+
// mips-NEXT: and $1, $1, $2
50+
// mips-NEXT: addiu $2, $1, 8
51+
// mips-NEXT: sw $2, 0($4)
52+
// mips-NEXT: ldc1 $f0, 0($1)
53+
// mips-NEXT: jr $ra
54+
// mips-NEXT: nop
55+
//
56+
// mips64: ld $1, 0($4)
57+
// mips64-NEXT: daddiu $2, $1, 8
58+
// mips64-NEXT: sd $2, 0($4)
59+
// mips64-NEXT: ldc1 $f0, 0($1)
60+
// mips64-NEXT: jrc $ra
61+
//
62+
// mips64el: ld $1, 0($4)
63+
// mips64el-NEXT: daddiu $2, $1, 8
64+
// mips64el-NEXT: sd $2, 0($4)
65+
// mips64el-NEXT: ldc1 $f0, 0($1)
66+
// mips64el-NEXT: jr $ra
67+
// mips64el-NEXT: nop
68+
va_arg(ap)
69+
}
70+
71+
#[unsafe(no_mangle)]
72+
unsafe extern "C" fn read_i32(ap: &mut VaList<'_>) -> i32 {
73+
// CHECK-LABEL: read_i32
74+
//
75+
// mips: lw $1, 0($4)
76+
// mips-NEXT: addiu $2, $1, 4
77+
// mips-NEXT: sw $2, 0($4)
78+
// mips-NEXT: lw $2, 0($1)
79+
// mips-NEXT: jr $ra
80+
// mips-NEXT: nop
81+
//
82+
// mips64: ld $1, 0($4)
83+
// mips64-NEXT: daddiu $2, $1, 8
84+
// mips64-NEXT: sd $2, 0($4)
85+
// mips64-NEXT: lw $2, 4($1)
86+
// mips64-NEXT: jrc $ra
87+
//
88+
// mips64el: ld $1, 0($4)
89+
// mips64el-NEXT: daddiu $2, $1, 8
90+
// mips64el-NEXT: sd $2, 0($4)
91+
// mips64el-NEXT: lw $1, 0($1)
92+
// mips64el-NEXT: jr $ra
93+
// mips64el-NEXT: sll $2, $1, 0
94+
va_arg(ap)
95+
}
96+
97+
#[unsafe(no_mangle)]
98+
unsafe extern "C" fn read_i64(ap: &mut VaList<'_>) -> i64 {
99+
// CHECK-LABEL: read_i64
100+
//
101+
// 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
106+
// mips-NEXT: addiu $2, $zero, -8
107+
// 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)
113+
// mips-NEXT: jr $ra
114+
// mips-NEXT: nop
115+
//
116+
// mips64: ld $1, 0($4)
117+
// mips64-NEXT: daddiu $2, $1, 8
118+
// mips64-NEXT: sd $2, 0($4)
119+
// mips64-NEXT: ld $2, 0($1)
120+
// mips64-NEXT: jrc $ra
121+
//
122+
// mips64el: ld $1, 0($4)
123+
// mips64el-NEXT: daddiu $2, $1, 8
124+
// mips64el-NEXT: sd $2, 0($4)
125+
// mips64el-NEXT: ld $2, 0($1)
126+
// mips64el-NEXT: jr $ra
127+
// mips64el-NEXT: nop
128+
va_arg(ap)
129+
}
130+
131+
#[unsafe(no_mangle)]
132+
unsafe extern "C" fn read_ptr(ap: &mut VaList<'_>) -> *const u8 {
133+
// mips: read_ptr = read_i32
134+
// mips64: read_ptr = read_i64
135+
// mips64el: read_ptr = read_i64
136+
va_arg(ap)
137+
}

0 commit comments

Comments
 (0)