]> git.lizzy.rs Git - rust.git/blob - src/librustc_target/abi/call/riscv.rs
Auto merge of #68414 - michaelwoerister:share-drop-glue, r=alexcrichton
[rust.git] / src / librustc_target / abi / call / riscv.rs
1 // Reference: RISC-V ELF psABI specification
2 // https://github.com/riscv/riscv-elf-psabi-doc
3
4 use crate::abi::call::{ArgAbi, FnAbi};
5
6 fn classify_ret<Ty>(arg: &mut ArgAbi<'_, Ty>, xlen: u64) {
7     // "Scalars wider than 2✕XLEN are passed by reference and are replaced in
8     // the argument list with the address."
9     // "Aggregates larger than 2✕XLEN bits are passed by reference and are
10     // replaced in the argument list with the address, as are C++ aggregates
11     // with nontrivial copy constructors, destructors, or vtables."
12     if arg.layout.size.bits() > 2 * xlen {
13         arg.make_indirect();
14     }
15
16     // "When passed in registers, scalars narrower than XLEN bits are widened
17     // according to the sign of their type up to 32 bits, then sign-extended to
18     // XLEN bits."
19     arg.extend_integer_width_to(xlen); // this method only affects integer scalars
20 }
21
22 fn classify_arg<Ty>(arg: &mut ArgAbi<'_, Ty>, xlen: u64) {
23     // "Scalars wider than 2✕XLEN are passed by reference and are replaced in
24     // the argument list with the address."
25     // "Aggregates larger than 2✕XLEN bits are passed by reference and are
26     // replaced in the argument list with the address, as are C++ aggregates
27     // with nontrivial copy constructors, destructors, or vtables."
28     if arg.layout.size.bits() > 2 * xlen {
29         arg.make_indirect();
30     }
31
32     // "When passed in registers, scalars narrower than XLEN bits are widened
33     // according to the sign of their type up to 32 bits, then sign-extended to
34     // XLEN bits."
35     arg.extend_integer_width_to(xlen); // this method only affects integer scalars
36 }
37
38 pub fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>, xlen: u64) {
39     if !fn_abi.ret.is_ignore() {
40         classify_ret(&mut fn_abi.ret, xlen);
41     }
42
43     for arg in &mut fn_abi.args {
44         if arg.is_ignore() {
45             continue;
46         }
47         classify_arg(arg, xlen);
48     }
49 }