1
+ use std:: iter;
2
+
3
+ use rustc_abi:: { BackendRepr , Primitive } ;
4
+
1
5
use crate :: abi:: call:: { ArgAbi , FnAbi , Reg , RegKind , Uniform } ;
2
6
use crate :: abi:: { HasDataLayout , TyAbiInterface } ;
7
+ use crate :: spec:: { HasTargetSpec , Target } ;
3
8
4
9
/// Indicates the variant of the AArch64 ABI we are compiling for.
5
10
/// Used to accommodate Apple and Microsoft's deviations from the usual AAPCS ABI.
@@ -35,10 +40,25 @@ where
35
40
} )
36
41
}
37
42
43
+ fn softfloat_float_abi < Ty > ( target : & Target , arg : & mut ArgAbi < ' _ , Ty > ) {
44
+ if let BackendRepr :: Scalar ( s) = arg. layout . backend_repr
45
+ && let Primitive :: Float ( f) = s. primitive ( )
46
+ {
47
+ if target. abi == "softfloat" {
48
+ // Do *not* use the floag registers for passing arguments, as that would make
49
+ // the ABI depend on whether `neon` instructions are enabled.
50
+ // Apparently there is no standard ABI here [1], so we can do whatever we want.
51
+ // We choose to pass floats via equal-sized integer registers.
52
+ // [1]: https://github.com/rust-lang/rust/issues/131058#issuecomment-2384960972
53
+ arg. cast_to ( Reg { kind : RegKind :: Integer , size : f. size ( ) } ) ;
54
+ }
55
+ }
56
+ }
57
+
38
58
fn classify_ret < ' a , Ty , C > ( cx : & C , ret : & mut ArgAbi < ' a , Ty > , kind : AbiKind )
39
59
where
40
60
Ty : TyAbiInterface < ' a , C > + Copy ,
41
- C : HasDataLayout ,
61
+ C : HasDataLayout + HasTargetSpec ,
42
62
{
43
63
if !ret. layout . is_sized ( ) {
44
64
// Not touching this...
51
71
// See also: <https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms#Pass-Arguments-to-Functions-Correctly>
52
72
ret. extend_integer_width_to ( 32 )
53
73
}
74
+ softfloat_float_abi ( cx. target_spec ( ) , ret) ;
54
75
return ;
55
76
}
56
77
if let Some ( uniform) = is_homogeneous_aggregate ( cx, ret) {
69
90
fn classify_arg < ' a , Ty , C > ( cx : & C , arg : & mut ArgAbi < ' a , Ty > , kind : AbiKind )
70
91
where
71
92
Ty : TyAbiInterface < ' a , C > + Copy ,
72
- C : HasDataLayout ,
93
+ C : HasDataLayout + HasTargetSpec ,
73
94
{
74
95
if !arg. layout . is_sized ( ) {
75
96
// Not touching this...
82
103
// See also: <https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms#Pass-Arguments-to-Functions-Correctly>
83
104
arg. extend_integer_width_to ( 32 ) ;
84
105
}
106
+ softfloat_float_abi ( cx. target_spec ( ) , arg) ;
107
+
85
108
return ;
86
109
}
87
110
if let Some ( uniform) = is_homogeneous_aggregate ( cx, arg) {
@@ -112,7 +135,7 @@ where
112
135
pub ( crate ) fn compute_abi_info < ' a , Ty , C > ( cx : & C , fn_abi : & mut FnAbi < ' a , Ty > , kind : AbiKind )
113
136
where
114
137
Ty : TyAbiInterface < ' a , C > + Copy ,
115
- C : HasDataLayout ,
138
+ C : HasDataLayout + HasTargetSpec ,
116
139
{
117
140
if !fn_abi. ret . is_ignore ( ) {
118
141
classify_ret ( cx, & mut fn_abi. ret , kind) ;
@@ -125,3 +148,13 @@ where
125
148
classify_arg ( cx, arg, kind) ;
126
149
}
127
150
}
151
+
152
+ pub ( crate ) fn compute_rust_abi_info < ' a , Ty , C > ( cx : & C , fn_abi : & mut FnAbi < ' a , Ty > )
153
+ where
154
+ Ty : TyAbiInterface < ' a , C > + Copy ,
155
+ C : HasDataLayout + HasTargetSpec ,
156
+ {
157
+ for arg in fn_abi. args . iter_mut ( ) . chain ( iter:: once ( & mut fn_abi. ret ) ) {
158
+ softfloat_float_abi ( cx. target_spec ( ) , arg) ;
159
+ }
160
+ }
0 commit comments