1 use crate::abi::call::{ArgAbi, FnAbi, Reg, RegKind, Uniform};
2 use crate::abi::{HasDataLayout, LayoutOf, TyAbiInterface, TyAndLayout};
4 fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) -> Option<Uniform>
6 Ty: TyAbiInterface<'a, C> + Copy,
7 C: LayoutOf<'a, 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: TyAbiInterface<'a, C> + Copy,
30 C: LayoutOf<'a, 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: TyAbiInterface<'a, C> + Copy,
52 C: LayoutOf<'a, 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: TyAbiInterface<'a, C> + Copy,
74 C: LayoutOf<'a, 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);