1 // Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 // Checks if the "sysv64" calling convention behaves the same as the
12 // "C" calling convention on platforms where both should be the same
14 // This file contains versions of the following run-pass tests with
15 // the calling convention changed to "sysv64"
24 // extern-pass-TwoU16s
25 // extern-pass-TwoU32s
26 // extern-pass-TwoU64s
27 // extern-return-TwoU8s
28 // extern-return-TwoU16s
29 // extern-return-TwoU32s
30 // extern-return-TwoU64s
31 // foreign-fn-with-byval
40 // note: windows is ignored as rust_test_helpers does not have the sysv64 abi on windows
42 #![feature(abi_sysv64)]
44 #[allow(improper_ctypes)]
46 #[cfg(target_arch = "x86_64")]
49 #[derive(Copy, Clone, PartialEq, Debug)]
55 #[derive(Copy, Clone, PartialEq, Debug)]
61 #[derive(Copy, Clone, PartialEq, Debug)]
67 #[derive(Copy, Clone, PartialEq, Debug)]
86 #[derive(Copy, Clone)]
94 #[derive(Copy, Clone)]
95 pub struct Quad { a: u64, b: u64, c: u64, d: u64 }
98 #[derive(Copy, Clone)]
99 pub struct Floats { a: f64, b: u8, c: f64 }
101 #[link(name = "rust_test_helpers")]
103 pub fn rust_int8_to_int32(_
: i8) -> i32;
104 pub fn rust_dbg_extern_identity_u8(v
: u8) -> u8;
105 pub fn rust_dbg_extern_identity_u32(v
: u32) -> u32;
106 pub fn rust_dbg_extern_identity_u64(v
: u64) -> u64;
107 pub fn rust_dbg_extern_identity_double(v
: f64) -> f64;
108 pub fn rust_dbg_extern_empty_struct(v1
: ManyInts
, e
: Empty
, v2
: ManyInts
);
109 pub fn rust_dbg_extern_identity_TwoU8s(v
: TwoU8s
) -> TwoU8s
;
110 pub fn rust_dbg_extern_identity_TwoU16s(v
: TwoU16s
) -> TwoU16s
;
111 pub fn rust_dbg_extern_identity_TwoU32s(v
: TwoU32s
) -> TwoU32s
;
112 pub fn rust_dbg_extern_identity_TwoU64s(v
: TwoU64s
) -> TwoU64s
;
113 pub fn rust_dbg_extern_return_TwoU8s() -> TwoU8s
;
114 pub fn rust_dbg_extern_return_TwoU16s() -> TwoU16s
;
115 pub fn rust_dbg_extern_return_TwoU32s() -> TwoU32s
;
116 pub fn rust_dbg_extern_return_TwoU64s() -> TwoU64s
;
117 pub fn get_x(x
: S
) -> u64;
118 pub fn get_y(x
: S
) -> u64;
119 pub fn get_z(x
: S
) -> u64;
120 pub fn get_c_many_params(_
: *const (), _
: *const (),
121 _
: *const (), _
: *const (), f
: Quad
) -> u64;
122 pub fn rust_dbg_abi_1(q
: Quad
) -> Quad
;
123 pub fn rust_dbg_abi_2(f
: Floats
) -> Floats
;
126 pub fn cabi_int_widening() {
128 rust_int8_to_int32(-1)
134 pub fn extern_pass_char() {
136 assert_eq
!(22, rust_dbg_extern_identity_u8(22));
140 pub fn extern_pass_u32() {
142 assert_eq
!(22, rust_dbg_extern_identity_u32(22));
146 pub fn extern_pass_u64() {
148 assert_eq
!(22, rust_dbg_extern_identity_u64(22));
152 pub fn extern_pass_double() {
154 assert_eq
!(22.0_f64, rust_dbg_extern_identity_double(22.0_f64));
158 pub fn extern_pass_empty() {
166 arg6
: TwoU8s { one: 7, two: 8, }
174 arg6
: TwoU8s { one: 6, two: 7, }
177 rust_dbg_extern_empty_struct(x
, empty
, y
);
181 pub fn extern_pass_twou8s() {
183 let x
= TwoU8s {one: 22, two: 23}
;
184 let y
= rust_dbg_extern_identity_TwoU8s(x
);
189 pub fn extern_pass_twou16s() {
191 let x
= TwoU16s {one: 22, two: 23}
;
192 let y
= rust_dbg_extern_identity_TwoU16s(x
);
197 pub fn extern_pass_twou32s() {
199 let x
= TwoU32s {one: 22, two: 23}
;
200 let y
= rust_dbg_extern_identity_TwoU32s(x
);
205 pub fn extern_pass_twou64s() {
207 let x
= TwoU64s {one: 22, two: 23}
;
208 let y
= rust_dbg_extern_identity_TwoU64s(x
);
213 pub fn extern_return_twou8s() {
215 let y
= rust_dbg_extern_return_TwoU8s();
216 assert_eq
!(y
.one
, 10);
217 assert_eq
!(y
.two
, 20);
221 pub fn extern_return_twou16s() {
223 let y
= rust_dbg_extern_return_TwoU16s();
224 assert_eq
!(y
.one
, 10);
225 assert_eq
!(y
.two
, 20);
229 pub fn extern_return_twou32s() {
231 let y
= rust_dbg_extern_return_TwoU32s();
232 assert_eq
!(y
.one
, 10);
233 assert_eq
!(y
.two
, 20);
237 pub fn extern_return_twou64s() {
239 let y
= rust_dbg_extern_return_TwoU64s();
240 assert_eq
!(y
.one
, 10);
241 assert_eq
!(y
.two
, 20);
246 fn indirect_call(func
: unsafe extern "sysv64" fn(s
: S
) -> u64, s
: S
) -> u64 {
252 pub fn foreign_fn_with_byval() {
253 let s
= S { x: 1, y: 2, z: 3 }
;
254 assert_eq
!(s
.x
, indirect_call(get_x
, s
));
255 assert_eq
!(s
.y
, indirect_call(get_y
, s
));
256 assert_eq
!(s
.z
, indirect_call(get_z
, s
));
262 let null
= ptr
::null();
269 assert_eq
!(get_c_many_params(null
, null
, null
, null
, q
), q
.c
);
273 pub fn issue_28676() {
279 let q
= Quad
{ a
: 0xaaaa_aaaa_aaaa_aaaa,
280 b
: 0xbbbb_bbbb_bbbb_bbbb,
281 c
: 0xcccc_cccc_cccc_cccc,
282 d
: 0xdddd_dddd_dddd_dddd };
283 let qq
= rust_dbg_abi_1(q
);
284 println
!("a: {:x}", qq
.a
as usize);
285 println
!("b: {:x}", qq
.b
as usize);
286 println
!("c: {:x}", qq
.c
as usize);
287 println
!("d: {:x}", qq
.d
as usize);
288 assert_eq
!(qq
.a
, q
.c
+ 1);
289 assert_eq
!(qq
.b
, q
.d
- 1);
290 assert_eq
!(qq
.c
, q
.a
+ 1);
291 assert_eq
!(qq
.d
, q
.b
- 1);
297 let f
= Floats
{ a
: 1.234567890e-15_f64,
299 c
: 1.0987654321e-15_f64 };
300 let ff
= rust_dbg_abi_2(f
);
301 println
!("a: {}", ff
.a
as f64);
302 println
!("b: {}", ff
.b
as usize);
303 println
!("c: {}", ff
.c
as f64);
304 assert_eq
!(ff
.a
, f
.c
+ 1.0f64);
305 assert_eq
!(ff
.b
, 0xff);
306 assert_eq
!(ff
.c
, f
.a
- 1.0f64);
310 pub fn struct_return() {
316 #[cfg(target_arch = "x86_64")]
323 extern_pass_double();
325 extern_pass_twou8s();
326 extern_pass_twou16s();
327 extern_pass_twou32s();
328 extern_pass_twou64s();
329 extern_return_twou8s();
330 extern_return_twou16s();
331 extern_return_twou32s();
332 extern_return_twou64s();
333 foreign_fn_with_byval();
338 #[cfg(not(target_arch = "x86_64"))]