1+ use std:: iter;
2+
3+ use rustc_abi:: { BackendRepr , Primitive } ;
4+
15use crate :: abi:: call:: { ArgAbi , FnAbi , Reg , RegKind , Uniform } ;
26use crate :: abi:: { HasDataLayout , TyAbiInterface } ;
7+ use crate :: spec:: { HasTargetSpec , Target } ;
38
49/// Indicates the variant of the AArch64 ABI we are compiling for.
510/// Used to accommodate Apple and Microsoft's deviations from the usual AAPCS ABI.
@@ -35,10 +40,25 @@ where
3540 } )
3641}
3742
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+
3858fn classify_ret < ' a , Ty , C > ( cx : & C , ret : & mut ArgAbi < ' a , Ty > , kind : AbiKind )
3959where
4060 Ty : TyAbiInterface < ' a , C > + Copy ,
41- C : HasDataLayout ,
61+ C : HasDataLayout + HasTargetSpec ,
4262{
4363 if !ret. layout . is_sized ( ) {
4464 // Not touching this...
5171 // See also: <https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms#Pass-Arguments-to-Functions-Correctly>
5272 ret. extend_integer_width_to ( 32 )
5373 }
74+ softfloat_float_abi ( cx. target_spec ( ) , ret) ;
5475 return ;
5576 }
5677 if let Some ( uniform) = is_homogeneous_aggregate ( cx, ret) {
6990fn classify_arg < ' a , Ty , C > ( cx : & C , arg : & mut ArgAbi < ' a , Ty > , kind : AbiKind )
7091where
7192 Ty : TyAbiInterface < ' a , C > + Copy ,
72- C : HasDataLayout ,
93+ C : HasDataLayout + HasTargetSpec ,
7394{
7495 if !arg. layout . is_sized ( ) {
7596 // Not touching this...
82103 // See also: <https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms#Pass-Arguments-to-Functions-Correctly>
83104 arg. extend_integer_width_to ( 32 ) ;
84105 }
106+ softfloat_float_abi ( cx. target_spec ( ) , arg) ;
107+
85108 return ;
86109 }
87110 if let Some ( uniform) = is_homogeneous_aggregate ( cx, arg) {
@@ -112,7 +135,7 @@ where
112135pub ( crate ) fn compute_abi_info < ' a , Ty , C > ( cx : & C , fn_abi : & mut FnAbi < ' a , Ty > , kind : AbiKind )
113136where
114137 Ty : TyAbiInterface < ' a , C > + Copy ,
115- C : HasDataLayout ,
138+ C : HasDataLayout + HasTargetSpec ,
116139{
117140 if !fn_abi. ret . is_ignore ( ) {
118141 classify_ret ( cx, & mut fn_abi. ret , kind) ;
@@ -125,3 +148,13 @@ where
125148 classify_arg ( cx, arg, kind) ;
126149 }
127150}
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