]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_target/src/abi/call/aarch64.rs
New upstream version 1.60.0+dfsg1
[rustc.git] / compiler / rustc_target / src / abi / call / aarch64.rs
CommitLineData
dfeec247 1use crate::abi::call::{ArgAbi, FnAbi, Reg, RegKind, Uniform};
94222f64 2use crate::abi::{HasDataLayout, TyAbiInterface};
9346a6ac 3
dfeec247
XL
4fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) -> Option<Uniform>
5where
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 27fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>)
dfeec247 28where
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 49fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>)
dfeec247 50where
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 71pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
dfeec247 72where
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}