1111// Checks if the correct registers are being used to pass arguments
1212// when the sysv64 ABI is specified.
1313
14+ // ignore-android
15+ // ignore-arm
16+ // ignore-aarch64
17+
1418#![ feature( abi_sysv64) ]
15- #![ feature( naked_functions) ]
1619#![ feature( asm) ]
1720
18- #[ naked]
19- #[ inline( never) ]
20- #[ allow( unused_variables) ]
21- pub unsafe extern "sysv64" fn all_the_registers ( rdi : i64 , rsi : i64 , rdx : i64 ,
22- rcx : i64 , r8 : i64 , r9 : i64 ,
23- xmm0 : f32 , xmm1 : f32 , xmm2 : f32 ,
24- xmm3 : f32 , xmm4 : f32 , xmm5 : f32 ,
25- xmm6 : f32 , xmm7 : f32 ) -> i64 {
26- // this assembly checks all registers for specific values, and puts in rax
27- // how many values were correct.
28- asm ! ( "cmp rdi, 0x1;
29- xor rax, rax;
30- setz al;
31-
32- cmp rsi, 0x2;
33- xor rdi, rdi
34- setz dil;
35- add rax, rdi;
36-
37- cmp rdx, 0x3;
38- setz dil;
39- add rax, rdi;
40-
41- cmp rcx, 0x4;
42- setz dil;
43- add rax, rdi;
44-
45- cmp r8, 0x5;
46- setz dil;
47- add rax, rdi;
48-
49- cmp r9, 0x6;
50- setz dil;
51- add rax, rdi;
52-
53- movd esi, xmm0;
54- cmp rsi, 0x3F800000;
55- setz dil;
56- add rax, rdi;
57-
58- movd esi, xmm1;
59- cmp rsi, 0x40000000;
60- setz dil;
61- add rax, rdi;
62-
63- movd esi, xmm2;
64- cmp rsi, 0x40800000;
65- setz dil;
66- add rax, rdi;
67-
68- movd esi, xmm3;
69- cmp rsi, 0x41000000;
70- setz dil;
71- add rax, rdi;
72-
73- movd esi, xmm4;
74- cmp rsi, 0x41800000;
75- setz dil;
76- add rax, rdi;
77-
78- movd esi, xmm5;
79- cmp rsi, 0x42000000;
80- setz dil;
81- add rax, rdi;
82-
83- movd esi, xmm6;
84- cmp rsi, 0x42800000;
85- setz dil;
86- add rax, rdi;
87-
88- movd esi, xmm7;
89- cmp rsi, 0x43000000;
90- setz dil;
91- add rax, rdi;
92- ret
93- " :: :: "intel" ) ;
94- unreachable ! ( ) ;
21+ #[ cfg( target_arch = "x86_64" ) ]
22+ pub extern "sysv64" fn all_the_registers ( rdi : i64 , rsi : i64 , rdx : i64 ,
23+ rcx : i64 , r8 : i64 , r9 : i64 ,
24+ xmm0 : f32 , xmm1 : f32 , xmm2 : f32 ,
25+ xmm3 : f32 , xmm4 : f32 , xmm5 : f32 ,
26+ xmm6 : f32 , xmm7 : f32 ) -> i64 {
27+ assert_eq ! ( rdi, 1 ) ;
28+ assert_eq ! ( rsi, 2 ) ;
29+ assert_eq ! ( rdx, 3 ) ;
30+ assert_eq ! ( rcx, 4 ) ;
31+ assert_eq ! ( r8, 5 ) ;
32+ assert_eq ! ( r9, 6 ) ;
33+ assert_eq ! ( xmm0, 1.0f32 ) ;
34+ assert_eq ! ( xmm1, 2.0f32 ) ;
35+ assert_eq ! ( xmm2, 4.0f32 ) ;
36+ assert_eq ! ( xmm3, 8.0f32 ) ;
37+ assert_eq ! ( xmm4, 16.0f32 ) ;
38+ assert_eq ! ( xmm5, 32.0f32 ) ;
39+ assert_eq ! ( xmm6, 64.0f32 ) ;
40+ assert_eq ! ( xmm7, 128.0f32 ) ;
41+ 42
9542}
9643
9744// this struct contains 8 i64's, while only 6 can be passed in registers.
45+ #[ cfg( target_arch = "x86_64" ) ]
9846#[ derive( PartialEq , Eq , Debug ) ]
9947pub struct LargeStruct ( i64 , i64 , i64 , i64 , i64 , i64 , i64 , i64 ) ;
10048
49+ #[ cfg( target_arch = "x86_64" ) ]
10150#[ inline( never) ]
10251pub extern "sysv64" fn large_struct_by_val ( mut foo : LargeStruct ) -> LargeStruct {
10352 foo. 0 *= 1 ;
@@ -111,15 +60,47 @@ pub extern "sysv64" fn large_struct_by_val(mut foo: LargeStruct) -> LargeStruct
11160 foo
11261}
11362
63+ #[ cfg( target_arch = "x86_64" ) ]
11464pub fn main ( ) {
115- assert_eq ! ( unsafe {
116- all_the_registers( 1 , 2 , 3 , 4 , 5 , 6 ,
117- 1.0 , 2.0 , 4.0 , 8.0 ,
118- 16.0 , 32.0 , 64.0 , 128.0 )
119- } , 14 ) ;
65+ let result: i64 ;
66+ unsafe {
67+ asm ! ( "mov rdi, 1;
68+ mov rsi, 2;
69+ mov rdx, 3;
70+ mov rcx, 4;
71+ mov r8, 5;
72+ mov r9, 6;
73+ mov eax, 0x3F800000;
74+ movd xmm0, eax;
75+ mov eax, 0x40000000;
76+ movd xmm1, eax;
77+ mov eax, 0x40800000;
78+ movd xmm2, eax;
79+ mov eax, 0x41000000;
80+ movd xmm3, eax;
81+ mov eax, 0x41800000;
82+ movd xmm4, eax;
83+ mov eax, 0x42000000;
84+ movd xmm5, eax;
85+ mov eax, 0x42800000;
86+ movd xmm6, eax;
87+ mov eax, 0x43000000;
88+ movd xmm7, eax;
89+ call r10
90+ "
91+ : "={rax}" ( result)
92+ : "{r10}" ( all_the_registers as usize )
93+ : "rdi" , "rsi" , "rdx" , "rcx" , "r8" , "r9" , "r11" , "cc" , "memory"
94+ : "intel" , "alignstack"
95+ )
96+ }
97+ assert_eq ! ( result, 42 ) ;
12098
12199 assert_eq ! (
122100 large_struct_by_val( LargeStruct ( 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ) ) ,
123101 LargeStruct ( 1 , 4 , 9 , 16 , 25 , 36 , 49 , 64 )
124102 ) ;
125103}
104+
105+ #[ cfg( not( target_arch = "x86_64" ) ) ]
106+ pub fn main ( ) { }
0 commit comments