rustc_target/callconv/
mips.rs1use rustc_abi::{Float, HasDataLayout, Integer, Numeric, Reg, RegKind, Size, TyAbiInterface};
2use rustc_span::bug;
3
4use crate::callconv::{ArgAbi, CastTarget, FnAbi, Uniform};
5
6fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>, offset: &mut Size)
7where
8 Ty: TyAbiInterface<'a, C> + Copy,
9 C: HasDataLayout,
10{
11 let dl = cx.data_layout();
12 let size = ret.layout.size;
13
14 let is_supported_complex_component = |numeric| match numeric {
16 Numeric::Int(Integer::I8 | Integer::I16 | Integer::I32 | Integer::I64, _) => true,
17 Numeric::Int(Integer::I128, _) => false,
18 Numeric::Float(Float::F32 | Float::F64) => true,
19 Numeric::Float(Float::F16 | Float::F128) => false,
20 Numeric::Float(Float::F16B | Float::PpcF128) => ::rustc_span::macros::bug_impl(None, format_args!("unsupported on mips"),
Location::caller())bug!("unsupported on mips"),
21 };
22
23 if let Some(component) = ret.layout.complex_number(cx)
24 && is_supported_complex_component(component)
25 {
26 match component {
27 Numeric::Int(Integer::I8 | Integer::I16, _) => {
28 ret.cast_to(Reg { kind: RegKind::Integer, size });
30 }
31 _ => {
32 let reg = Reg { kind: component.reg_kind(), size: component.size() };
33 ret.cast_to(CastTarget::from(Uniform::new(reg, size)));
34 }
35 }
36 } else if ret.layout.is_aggregate() {
37 ret.make_indirect();
38 *offset += dl.pointer_size();
39 } else {
40 ret.extend_integer_width_to(32);
41 }
42}
43
44fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>, offset: &mut Size)
45where
46 Ty: TyAbiInterface<'a, C> + Copy,
47 C: HasDataLayout,
48{
49 if !arg.layout.is_sized() {
50 return;
53 }
54 let dl = cx.data_layout();
55 let align = arg.layout.align.abi.max(dl.i32_align).min(dl.i64_align);
56
57 if arg.layout.pass_indirectly_in_non_rustic_abis(cx) {
58 arg.make_indirect();
59 *offset = offset.align_to(align) + dl.pointer_size().align_to(align);
60 return;
61 }
62
63 let size = arg.layout.size;
64 if arg.layout.is_aggregate() {
65 let pad_i32 = u8::from(!offset.is_aligned(align));
66 arg.cast_to_and_pad_i32(Uniform::new(Reg::i32(), size), pad_i32);
67 } else {
68 arg.extend_integer_width_to(32);
69 }
70
71 *offset = offset.align_to(align) + size.align_to(align);
72}
73
74pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
75where
76 Ty: TyAbiInterface<'a, C> + Copy,
77 C: HasDataLayout,
78{
79 let mut offset = Size::ZERO;
80 if !fn_abi.ret.is_ignore() {
81 classify_ret(cx, &mut fn_abi.ret, &mut offset);
82 }
83
84 for arg in fn_abi.args.iter_mut() {
85 if arg.is_ignore() {
86 continue;
87 }
88 classify_arg(cx, arg, &mut offset);
89 }
90}