1 use crate::abi
::call
::{ArgAbi, FnAbi, Reg, RegKind, Uniform}
;
2 use crate::abi
::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods}
;
4 fn is_homogeneous_aggregate
<'a
, Ty
, C
>(cx
: &C
, arg
: &mut ArgAbi
<'a
, Ty
>) -> Option
<Uniform
>
6 Ty
: TyAndLayoutMethods
<'a
, C
> + Copy
,
7 C
: LayoutOf
<Ty
= Ty
, TyAndLayout
= TyAndLayout
<'a
, Ty
>> + HasDataLayout
,
9 arg
.layout
.homogeneous_aggregate(cx
).ok().and_then(|ha
| ha
.unit()).and_then(|unit
| {
10 let size
= arg
.layout
.size
;
12 // Ensure we have at most four uniquely addressable members.
13 if size
> unit
.size
.checked_mul(4, cx
).unwrap() {
17 let valid_unit
= match unit
.kind
{
18 RegKind
::Integer
=> false,
19 RegKind
::Float
=> true,
20 RegKind
::Vector
=> size
.bits() == 64 || size
.bits() == 128,
23 valid_unit
.then_some(Uniform { unit, total: size }
)
27 fn classify_ret
<'a
, Ty
, C
>(cx
: &C
, ret
: &mut ArgAbi
<'a
, Ty
>)
29 Ty
: TyAndLayoutMethods
<'a
, C
> + Copy
,
30 C
: LayoutOf
<Ty
= Ty
, TyAndLayout
= TyAndLayout
<'a
, Ty
>> + HasDataLayout
,
32 if !ret
.layout
.is_aggregate() {
33 ret
.extend_integer_width_to(32);
36 if let Some(uniform
) = is_homogeneous_aggregate(cx
, ret
) {
40 let size
= ret
.layout
.size
;
41 let bits
= size
.bits();
43 ret
.cast_to(Uniform { unit: Reg::i64(), total: size }
);
49 fn classify_arg
<'a
, Ty
, C
>(cx
: &C
, arg
: &mut ArgAbi
<'a
, Ty
>)
51 Ty
: TyAndLayoutMethods
<'a
, C
> + Copy
,
52 C
: LayoutOf
<Ty
= Ty
, TyAndLayout
= TyAndLayout
<'a
, Ty
>> + HasDataLayout
,
54 if !arg
.layout
.is_aggregate() {
55 arg
.extend_integer_width_to(32);
58 if let Some(uniform
) = is_homogeneous_aggregate(cx
, arg
) {
62 let size
= arg
.layout
.size
;
63 let bits
= size
.bits();
65 arg
.cast_to(Uniform { unit: Reg::i64(), total: size }
);
71 pub fn compute_abi_info
<'a
, Ty
, C
>(cx
: &C
, fn_abi
: &mut FnAbi
<'a
, Ty
>)
73 Ty
: TyAndLayoutMethods
<'a
, C
> + Copy
,
74 C
: LayoutOf
<Ty
= Ty
, TyAndLayout
= TyAndLayout
<'a
, Ty
>> + HasDataLayout
,
76 if !fn_abi
.ret
.is_ignore() {
77 classify_ret(cx
, &mut fn_abi
.ret
);
80 for arg
in &mut fn_abi
.args
{
84 classify_arg(cx
, arg
);