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