2 // Checks if the "sysv64" calling convention behaves the same as the
3 // "C" calling convention on platforms where both should be the same
5 // This file contains versions of the following run-pass tests with
6 // the calling convention changed to "sysv64"
15 // extern-pass-TwoU16s
16 // extern-pass-TwoU32s
17 // extern-pass-TwoU64s
18 // extern-return-TwoU8s
19 // extern-return-TwoU16s
20 // extern-return-TwoU32s
21 // extern-return-TwoU64s
22 // foreign-fn-with-byval
24 // issue-62350-sysv-neg-reg-counts
32 // note: windows is ignored as rust_test_helpers does not have the sysv64 abi on windows
35 #[allow(improper_ctypes)]
37 #[cfg(target_arch = "x86_64")]
40 #[derive(Copy, Clone, PartialEq, Debug)]
46 #[derive(Copy, Clone, PartialEq, Debug)]
52 #[derive(Copy, Clone, PartialEq, Debug)]
58 #[derive(Copy, Clone, PartialEq, Debug)]
77 #[derive(Copy, Clone)]
85 #[derive(Copy, Clone)]
86 pub struct Quad { a: u64, b: u64, c: u64, d: u64 }
88 #[derive(Copy, Clone)]
89 pub struct QuadFloats { a: f32, b: f32, c: f32, d: f32 }
92 #[derive(Copy, Clone)]
93 pub struct Floats { a: f64, b: u8, c: f64 }
96 pub enum U8TaggedEnumOptionU64U64 {
102 pub enum U8TaggedEnumOptionU64 {
107 #[link(name = "rust_test_helpers", kind = "static")]
109 pub fn rust_int8_to_int32(_: i8) -> i32;
110 pub fn rust_dbg_extern_identity_u8(v: u8) -> u8;
111 pub fn rust_dbg_extern_identity_u32(v: u32) -> u32;
112 pub fn rust_dbg_extern_identity_u64(v: u64) -> u64;
113 pub fn rust_dbg_extern_identity_double(v: f64) -> f64;
114 pub fn rust_dbg_extern_empty_struct(v1: ManyInts, e: Empty, v2: ManyInts);
115 pub fn rust_dbg_extern_identity_TwoU8s(v: TwoU8s) -> TwoU8s;
116 pub fn rust_dbg_extern_identity_TwoU16s(v: TwoU16s) -> TwoU16s;
117 pub fn rust_dbg_extern_identity_TwoU32s(v: TwoU32s) -> TwoU32s;
118 pub fn rust_dbg_extern_identity_TwoU64s(v: TwoU64s) -> TwoU64s;
119 pub fn rust_dbg_extern_return_TwoU8s() -> TwoU8s;
120 pub fn rust_dbg_extern_return_TwoU16s() -> TwoU16s;
121 pub fn rust_dbg_extern_return_TwoU32s() -> TwoU32s;
122 pub fn rust_dbg_extern_return_TwoU64s() -> TwoU64s;
123 pub fn get_x(x: S) -> u64;
124 pub fn get_y(x: S) -> u64;
125 pub fn get_z(x: S) -> u64;
126 pub fn get_c_many_params(_: *const (), _: *const (),
127 _: *const (), _: *const (), f: Quad) -> u64;
128 pub fn get_c_exhaust_sysv64_ints(
138 pub fn rust_dbg_abi_1(q: Quad) -> Quad;
139 pub fn rust_dbg_abi_2(f: Floats) -> Floats;
140 pub fn rust_dbg_new_some_u64u64(a: u64, b: u64) -> U8TaggedEnumOptionU64U64;
141 pub fn rust_dbg_new_none_u64u64() -> U8TaggedEnumOptionU64U64;
142 pub fn rust_dbg_unpack_option_u64u64(
143 o: U8TaggedEnumOptionU64U64,
147 pub fn rust_dbg_new_some_u64(some: u64) -> U8TaggedEnumOptionU64;
148 pub fn rust_dbg_new_none_u64() -> U8TaggedEnumOptionU64;
149 pub fn rust_dbg_unpack_option_u64(o: U8TaggedEnumOptionU64, v: *mut u64) -> i32;
152 pub fn cabi_int_widening() {
154 rust_int8_to_int32(-1)
160 pub fn extern_pass_char() {
162 assert_eq!(22, rust_dbg_extern_identity_u8(22));
166 pub fn extern_pass_u32() {
168 assert_eq!(22, rust_dbg_extern_identity_u32(22));
172 pub fn extern_pass_u64() {
174 assert_eq!(22, rust_dbg_extern_identity_u64(22));
178 pub fn extern_pass_double() {
180 assert_eq!(22.0_f64, rust_dbg_extern_identity_double(22.0_f64));
184 pub fn extern_pass_empty() {
192 arg6: TwoU8s { one: 7, two: 8, }
200 arg6: TwoU8s { one: 6, two: 7, }
203 rust_dbg_extern_empty_struct(x, empty, y);
207 pub fn extern_pass_twou8s() {
209 let x = TwoU8s {one: 22, two: 23};
210 let y = rust_dbg_extern_identity_TwoU8s(x);
215 pub fn extern_pass_twou16s() {
217 let x = TwoU16s {one: 22, two: 23};
218 let y = rust_dbg_extern_identity_TwoU16s(x);
223 pub fn extern_pass_twou32s() {
225 let x = TwoU32s {one: 22, two: 23};
226 let y = rust_dbg_extern_identity_TwoU32s(x);
231 pub fn extern_pass_twou64s() {
233 let x = TwoU64s {one: 22, two: 23};
234 let y = rust_dbg_extern_identity_TwoU64s(x);
239 pub fn extern_return_twou8s() {
241 let y = rust_dbg_extern_return_TwoU8s();
242 assert_eq!(y.one, 10);
243 assert_eq!(y.two, 20);
247 pub fn extern_return_twou16s() {
249 let y = rust_dbg_extern_return_TwoU16s();
250 assert_eq!(y.one, 10);
251 assert_eq!(y.two, 20);
255 pub fn extern_return_twou32s() {
257 let y = rust_dbg_extern_return_TwoU32s();
258 assert_eq!(y.one, 10);
259 assert_eq!(y.two, 20);
263 pub fn extern_return_twou64s() {
265 let y = rust_dbg_extern_return_TwoU64s();
266 assert_eq!(y.one, 10);
267 assert_eq!(y.two, 20);
272 fn indirect_call(func: unsafe extern "sysv64" fn(s: S) -> u64, s: S) -> u64 {
278 pub fn foreign_fn_with_byval() {
279 let s = S { x: 1, y: 2, z: 3 };
280 assert_eq!(s.x, indirect_call(get_x, s));
281 assert_eq!(s.y, indirect_call(get_y, s));
282 assert_eq!(s.z, indirect_call(get_z, s));
288 let null = ptr::null();
295 assert_eq!(get_c_many_params(null, null, null, null, q), q.c);
299 pub fn issue_28676() {
306 let null = ptr::null();
314 get_c_exhaust_sysv64_ints(null, null, null, null, null, null, null, q),
320 pub fn issue_62350() {
326 let q = Quad { a: 0xaaaa_aaaa_aaaa_aaaa,
327 b: 0xbbbb_bbbb_bbbb_bbbb,
328 c: 0xcccc_cccc_cccc_cccc,
329 d: 0xdddd_dddd_dddd_dddd };
330 let qq = rust_dbg_abi_1(q);
331 println!("a: {:x}", qq.a as usize);
332 println!("b: {:x}", qq.b as usize);
333 println!("c: {:x}", qq.c as usize);
334 println!("d: {:x}", qq.d as usize);
335 assert_eq!(qq.a, q.c + 1);
336 assert_eq!(qq.b, q.d - 1);
337 assert_eq!(qq.c, q.a + 1);
338 assert_eq!(qq.d, q.b - 1);
344 let f = Floats { a: 1.234567890e-15_f64,
346 c: 1.0987654321e-15_f64 };
347 let ff = rust_dbg_abi_2(f);
348 println!("a: {}", ff.a as f64);
349 println!("b: {}", ff.b as usize);
350 println!("c: {}", ff.c as f64);
351 assert_eq!(ff.a, f.c + 1.0f64);
352 assert_eq!(ff.b, 0xff);
353 assert_eq!(ff.c, f.a - 1.0f64);
357 pub fn struct_return() {
362 pub fn enum_passing_and_return_pair() {
363 let some_u64u64 = unsafe { rust_dbg_new_some_u64u64(10, 20) };
364 if let U8TaggedEnumOptionU64U64::Some(a, b) = some_u64u64 {
368 panic!("unexpected none");
371 let none_u64u64 = unsafe { rust_dbg_new_none_u64u64() };
372 if let U8TaggedEnumOptionU64U64::Some(_,_) = none_u64u64 {
373 panic!("unexpected some");
379 rust_dbg_unpack_option_u64u64(some_u64u64, &mut a as *mut _, &mut b as *mut _)
388 rust_dbg_unpack_option_u64u64(none_u64u64, &mut a as *mut _, &mut b as *mut _)
395 pub fn enum_passing_and_return() {
396 let some_u64 = unsafe { rust_dbg_new_some_u64(10) };
397 if let U8TaggedEnumOptionU64::Some(v) = some_u64 {
400 panic!("unexpected none");
403 let none_u64 = unsafe { rust_dbg_new_none_u64() };
404 if let U8TaggedEnumOptionU64::Some(_) = none_u64 {
405 panic!("unexpected some");
408 let mut target: u64 = 0;
409 let r = unsafe { rust_dbg_unpack_option_u64(some_u64, &mut target as *mut _) };
411 assert_eq!(10, target);
413 let mut target: u64 = 0;
414 let r = unsafe { rust_dbg_unpack_option_u64(none_u64, &mut target as *mut _) };
416 assert_eq!(0, target);
420 #[cfg(target_arch = "x86_64")]
427 extern_pass_double();
429 extern_pass_twou8s();
430 extern_pass_twou16s();
431 extern_pass_twou32s();
432 extern_pass_twou64s();
433 extern_return_twou8s();
434 extern_return_twou16s();
435 extern_return_twou32s();
436 extern_return_twou64s();
437 foreign_fn_with_byval();
441 enum_passing_and_return_pair();
442 enum_passing_and_return();
445 #[cfg(not(target_arch = "x86_64"))]