]> git.proxmox.com Git - rustc.git/blob - src/test/run-pass/abi-sysv64-arg-passing.rs
New upstream version 1.13.0+dfsg1
[rustc.git] / src / test / run-pass / abi-sysv64-arg-passing.rs
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.
4 //
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.
10
11 // Checks if the "sysv64" calling convention behaves the same as the
12 // "C" calling convention on platforms where both should be the same
13
14 // This file contains versions of the following run-pass tests with
15 // the calling convention changed to "sysv64"
16
17 // cabi-int-widening
18 // extern-pass-char
19 // extern-pass-u32
20 // extern-pass-u64
21 // extern-pass-double
22 // extern-pass-empty
23 // extern-pass-TwoU8s
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
32 // issue-28676
33 // struct-return
34
35 // ignore-android
36 // ignore-arm
37 // ignore-aarch64
38 // ignore-windows
39
40 // note: windows is ignored as rust_test_helpers does not have the sysv64 abi on windows
41
42 #![feature(abi_sysv64)]
43 #[allow(dead_code)]
44 #[allow(improper_ctypes)]
45
46 #[cfg(target_arch = "x86_64")]
47 mod tests {
48 #[repr(C)]
49 #[derive(Copy, Clone, PartialEq, Debug)]
50 pub struct TwoU8s {
51 one: u8, two: u8
52 }
53
54 #[repr(C)]
55 #[derive(Copy, Clone, PartialEq, Debug)]
56 pub struct TwoU16s {
57 one: u16, two: u16
58 }
59
60 #[repr(C)]
61 #[derive(Copy, Clone, PartialEq, Debug)]
62 pub struct TwoU32s {
63 one: u32, two: u32
64 }
65
66 #[repr(C)]
67 #[derive(Copy, Clone, PartialEq, Debug)]
68 pub struct TwoU64s {
69 one: u64, two: u64
70 }
71
72 #[repr(C)]
73 pub struct ManyInts {
74 arg1: i8,
75 arg2: i16,
76 arg3: i32,
77 arg4: i16,
78 arg5: i8,
79 arg6: TwoU8s,
80 }
81
82 #[repr(C)]
83 pub struct Empty;
84
85 #[repr(C)]
86 #[derive(Copy, Clone)]
87 pub struct S {
88 x: u64,
89 y: u64,
90 z: u64,
91 }
92
93 #[repr(C)]
94 #[derive(Copy, Clone)]
95 pub struct Quad { a: u64, b: u64, c: u64, d: u64 }
96
97 #[repr(C)]
98 #[derive(Copy, Clone)]
99 pub struct Floats { a: f64, b: u8, c: f64 }
100
101 #[link(name = "rust_test_helpers")]
102 extern "sysv64" {
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;
124 }
125
126 pub fn cabi_int_widening() {
127 let x = unsafe {
128 rust_int8_to_int32(-1)
129 };
130
131 assert!(x == -1);
132 }
133
134 pub fn extern_pass_char() {
135 unsafe {
136 assert_eq!(22, rust_dbg_extern_identity_u8(22));
137 }
138 }
139
140 pub fn extern_pass_u32() {
141 unsafe {
142 assert_eq!(22, rust_dbg_extern_identity_u32(22));
143 }
144 }
145
146 pub fn extern_pass_u64() {
147 unsafe {
148 assert_eq!(22, rust_dbg_extern_identity_u64(22));
149 }
150 }
151
152 pub fn extern_pass_double() {
153 unsafe {
154 assert_eq!(22.0_f64, rust_dbg_extern_identity_double(22.0_f64));
155 }
156 }
157
158 pub fn extern_pass_empty() {
159 unsafe {
160 let x = ManyInts {
161 arg1: 2,
162 arg2: 3,
163 arg3: 4,
164 arg4: 5,
165 arg5: 6,
166 arg6: TwoU8s { one: 7, two: 8, }
167 };
168 let y = ManyInts {
169 arg1: 1,
170 arg2: 2,
171 arg3: 3,
172 arg4: 4,
173 arg5: 5,
174 arg6: TwoU8s { one: 6, two: 7, }
175 };
176 let empty = Empty;
177 rust_dbg_extern_empty_struct(x, empty, y);
178 }
179 }
180
181 pub fn extern_pass_twou8s() {
182 unsafe {
183 let x = TwoU8s {one: 22, two: 23};
184 let y = rust_dbg_extern_identity_TwoU8s(x);
185 assert_eq!(x, y);
186 }
187 }
188
189 pub fn extern_pass_twou16s() {
190 unsafe {
191 let x = TwoU16s {one: 22, two: 23};
192 let y = rust_dbg_extern_identity_TwoU16s(x);
193 assert_eq!(x, y);
194 }
195 }
196
197 pub fn extern_pass_twou32s() {
198 unsafe {
199 let x = TwoU32s {one: 22, two: 23};
200 let y = rust_dbg_extern_identity_TwoU32s(x);
201 assert_eq!(x, y);
202 }
203 }
204
205 pub fn extern_pass_twou64s() {
206 unsafe {
207 let x = TwoU64s {one: 22, two: 23};
208 let y = rust_dbg_extern_identity_TwoU64s(x);
209 assert_eq!(x, y);
210 }
211 }
212
213 pub fn extern_return_twou8s() {
214 unsafe {
215 let y = rust_dbg_extern_return_TwoU8s();
216 assert_eq!(y.one, 10);
217 assert_eq!(y.two, 20);
218 }
219 }
220
221 pub fn extern_return_twou16s() {
222 unsafe {
223 let y = rust_dbg_extern_return_TwoU16s();
224 assert_eq!(y.one, 10);
225 assert_eq!(y.two, 20);
226 }
227 }
228
229 pub fn extern_return_twou32s() {
230 unsafe {
231 let y = rust_dbg_extern_return_TwoU32s();
232 assert_eq!(y.one, 10);
233 assert_eq!(y.two, 20);
234 }
235 }
236
237 pub fn extern_return_twou64s() {
238 unsafe {
239 let y = rust_dbg_extern_return_TwoU64s();
240 assert_eq!(y.one, 10);
241 assert_eq!(y.two, 20);
242 }
243 }
244
245 #[inline(never)]
246 fn indirect_call(func: unsafe extern "sysv64" fn(s: S) -> u64, s: S) -> u64 {
247 unsafe {
248 func(s)
249 }
250 }
251
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));
257 }
258
259 fn test() {
260 use std::ptr;
261 unsafe {
262 let null = ptr::null();
263 let q = Quad {
264 a: 1,
265 b: 2,
266 c: 3,
267 d: 4
268 };
269 assert_eq!(get_c_many_params(null, null, null, null, q), q.c);
270 }
271 }
272
273 pub fn issue_28676() {
274 test();
275 }
276
277 fn test1() {
278 unsafe {
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);
292 }
293 }
294
295 fn test2() {
296 unsafe {
297 let f = Floats { a: 1.234567890e-15_f64,
298 b: 0b_1010_1010,
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);
307 }
308 }
309
310 pub fn struct_return() {
311 test1();
312 test2();
313 }
314 }
315
316 #[cfg(target_arch = "x86_64")]
317 fn main() {
318 use tests::*;
319 cabi_int_widening();
320 extern_pass_char();
321 extern_pass_u32();
322 extern_pass_u64();
323 extern_pass_double();
324 extern_pass_empty();
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();
334 issue_28676();
335 struct_return();
336 }
337
338 #[cfg(not(target_arch = "x86_64"))]
339 fn main() {
340
341 }