]> git.proxmox.com Git - rustc.git/blame - src/librustc_target/abi/call/sparc64.rs
New upstream version 1.47.0+dfsg1
[rustc.git] / src / librustc_target / abi / call / sparc64.rs
CommitLineData
32a655c1
SL
1// FIXME: This needs an audit for correctness and completeness.
2
dfeec247 3use crate::abi::call::{ArgAbi, FnAbi, Reg, RegKind, Uniform};
ba9703b0 4use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods};
32a655c1 5
dfeec247
XL
6fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) -> Option<Uniform>
7where
ba9703b0
XL
8 Ty: TyAndLayoutMethods<'a, C> + Copy,
9 C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
83c7162d 10{
74b04a01 11 arg.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()).and_then(|unit| {
cc61c64b 12 // Ensure we have at most eight uniquely addressable members.
2c00a5a8 13 if arg.layout.size > unit.size.checked_mul(8, cx).unwrap() {
cc61c64b 14 return None;
32a655c1
SL
15 }
16
cc61c64b
XL
17 let valid_unit = match unit.kind {
18 RegKind::Integer => false,
19 RegKind::Float => true,
dfeec247 20 RegKind::Vector => arg.layout.size.bits() == 128,
cc61c64b 21 };
32a655c1 22
60c5eb7d 23 valid_unit.then_some(Uniform { unit, total: arg.layout.size })
32a655c1
SL
24 })
25}
26
60c5eb7d 27fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>)
dfeec247 28where
ba9703b0
XL
29 Ty: TyAndLayoutMethods<'a, C> + Copy,
30 C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
83c7162d 31{
cc61c64b 32 if !ret.layout.is_aggregate() {
32a655c1
SL
33 ret.extend_integer_width_to(64);
34 return;
35 }
36
2c00a5a8 37 if let Some(uniform) = is_homogeneous_aggregate(cx, ret) {
ff7c6d11 38 ret.cast_to(uniform);
32a655c1
SL
39 return;
40 }
ff7c6d11 41 let size = ret.layout.size;
cc61c64b 42 let bits = size.bits();
2c00a5a8 43 if bits <= 256 {
8faf50e0 44 let unit = Reg::i64();
dfeec247 45 ret.cast_to(Uniform { unit, total: size });
32a655c1
SL
46 return;
47 }
cc61c64b
XL
48
49 // don't return aggregates in registers
ff7c6d11 50 ret.make_indirect();
32a655c1
SL
51}
52
60c5eb7d 53fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>)
dfeec247 54where
ba9703b0
XL
55 Ty: TyAndLayoutMethods<'a, C> + Copy,
56 C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
83c7162d 57{
cc61c64b 58 if !arg.layout.is_aggregate() {
32a655c1
SL
59 arg.extend_integer_width_to(64);
60 return;
61 }
62
2c00a5a8 63 if let Some(uniform) = is_homogeneous_aggregate(cx, arg) {
ff7c6d11 64 arg.cast_to(uniform);
32a655c1
SL
65 return;
66 }
67
ff7c6d11 68 let total = arg.layout.size;
2c00a5a8
XL
69 if total.bits() > 128 {
70 arg.make_indirect();
71 return;
72 }
73
dfeec247 74 arg.cast_to(Uniform { unit: Reg::i64(), total });
32a655c1
SL
75}
76
60c5eb7d 77pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
dfeec247 78where
ba9703b0
XL
79 Ty: TyAndLayoutMethods<'a, C> + Copy,
80 C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout,
83c7162d 81{
60c5eb7d
XL
82 if !fn_abi.ret.is_ignore() {
83 classify_ret(cx, &mut fn_abi.ret);
32a655c1
SL
84 }
85
60c5eb7d 86 for arg in &mut fn_abi.args {
dfeec247
XL
87 if arg.is_ignore() {
88 continue;
89 }
60c5eb7d 90 classify_arg(cx, arg);
32a655c1
SL
91 }
92}