Skip to main content

rustc_target/callconv/
hexagon.rs

1use rustc_abi::{HasDataLayout, TyAbiInterface};
2
3use crate::callconv::{ArgAbi, FnAbi, Reg, Uniform};
4
5fn classify_ret<'a, Ty, C>(_cx: &C, ret: &mut ArgAbi<'a, Ty>)
6where
7    Ty: TyAbiInterface<'a, C> + Copy,
8    C: HasDataLayout,
9{
10    if !ret.layout.is_sized() {
11        return;
12    }
13
14    if !ret.layout.is_aggregate() {
15        ret.extend_integer_width_to(32);
16        return;
17    }
18
19    // Per the Hexagon ABI:
20    // - Aggregates up to 32 bits are returned in R0
21    // - Aggregates 33-64 bits are returned in R1:R0
22    // - Aggregates > 64 bits are returned indirectly via hidden first argument
23    let size = ret.layout.size;
24    let bits = size.bits();
25    if bits <= 32 {
26        ret.cast_to(Uniform::new(Reg::i32(), size));
27    } else if bits <= 64 {
28        ret.cast_to(Uniform::new(Reg::i64(), size));
29    } else {
30        ret.make_indirect();
31    }
32}
33
34fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>)
35where
36    Ty: TyAbiInterface<'a, C> + Copy,
37    C: HasDataLayout,
38{
39    if !arg.layout.is_sized() {
40        return;
41    }
42    if arg.layout.pass_indirectly_in_non_rustic_abis(cx) {
43        arg.make_indirect();
44        return;
45    }
46
47    if !arg.layout.is_aggregate() {
48        arg.extend_integer_width_to(32);
49        return;
50    }
51
52    // Per the Hexagon ABI:
53    // - Aggregates up to 32 bits are passed in a single register
54    // - Aggregates 33-64 bits are passed in a register pair
55    // - Aggregates > 64 bits are passed on the stack
56    let size = arg.layout.size;
57    let bits = size.bits();
58    if bits <= 32 {
59        arg.cast_to(Uniform::new(Reg::i32(), size));
60    } else if bits <= 64 {
61        arg.cast_to(Uniform::new(Reg::i64(), size));
62    } else {
63        arg.pass_by_stack_offset(None);
64    }
65}
66
67pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
68where
69    Ty: TyAbiInterface<'a, C> + Copy,
70    C: HasDataLayout,
71{
72    if !fn_abi.ret.is_ignore() {
73        classify_ret(cx, &mut fn_abi.ret);
74    }
75
76    for arg in fn_abi.args.iter_mut() {
77        if arg.is_ignore() {
78            continue;
79        }
80        classify_arg(cx, arg);
81    }
82}