Trait cranelift_codegen::machinst::abi_impl::ABIMachineSpec
source · [−]pub trait ABIMachineSpec {
type I: VCodeInst;
Show 32 methods
fn word_bits() -> u32;
fn stack_align(call_conv: CallConv) -> u32;
fn compute_arg_locs(
call_conv: CallConv,
params: &[AbiParam],
args_or_rets: ArgsOrRets,
add_ret_area_ptr: bool
) -> CodegenResult<(Vec<ABIArg>, i64, Option<usize>)>;
fn fp_to_arg_offset(call_conv: CallConv, flags: &Flags) -> i64;
fn gen_load_stack(
mem: StackAMode,
into_reg: Writable<Reg>,
ty: Type
) -> Self::I;
fn gen_store_stack(mem: StackAMode, from_reg: Reg, ty: Type) -> Self::I;
fn gen_move(to_reg: Writable<Reg>, from_reg: Reg, ty: Type) -> Self::I;
fn gen_extend(
to_reg: Writable<Reg>,
from_reg: Reg,
is_signed: bool,
from_bits: u8,
to_bits: u8
) -> Self::I;
fn gen_ret() -> Self::I;
fn gen_epilogue_placeholder() -> Self::I;
fn gen_add_imm(
into_reg: Writable<Reg>,
from_reg: Reg,
imm: u32
) -> SmallInstVec<Self::I>;
fn gen_stack_lower_bound_trap(limit_reg: Reg) -> SmallInstVec<Self::I>;
fn gen_get_stack_addr(
mem: StackAMode,
into_reg: Writable<Reg>,
ty: Type
) -> Self::I;
fn get_stacklimit_reg() -> Reg;
fn gen_load_base_offset(
into_reg: Writable<Reg>,
base: Reg,
offset: i32,
ty: Type
) -> Self::I;
fn gen_store_base_offset(
base: Reg,
offset: i32,
from_reg: Reg,
ty: Type
) -> Self::I;
fn gen_sp_reg_adjust(amount: i32) -> SmallInstVec<Self::I>;
fn gen_nominal_sp_adj(amount: i32) -> Self::I;
fn gen_prologue_frame_setup() -> SmallInstVec<Self::I>;
fn gen_epilogue_frame_restore() -> SmallInstVec<Self::I>;
fn gen_probestack(_frame_size: u32) -> SmallInstVec<Self::I>;
fn gen_clobber_save(
call_conv: CallConv,
flags: &Flags,
clobbers: &Set<Writable<RealReg>>,
fixed_frame_storage_size: u32,
outgoing_args_size: u32
) -> (u64, SmallVec<[Self::I; 16]>);
fn gen_clobber_restore(
call_conv: CallConv,
flags: &Flags,
clobbers: &Set<Writable<RealReg>>,
fixed_frame_storage_size: u32,
outgoing_args_size: u32
) -> SmallVec<[Self::I; 16]>;
fn gen_call(
dest: &CallDest,
uses: Vec<Reg>,
defs: Vec<Writable<Reg>>,
opcode: Opcode,
tmp: Writable<Reg>,
callee_conv: CallConv,
callee_conv: CallConv
) -> SmallVec<[(InstIsSafepoint, Self::I); 2]>;
fn get_number_of_spillslots_for_value(rc: RegClass, ty: Type) -> u32;
fn get_virtual_sp_offset_from_state(
s: &<Self::I as MachInstEmit>::State
) -> i64;
fn get_nominal_sp_to_fp(s: &<Self::I as MachInstEmit>::State) -> i64;
fn get_regs_clobbered_by_call(
call_conv_of_callee: CallConv
) -> Vec<Writable<Reg>>;
fn get_ext_mode(
call_conv: CallConv,
specified: ArgumentExtension
) -> ArgumentExtension;
fn word_bytes() -> u32 { ... }
fn word_type() -> Type { ... }
fn word_reg_class() -> RegClass { ... }
}
Expand description
Trait implemented by machine-specific backend to provide information about register assignments and to allow generating the specific instructions for stack loads/saves, prologues/epilogues, etc.
Associated Types
Required methods
Returns the number of bits in a word, that is 32/64 for 32/64-bit architecture.
fn stack_align(call_conv: CallConv) -> u32
fn stack_align(call_conv: CallConv) -> u32
Returns required stack alignment in bytes.
Process a list of parameters or return values and allocate them to registers and stack slots.
Returns the list of argument locations, the stack-space used (rounded up
to as alignment requires), and if add_ret_area_ptr
was passed, the
index of the extra synthetic arg that was added.
fn fp_to_arg_offset(call_conv: CallConv, flags: &Flags) -> i64
fn fp_to_arg_offset(call_conv: CallConv, flags: &Flags) -> i64
Returns the offset from FP to the argument area, i.e., jumping over the saved FP, return address, and maybe other standard elements depending on ABI (e.g. Wasm TLS reg).
fn gen_load_stack(mem: StackAMode, into_reg: Writable<Reg>, ty: Type) -> Self::I
fn gen_load_stack(mem: StackAMode, into_reg: Writable<Reg>, ty: Type) -> Self::I
Generate a load from the stack.
fn gen_store_stack(mem: StackAMode, from_reg: Reg, ty: Type) -> Self::I
fn gen_store_stack(mem: StackAMode, from_reg: Reg, ty: Type) -> Self::I
Generate a store to the stack.
Generate an integer-extend operation.
fn gen_epilogue_placeholder() -> Self::I
fn gen_epilogue_placeholder() -> Self::I
Generate an “epilogue placeholder” instruction, recognized by lowering when using the Baldrdash ABI.
fn gen_add_imm(
into_reg: Writable<Reg>,
from_reg: Reg,
imm: u32
) -> SmallInstVec<Self::I>
fn gen_add_imm(
into_reg: Writable<Reg>,
from_reg: Reg,
imm: u32
) -> SmallInstVec<Self::I>
Generate an add-with-immediate. Note that even if this uses a scratch register, it must satisfy two requirements:
-
The add-imm sequence must only clobber caller-save registers, because it will be placed in the prologue before the clobbered callee-save registers are saved.
-
The add-imm sequence must work correctly when
from_reg
and/orinto_reg
are the register returned byget_stacklimit_reg()
.
fn gen_stack_lower_bound_trap(limit_reg: Reg) -> SmallInstVec<Self::I>
fn gen_stack_lower_bound_trap(limit_reg: Reg) -> SmallInstVec<Self::I>
Generate a sequence that traps with a TrapCode::StackOverflow
code if
the stack pointer is less than the given limit register (assuming the
stack grows downward).
fn gen_get_stack_addr(
mem: StackAMode,
into_reg: Writable<Reg>,
ty: Type
) -> Self::I
fn gen_get_stack_addr(
mem: StackAMode,
into_reg: Writable<Reg>,
ty: Type
) -> Self::I
Generate an instruction to compute an address of a stack slot (FP- or SP-based offset).
fn get_stacklimit_reg() -> Reg
fn get_stacklimit_reg() -> Reg
Get a fixed register to use to compute a stack limit. This is needed for certain sequences generated after the register allocator has already run. This must satisfy two requirements:
-
It must be a caller-save register, because it will be clobbered in the prologue before the clobbered callee-save registers are saved.
-
It must be safe to pass as an argument and/or destination to
gen_add_imm()
. This is relevant when an addition with a large immediate needs its own temporary; it cannot use the same fixed temporary as this one.
Generate a store to the given [base+offset] address.
Generate a load from the given [base+offset] address.
fn gen_sp_reg_adjust(amount: i32) -> SmallInstVec<Self::I>
fn gen_sp_reg_adjust(amount: i32) -> SmallInstVec<Self::I>
Adjust the stack pointer up or down.
fn gen_nominal_sp_adj(amount: i32) -> Self::I
fn gen_nominal_sp_adj(amount: i32) -> Self::I
Generate a meta-instruction that adjusts the nominal SP offset.
fn gen_prologue_frame_setup() -> SmallInstVec<Self::I>
fn gen_prologue_frame_setup() -> SmallInstVec<Self::I>
Generate the usual frame-setup sequence for this architecture: e.g.,
push rbp / mov rbp, rsp
on x86-64, or stp fp, lr, [sp, #-16]!
on
AArch64.
fn gen_epilogue_frame_restore() -> SmallInstVec<Self::I>
fn gen_epilogue_frame_restore() -> SmallInstVec<Self::I>
Generate the usual frame-restore sequence for this architecture.
fn gen_probestack(_frame_size: u32) -> SmallInstVec<Self::I>
fn gen_probestack(_frame_size: u32) -> SmallInstVec<Self::I>
Generate a probestack call.
Generate a clobber-save sequence. This takes the list of all registers written/modified by the function body. The implementation here is responsible for determining which of these are callee-saved according to the ABI. It should return a sequence of instructions that “push” or otherwise save these values to the stack. The sequence of instructions should adjust the stack pointer downward, and should align as necessary according to ABI requirements.
Returns stack bytes used as well as instructions. Does not adjust nominal SP offset; caller will do that.
Generate a clobber-restore sequence. This sequence should perform the opposite of the clobber-save sequence generated above, assuming that SP going into the sequence is at the same point that it was left when the clobber-save sequence finished.
Generate a call instruction/sequence. This method is provided one temporary register to use to synthesize the called address, if needed.
fn get_number_of_spillslots_for_value(rc: RegClass, ty: Type) -> u32
fn get_number_of_spillslots_for_value(rc: RegClass, ty: Type) -> u32
Get the number of spillslots required for the given register-class and type.
fn get_virtual_sp_offset_from_state(s: &<Self::I as MachInstEmit>::State) -> i64
fn get_virtual_sp_offset_from_state(s: &<Self::I as MachInstEmit>::State) -> i64
Get the current virtual-SP offset from an instruction-emission state.
fn get_nominal_sp_to_fp(s: &<Self::I as MachInstEmit>::State) -> i64
fn get_nominal_sp_to_fp(s: &<Self::I as MachInstEmit>::State) -> i64
Get the “nominal SP to FP” offset from an instruction-emission state.
Get all caller-save registers, that is, registers that we expect not to be saved across a call to a callee with the given ABI.
fn get_ext_mode(
call_conv: CallConv,
specified: ArgumentExtension
) -> ArgumentExtension
fn get_ext_mode(
call_conv: CallConv,
specified: ArgumentExtension
) -> ArgumentExtension
Get the needed extension mode, given the mode attached to the argument in the signature and the calling convention. The input (the attribute in the signature) specifies what extension type should be done if the ABI requires extension to the full register; this method’s return value indicates whether the extension actually will be done.
Provided methods
fn word_bytes() -> u32
fn word_bytes() -> u32
Returns the number of bytes in a word.
fn word_reg_class() -> RegClass
fn word_reg_class() -> RegClass
Returns word register class.