1 use crate::abi
::call
::{Conv, FnAbi, ArgAbi, Reg, RegKind, Uniform}
;
2 use crate::abi
::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}
;
3 use crate::spec
::HasTargetSpec
;
5 fn is_homogeneous_aggregate
<'a
, Ty
, C
>(cx
: &C
, arg
: &mut ArgAbi
<'a
, Ty
>)
7 where Ty
: TyLayoutMethods
<'a
, C
> + Copy
,
8 C
: LayoutOf
<Ty
= Ty
, TyLayout
= TyLayout
<'a
, Ty
>> + HasDataLayout
10 arg
.layout
.homogeneous_aggregate(cx
).unit().and_then(|unit
| {
11 let size
= arg
.layout
.size
;
13 // Ensure we have at most four uniquely addressable members.
14 if size
> unit
.size
.checked_mul(4, cx
).unwrap() {
18 let valid_unit
= match unit
.kind
{
19 RegKind
::Integer
=> false,
20 RegKind
::Float
=> true,
21 RegKind
::Vector
=> size
.bits() == 64 || size
.bits() == 128
24 valid_unit
.then_some(Uniform { unit, total: size }
)
28 fn classify_ret
<'a
, Ty
, C
>(cx
: &C
, ret
: &mut ArgAbi
<'a
, Ty
>, vfp
: bool
)
29 where Ty
: TyLayoutMethods
<'a
, C
> + Copy
,
30 C
: LayoutOf
<Ty
= Ty
, TyLayout
= TyLayout
<'a
, Ty
>> + HasDataLayout
32 if !ret
.layout
.is_aggregate() {
33 ret
.extend_integer_width_to(32);
38 if let Some(uniform
) = is_homogeneous_aggregate(cx
, ret
) {
44 let size
= ret
.layout
.size
;
45 let bits
= size
.bits();
47 let unit
= if bits
<= 8 {
49 } else if bits
<= 16 {
63 fn classify_arg
<'a
, Ty
, C
>(cx
: &C
, arg
: &mut ArgAbi
<'a
, Ty
>, vfp
: bool
)
64 where Ty
: TyLayoutMethods
<'a
, C
> + Copy
,
65 C
: LayoutOf
<Ty
= Ty
, TyLayout
= TyLayout
<'a
, Ty
>> + HasDataLayout
67 if !arg
.layout
.is_aggregate() {
68 arg
.extend_integer_width_to(32);
73 if let Some(uniform
) = is_homogeneous_aggregate(cx
, arg
) {
79 let align
= arg
.layout
.align
.abi
.bytes();
80 let total
= arg
.layout
.size
;
82 unit
: if align
<= 4 { Reg::i32() }
else { Reg::i64() }
,
87 pub fn compute_abi_info
<'a
, Ty
, C
>(cx
: &C
, fn_abi
: &mut FnAbi
<'a
, Ty
>)
88 where Ty
: TyLayoutMethods
<'a
, C
> + Copy
,
89 C
: LayoutOf
<Ty
= Ty
, TyLayout
= TyLayout
<'a
, Ty
>> + HasDataLayout
+ HasTargetSpec
91 // If this is a target with a hard-float ABI, and the function is not explicitly
92 // `extern "aapcs"`, then we must use the VFP registers for homogeneous aggregates.
93 let vfp
= cx
.target_spec().llvm_target
.ends_with("hf")
94 && fn_abi
.conv
!= Conv
::ArmAapcs
95 && !fn_abi
.c_variadic
;
97 if !fn_abi
.ret
.is_ignore() {
98 classify_ret(cx
, &mut fn_abi
.ret
, vfp
);
101 for arg
in &mut fn_abi
.args
{
102 if arg
.is_ignore() { continue; }
103 classify_arg(cx
, arg
, vfp
);