]>
Commit | Line | Data |
---|---|---|
dfeec247 | 1 | use crate::abi::call::{ArgAbi, FnAbi, Reg, RegKind, Uniform}; |
94222f64 | 2 | use crate::abi::{HasDataLayout, TyAbiInterface}; |
9346a6ac | 3 | |
dfeec247 XL |
4 | fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) -> Option<Uniform> |
5 | where | |
94222f64 XL |
6 | Ty: TyAbiInterface<'a, C> + Copy, |
7 | C: HasDataLayout, | |
83c7162d | 8 | { |
74b04a01 | 9 | arg.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()).and_then(|unit| { |
ff7c6d11 | 10 | let size = arg.layout.size; |
9346a6ac | 11 | |
cc61c64b | 12 | // Ensure we have at most four uniquely addressable members. |
2c00a5a8 | 13 | if size > unit.size.checked_mul(4, cx).unwrap() { |
cc61c64b | 14 | return None; |
9346a6ac | 15 | } |
9346a6ac | 16 | |
cc61c64b XL |
17 | let valid_unit = match unit.kind { |
18 | RegKind::Integer => false, | |
19 | RegKind::Float => true, | |
dfeec247 | 20 | RegKind::Vector => size.bits() == 64 || size.bits() == 128, |
cc61c64b | 21 | }; |
9346a6ac | 22 | |
60c5eb7d | 23 | valid_unit.then_some(Uniform { unit, total: size }) |
9346a6ac AL |
24 | }) |
25 | } | |
26 | ||
60c5eb7d | 27 | fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>) |
dfeec247 | 28 | where |
94222f64 XL |
29 | Ty: TyAbiInterface<'a, C> + Copy, |
30 | C: HasDataLayout, | |
83c7162d | 31 | { |
cc61c64b | 32 | if !ret.layout.is_aggregate() { |
54a0048b SL |
33 | ret.extend_integer_width_to(32); |
34 | return; | |
223e47cc | 35 | } |
2c00a5a8 | 36 | if let Some(uniform) = is_homogeneous_aggregate(cx, ret) { |
ff7c6d11 | 37 | ret.cast_to(uniform); |
54a0048b | 38 | return; |
9346a6ac | 39 | } |
ff7c6d11 | 40 | let size = ret.layout.size; |
cc61c64b XL |
41 | let bits = size.bits(); |
42 | if bits <= 128 { | |
5869c6ff | 43 | ret.cast_to(Uniform { unit: Reg::i64(), total: size }); |
54a0048b | 44 | return; |
223e47cc | 45 | } |
ff7c6d11 | 46 | ret.make_indirect(); |
223e47cc LB |
47 | } |
48 | ||
60c5eb7d | 49 | fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) |
dfeec247 | 50 | where |
94222f64 XL |
51 | Ty: TyAbiInterface<'a, C> + Copy, |
52 | C: HasDataLayout, | |
83c7162d | 53 | { |
cc61c64b | 54 | if !arg.layout.is_aggregate() { |
54a0048b SL |
55 | arg.extend_integer_width_to(32); |
56 | return; | |
223e47cc | 57 | } |
2c00a5a8 | 58 | if let Some(uniform) = is_homogeneous_aggregate(cx, arg) { |
ff7c6d11 | 59 | arg.cast_to(uniform); |
54a0048b | 60 | return; |
9346a6ac | 61 | } |
ff7c6d11 | 62 | let size = arg.layout.size; |
cc61c64b XL |
63 | let bits = size.bits(); |
64 | if bits <= 128 { | |
5869c6ff | 65 | arg.cast_to(Uniform { unit: Reg::i64(), total: size }); |
54a0048b | 66 | return; |
1a4d82fc | 67 | } |
ff7c6d11 | 68 | arg.make_indirect(); |
223e47cc LB |
69 | } |
70 | ||
60c5eb7d | 71 | pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) |
dfeec247 | 72 | where |
94222f64 XL |
73 | Ty: TyAbiInterface<'a, C> + Copy, |
74 | C: HasDataLayout, | |
83c7162d | 75 | { |
60c5eb7d XL |
76 | if !fn_abi.ret.is_ignore() { |
77 | classify_ret(cx, &mut fn_abi.ret); | |
223e47cc | 78 | } |
223e47cc | 79 | |
60c5eb7d | 80 | for arg in &mut fn_abi.args { |
dfeec247 XL |
81 | if arg.is_ignore() { |
82 | continue; | |
83 | } | |
60c5eb7d | 84 | classify_arg(cx, arg); |
54a0048b | 85 | } |
223e47cc | 86 | } |