Skip to content

Commit f036fae

Browse files
committed
Grouping ABI test #62401
1 parent 1cdcea9 commit f036fae

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1695
-0
lines changed
Lines changed: 366 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,366 @@
1+
// Checks if the "sysv64" calling convention behaves the same as the
2+
// "C" calling convention on platforms where both should be the same
3+
4+
// This file contains versions of the following run-pass tests with
5+
// the calling convention changed to "sysv64"
6+
7+
// cabi-int-widening
8+
// extern-pass-char
9+
// extern-pass-u32
10+
// extern-pass-u64
11+
// extern-pass-double
12+
// extern-pass-empty
13+
// extern-pass-TwoU8s
14+
// extern-pass-TwoU16s
15+
// extern-pass-TwoU32s
16+
// extern-pass-TwoU64s
17+
// extern-return-TwoU8s
18+
// extern-return-TwoU16s
19+
// extern-return-TwoU32s
20+
// extern-return-TwoU64s
21+
// foreign-fn-with-byval
22+
// issue-28676
23+
// issue-62350-sysv-neg-reg-counts
24+
// struct-return
25+
26+
// ignore-android
27+
// ignore-arm
28+
// ignore-aarch64
29+
// ignore-windows
30+
31+
// note: windows is ignored as rust_test_helpers does not have the sysv64 abi on windows
32+
33+
#[allow(dead_code)]
34+
#[allow(improper_ctypes)]
35+
36+
#[cfg(target_arch = "x86_64")]
37+
mod tests {
38+
#[repr(C)]
39+
#[derive(Copy, Clone, PartialEq, Debug)]
40+
pub struct TwoU8s {
41+
one: u8, two: u8
42+
}
43+
44+
#[repr(C)]
45+
#[derive(Copy, Clone, PartialEq, Debug)]
46+
pub struct TwoU16s {
47+
one: u16, two: u16
48+
}
49+
50+
#[repr(C)]
51+
#[derive(Copy, Clone, PartialEq, Debug)]
52+
pub struct TwoU32s {
53+
one: u32, two: u32
54+
}
55+
56+
#[repr(C)]
57+
#[derive(Copy, Clone, PartialEq, Debug)]
58+
pub struct TwoU64s {
59+
one: u64, two: u64
60+
}
61+
62+
#[repr(C)]
63+
pub struct ManyInts {
64+
arg1: i8,
65+
arg2: i16,
66+
arg3: i32,
67+
arg4: i16,
68+
arg5: i8,
69+
arg6: TwoU8s,
70+
}
71+
72+
#[repr(C)]
73+
pub struct Empty;
74+
75+
#[repr(C)]
76+
#[derive(Copy, Clone)]
77+
pub struct S {
78+
x: u64,
79+
y: u64,
80+
z: u64,
81+
}
82+
83+
#[repr(C)]
84+
#[derive(Copy, Clone)]
85+
pub struct Quad { a: u64, b: u64, c: u64, d: u64 }
86+
87+
#[derive(Copy, Clone)]
88+
pub struct QuadFloats { a: f32, b: f32, c: f32, d: f32 }
89+
90+
#[repr(C)]
91+
#[derive(Copy, Clone)]
92+
pub struct Floats { a: f64, b: u8, c: f64 }
93+
94+
#[link(name = "rust_test_helpers", kind = "static")]
95+
extern "sysv64" {
96+
pub fn rust_int8_to_int32(_: i8) -> i32;
97+
pub fn rust_dbg_extern_identity_u8(v: u8) -> u8;
98+
pub fn rust_dbg_extern_identity_u32(v: u32) -> u32;
99+
pub fn rust_dbg_extern_identity_u64(v: u64) -> u64;
100+
pub fn rust_dbg_extern_identity_double(v: f64) -> f64;
101+
pub fn rust_dbg_extern_empty_struct(v1: ManyInts, e: Empty, v2: ManyInts);
102+
pub fn rust_dbg_extern_identity_TwoU8s(v: TwoU8s) -> TwoU8s;
103+
pub fn rust_dbg_extern_identity_TwoU16s(v: TwoU16s) -> TwoU16s;
104+
pub fn rust_dbg_extern_identity_TwoU32s(v: TwoU32s) -> TwoU32s;
105+
pub fn rust_dbg_extern_identity_TwoU64s(v: TwoU64s) -> TwoU64s;
106+
pub fn rust_dbg_extern_return_TwoU8s() -> TwoU8s;
107+
pub fn rust_dbg_extern_return_TwoU16s() -> TwoU16s;
108+
pub fn rust_dbg_extern_return_TwoU32s() -> TwoU32s;
109+
pub fn rust_dbg_extern_return_TwoU64s() -> TwoU64s;
110+
pub fn get_x(x: S) -> u64;
111+
pub fn get_y(x: S) -> u64;
112+
pub fn get_z(x: S) -> u64;
113+
pub fn get_c_many_params(_: *const (), _: *const (),
114+
_: *const (), _: *const (), f: Quad) -> u64;
115+
pub fn get_c_exhaust_sysv64_ints(
116+
_: *const (),
117+
_: *const (),
118+
_: *const (),
119+
_: *const (),
120+
_: *const (),
121+
_: *const (),
122+
_: *const (),
123+
h: QuadFloats,
124+
) -> f32;
125+
pub fn rust_dbg_abi_1(q: Quad) -> Quad;
126+
pub fn rust_dbg_abi_2(f: Floats) -> Floats;
127+
}
128+
129+
pub fn cabi_int_widening() {
130+
let x = unsafe {
131+
rust_int8_to_int32(-1)
132+
};
133+
134+
assert!(x == -1);
135+
}
136+
137+
pub fn extern_pass_char() {
138+
unsafe {
139+
assert_eq!(22, rust_dbg_extern_identity_u8(22));
140+
}
141+
}
142+
143+
pub fn extern_pass_u32() {
144+
unsafe {
145+
assert_eq!(22, rust_dbg_extern_identity_u32(22));
146+
}
147+
}
148+
149+
pub fn extern_pass_u64() {
150+
unsafe {
151+
assert_eq!(22, rust_dbg_extern_identity_u64(22));
152+
}
153+
}
154+
155+
pub fn extern_pass_double() {
156+
unsafe {
157+
assert_eq!(22.0_f64, rust_dbg_extern_identity_double(22.0_f64));
158+
}
159+
}
160+
161+
pub fn extern_pass_empty() {
162+
unsafe {
163+
let x = ManyInts {
164+
arg1: 2,
165+
arg2: 3,
166+
arg3: 4,
167+
arg4: 5,
168+
arg5: 6,
169+
arg6: TwoU8s { one: 7, two: 8, }
170+
};
171+
let y = ManyInts {
172+
arg1: 1,
173+
arg2: 2,
174+
arg3: 3,
175+
arg4: 4,
176+
arg5: 5,
177+
arg6: TwoU8s { one: 6, two: 7, }
178+
};
179+
let empty = Empty;
180+
rust_dbg_extern_empty_struct(x, empty, y);
181+
}
182+
}
183+
184+
pub fn extern_pass_twou8s() {
185+
unsafe {
186+
let x = TwoU8s {one: 22, two: 23};
187+
let y = rust_dbg_extern_identity_TwoU8s(x);
188+
assert_eq!(x, y);
189+
}
190+
}
191+
192+
pub fn extern_pass_twou16s() {
193+
unsafe {
194+
let x = TwoU16s {one: 22, two: 23};
195+
let y = rust_dbg_extern_identity_TwoU16s(x);
196+
assert_eq!(x, y);
197+
}
198+
}
199+
200+
pub fn extern_pass_twou32s() {
201+
unsafe {
202+
let x = TwoU32s {one: 22, two: 23};
203+
let y = rust_dbg_extern_identity_TwoU32s(x);
204+
assert_eq!(x, y);
205+
}
206+
}
207+
208+
pub fn extern_pass_twou64s() {
209+
unsafe {
210+
let x = TwoU64s {one: 22, two: 23};
211+
let y = rust_dbg_extern_identity_TwoU64s(x);
212+
assert_eq!(x, y);
213+
}
214+
}
215+
216+
pub fn extern_return_twou8s() {
217+
unsafe {
218+
let y = rust_dbg_extern_return_TwoU8s();
219+
assert_eq!(y.one, 10);
220+
assert_eq!(y.two, 20);
221+
}
222+
}
223+
224+
pub fn extern_return_twou16s() {
225+
unsafe {
226+
let y = rust_dbg_extern_return_TwoU16s();
227+
assert_eq!(y.one, 10);
228+
assert_eq!(y.two, 20);
229+
}
230+
}
231+
232+
pub fn extern_return_twou32s() {
233+
unsafe {
234+
let y = rust_dbg_extern_return_TwoU32s();
235+
assert_eq!(y.one, 10);
236+
assert_eq!(y.two, 20);
237+
}
238+
}
239+
240+
pub fn extern_return_twou64s() {
241+
unsafe {
242+
let y = rust_dbg_extern_return_TwoU64s();
243+
assert_eq!(y.one, 10);
244+
assert_eq!(y.two, 20);
245+
}
246+
}
247+
248+
#[inline(never)]
249+
fn indirect_call(func: unsafe extern "sysv64" fn(s: S) -> u64, s: S) -> u64 {
250+
unsafe {
251+
func(s)
252+
}
253+
}
254+
255+
pub fn foreign_fn_with_byval() {
256+
let s = S { x: 1, y: 2, z: 3 };
257+
assert_eq!(s.x, indirect_call(get_x, s));
258+
assert_eq!(s.y, indirect_call(get_y, s));
259+
assert_eq!(s.z, indirect_call(get_z, s));
260+
}
261+
262+
fn test() {
263+
use std::ptr;
264+
unsafe {
265+
let null = ptr::null();
266+
let q = Quad {
267+
a: 1,
268+
b: 2,
269+
c: 3,
270+
d: 4
271+
};
272+
assert_eq!(get_c_many_params(null, null, null, null, q), q.c);
273+
}
274+
}
275+
276+
pub fn issue_28676() {
277+
test();
278+
}
279+
280+
fn test_62350() {
281+
use std::ptr;
282+
unsafe {
283+
let null = ptr::null();
284+
let q = QuadFloats {
285+
a: 10.2,
286+
b: 20.3,
287+
c: 30.4,
288+
d: 40.5
289+
};
290+
assert_eq!(
291+
get_c_exhaust_sysv64_ints(null, null, null, null, null, null, null, q),
292+
q.c,
293+
);
294+
}
295+
}
296+
297+
pub fn issue_62350() {
298+
test_62350();
299+
}
300+
301+
fn test1() {
302+
unsafe {
303+
let q = Quad { a: 0xaaaa_aaaa_aaaa_aaaa,
304+
b: 0xbbbb_bbbb_bbbb_bbbb,
305+
c: 0xcccc_cccc_cccc_cccc,
306+
d: 0xdddd_dddd_dddd_dddd };
307+
let qq = rust_dbg_abi_1(q);
308+
println!("a: {:x}", qq.a as usize);
309+
println!("b: {:x}", qq.b as usize);
310+
println!("c: {:x}", qq.c as usize);
311+
println!("d: {:x}", qq.d as usize);
312+
assert_eq!(qq.a, q.c + 1);
313+
assert_eq!(qq.b, q.d - 1);
314+
assert_eq!(qq.c, q.a + 1);
315+
assert_eq!(qq.d, q.b - 1);
316+
}
317+
}
318+
319+
fn test2() {
320+
unsafe {
321+
let f = Floats { a: 1.234567890e-15_f64,
322+
b: 0b_1010_1010,
323+
c: 1.0987654321e-15_f64 };
324+
let ff = rust_dbg_abi_2(f);
325+
println!("a: {}", ff.a as f64);
326+
println!("b: {}", ff.b as usize);
327+
println!("c: {}", ff.c as f64);
328+
assert_eq!(ff.a, f.c + 1.0f64);
329+
assert_eq!(ff.b, 0xff);
330+
assert_eq!(ff.c, f.a - 1.0f64);
331+
}
332+
}
333+
334+
pub fn struct_return() {
335+
test1();
336+
test2();
337+
}
338+
}
339+
340+
#[cfg(target_arch = "x86_64")]
341+
fn main() {
342+
use tests::*;
343+
cabi_int_widening();
344+
extern_pass_char();
345+
extern_pass_u32();
346+
extern_pass_u64();
347+
extern_pass_double();
348+
extern_pass_empty();
349+
extern_pass_twou8s();
350+
extern_pass_twou16s();
351+
extern_pass_twou32s();
352+
extern_pass_twou64s();
353+
extern_return_twou8s();
354+
extern_return_twou16s();
355+
extern_return_twou32s();
356+
extern_return_twou64s();
357+
foreign_fn_with_byval();
358+
issue_28676();
359+
issue_62350();
360+
struct_return();
361+
}
362+
363+
#[cfg(not(target_arch = "x86_64"))]
364+
fn main() {
365+
366+
}

0 commit comments

Comments
 (0)