rustc_target/callconv/
nvptx64.rs1use arrayvec::ArrayVec;
2use rustc_abi::{HasDataLayout, Reg, Size, TyAbiInterface};
3
4use super::CastTarget;
5use crate::callconv::{ArgAbi, FnAbi, Uniform};
6
7fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
8 if ret.layout.is_aggregate() && ret.layout.is_sized() {
9 classify_aggregate(ret)
10 } else if ret.layout.size.bits() < 32 && ret.layout.is_sized() {
11 ret.extend_integer_width_to(32);
12 }
13}
14
15fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>)
16where
17 Ty: TyAbiInterface<'a, C> + Copy,
18{
19 if arg.layout.pass_indirectly_in_non_rustic_abis(cx) {
20 arg.make_indirect();
21 return;
22 }
23 if arg.layout.is_aggregate() && arg.layout.is_sized() {
24 classify_aggregate(arg)
25 } else if arg.layout.size.bits() < 32 && arg.layout.is_sized() {
26 arg.extend_integer_width_to(32);
27 }
28}
29
30fn classify_aggregate<Ty>(arg: &mut ArgAbi<'_, Ty>) {
32 let align_bytes = arg.layout.align.bytes();
33 let size = arg.layout.size;
34
35 let reg = match align_bytes {
36 1 => Reg::i8(),
37 2 => Reg::i16(),
38 4 => Reg::i32(),
39 8 => Reg::i64(),
40 16 => Reg::i128(),
41 _ => {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("Align is given as power of 2 no larger than 16 bytes")));
}unreachable!("Align is given as power of 2 no larger than 16 bytes"),
42 };
43
44 if align_bytes == size.bytes() {
45 let mut prefix = ArrayVec::new();
46 prefix.push(reg);
47 arg.cast_to(CastTarget::prefixed(prefix, Uniform::new(Reg::i8(), Size::ZERO)));
48 } else {
49 arg.cast_to(Uniform::new(reg, size));
50 }
51}
52
53fn classify_arg_kernel<'a, Ty, C>(_cx: &C, arg: &mut ArgAbi<'a, Ty>)
54where
55 Ty: TyAbiInterface<'a, C> + Copy,
56 C: HasDataLayout,
57{
58 match arg.mode {
59 super::PassMode::Ignore | super::PassMode::Direct(_) => return,
60 super::PassMode::Pair(_, _) => {}
61 super::PassMode::Cast { .. } => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
62 super::PassMode::Indirect { .. } => {}
63 }
64
65 let align_bytes = arg.layout.align.bytes();
71
72 let unit = match align_bytes {
73 1 => Reg::i8(),
74 2 => Reg::i16(),
75 4 => Reg::i32(),
76 8 => Reg::i64(),
77 16 => Reg::i128(),
78 _ => {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("Align is given as power of 2 no larger than 16 bytes")));
}unreachable!("Align is given as power of 2 no larger than 16 bytes"),
79 };
80 if arg.layout.size.bytes() / align_bytes == 1 {
81 let mut prefix = ArrayVec::new();
83 prefix.push(unit);
84 arg.cast_to(CastTarget::prefixed(prefix, Uniform::new(unit, Size::ZERO)));
85 } else {
86 arg.cast_to(Uniform::new(unit, arg.layout.size));
87 }
88}
89
90pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
91where
92 Ty: TyAbiInterface<'a, C> + Copy,
93{
94 if !fn_abi.ret.is_ignore() {
95 classify_ret(&mut fn_abi.ret);
96 }
97
98 for arg in fn_abi.args.iter_mut() {
99 if arg.is_ignore() {
100 continue;
101 }
102 classify_arg(cx, arg);
103 }
104}
105
106pub(crate) fn compute_ptx_kernel_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
107where
108 Ty: TyAbiInterface<'a, C> + Copy,
109 C: HasDataLayout,
110{
111 if !fn_abi.ret.layout.is_unit() && !fn_abi.ret.layout.is_never() {
112 {
::core::panicking::panic_fmt(format_args!("Kernels should not return anything other than () or !"));
};panic!("Kernels should not return anything other than () or !");
113 }
114
115 for arg in fn_abi.args.iter_mut() {
116 if arg.is_ignore() {
117 continue;
118 }
119 classify_arg_kernel(cx, arg);
120 }
121}