11
11
// Checks if the correct registers are being used to pass arguments
12
12
// when the sysv64 ABI is specified.
13
13
14
+ // ignore-android
15
+ // ignore-arm
16
+ // ignore-aarch64
17
+
14
18
#![ feature( abi_sysv64) ]
15
- #![ feature( naked_functions) ]
16
19
#![ feature( asm) ]
17
20
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
95
42
}
96
43
97
44
// this struct contains 8 i64's, while only 6 can be passed in registers.
45
+ #[ cfg( target_arch = "x86_64" ) ]
98
46
#[ derive( PartialEq , Eq , Debug ) ]
99
47
pub struct LargeStruct ( i64 , i64 , i64 , i64 , i64 , i64 , i64 , i64 ) ;
100
48
49
+ #[ cfg( target_arch = "x86_64" ) ]
101
50
#[ inline( never) ]
102
51
pub extern "sysv64" fn large_struct_by_val ( mut foo : LargeStruct ) -> LargeStruct {
103
52
foo. 0 *= 1 ;
@@ -111,15 +60,47 @@ pub extern "sysv64" fn large_struct_by_val(mut foo: LargeStruct) -> LargeStruct
111
60
foo
112
61
}
113
62
63
+ #[ cfg( target_arch = "x86_64" ) ]
114
64
pub 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 ) ;
120
98
121
99
assert_eq ! (
122
100
large_struct_by_val( LargeStruct ( 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ) ) ,
123
101
LargeStruct ( 1 , 4 , 9 , 16 , 25 , 36 , 49 , 64 )
124
102
) ;
125
103
}
104
+
105
+ #[ cfg( not( target_arch = "x86_64" ) ) ]
106
+ pub fn main ( ) { }
0 commit comments