1 // Reference: RISC-V ELF psABI specification
2 // https://github.com/riscv/riscv-elf-psabi-doc
4 use crate::abi::call::{ArgAbi, FnAbi};
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 {
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
19 arg.extend_integer_width_to(xlen); // this method only affects integer scalars
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 {
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
35 arg.extend_integer_width_to(xlen); // this method only affects integer scalars
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);
43 for arg in &mut fn_abi.args {
47 classify_arg(arg, xlen);