Skip to main content

rustc_target/callconv/
bpf.rs

1// see https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/BPF/BPFCallingConv.td
2use rustc_abi::{Reg, RegKind, Size, TyAbiInterface};
3
4use crate::callconv::{ArgAbi, CastTarget, FnAbi, Uniform};
5
6fn classify_aggregate_type<Ty>(arg: &mut ArgAbi<'_, Ty>) {
7    let size = arg.layout.size;
8
9    match size.bits() {
10        0 => return,
11        1..=64 => {
12            arg.cast_to(Reg { kind: RegKind::Integer, size });
13        }
14        65..=128 => {
15            arg.cast_to(CastTarget::from(Uniform::new(Reg::i64(), Size::from_bytes(16))));
16        }
17        _ => {
18            arg.make_indirect();
19        }
20    }
21}
22
23fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
24    if !ret.layout.is_sized() {
25        // Not touching this...
26        return;
27    }
28
29    if ret.layout.is_aggregate() || ret.layout.size.bits() > 64 {
30        classify_aggregate_type(ret);
31    } else {
32        ret.extend_integer_width_to(32);
33    }
34}
35
36fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>)
37where
38    Ty: TyAbiInterface<'a, C> + Copy,
39{
40    if !arg.layout.is_sized() {
41        // Not touching this...
42        return;
43    }
44    if arg.layout.pass_indirectly_in_non_rustic_abis(cx) {
45        arg.make_indirect();
46        return;
47    }
48    if arg.layout.is_aggregate() || arg.layout.size.bits() > 64 {
49        classify_aggregate_type(arg);
50    } else {
51        arg.extend_integer_width_to(32);
52    }
53}
54
55pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
56where
57    Ty: TyAbiInterface<'a, C> + Copy,
58{
59    if !fn_abi.ret.is_ignore() {
60        classify_ret(&mut fn_abi.ret);
61    }
62
63    for arg in fn_abi.args.iter_mut() {
64        if arg.is_ignore() {
65            continue;
66        }
67        classify_arg(cx, arg);
68    }
69}
70
71pub(crate) fn compute_rust_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
72    if !fn_abi.ret.is_ignore() {
73        classify_ret(&mut fn_abi.ret);
74    }
75}