Skip to main content

rustc_target/callconv/
sparc.rs

1use rustc_abi::{
2    BackendRepr, Float, HasDataLayout, Integer, Numeric, Primitive, RegKind, TyAbiInterface,
3};
4
5use crate::callconv::{ArgAbi, ArgAttribute, CastTarget, FnAbi, Reg};
6
7fn classify_shared<'a, Ty>(val: &mut ArgAbi<'a, Ty>) {
8    if val.layout.is_aggregate() {
9        val.make_indirect();
10    } else if let BackendRepr::Scalar(scalar) = val.layout.backend_repr
11        && scalar.primitive() == Primitive::Float(Float::F128)
12    {
13        // f128 is passed and returned indirectly.
14        val.make_indirect();
15    } else {
16        val.extend_integer_width_to(32);
17    }
18}
19
20fn classify_complex_ret<'a, Ty>(ret: &mut ArgAbi<'a, Ty>, component: Numeric) {
21    let reg = Reg { kind: component.reg_kind(), size: component.size() };
22    let mut cast = CastTarget::pair(reg, reg);
23
24    match component {
25        Numeric::Float(Float::F128) => {
26            // Mark `_Complex long double` as inreg to get the right behavior,
27            // consistent with clang `SparcV8ABIInfo::classifyReturnType`.
28            cast.attrs.set(ArgAttribute::InReg);
29        }
30        Numeric::Int(Integer::I8 | Integer::I16 | Integer::I32, _) => {
31            let size = ret.layout.size;
32            cast = CastTarget::from(Reg { kind: RegKind::Integer, size });
33        }
34        _ => { /* default behavior */ }
35    }
36
37    ret.cast_to(cast);
38}
39
40fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>)
41where
42    Ty: TyAbiInterface<'a, C> + Copy,
43    C: HasDataLayout,
44{
45    if !arg.layout.is_sized() {
46        // Not touching this...
47        return;
48    }
49    if arg.layout.pass_indirectly_in_non_rustic_abis(cx) {
50        arg.make_indirect();
51        return;
52    }
53
54    if let Some(component) = arg.layout.complex_number(cx) {
55        if let Numeric::Int(Integer::I8 | Integer::I16 | Integer::I32, _) = component {
56            arg.cast_to(Reg { kind: RegKind::Integer, size: 2 * component.size() });
57        } else {
58            arg.make_indirect();
59        }
60        return;
61    }
62
63    classify_shared(arg)
64}
65
66pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
67where
68    Ty: TyAbiInterface<'a, C> + Copy,
69    C: HasDataLayout,
70{
71    if !fn_abi.ret.is_ignore() {
72        if let Some(component) = fn_abi.ret.layout.complex_number(cx) {
73            classify_complex_ret(&mut fn_abi.ret, component);
74        } else {
75            classify_shared(&mut fn_abi.ret);
76        };
77    }
78
79    for arg in fn_abi.args.iter_mut() {
80        if arg.is_ignore() {
81            if arg.layout.is_zst() {
82                arg.make_indirect_from_ignore();
83            }
84            continue;
85        }
86        classify_arg(cx, arg);
87    }
88}