pub trait ABICallee {
type I: VCodeInst;
Show 32 methods
fn temp_needed(&self) -> Option<Type>;
fn init(&mut self, maybe_tmp: Option<Writable<Reg>>);
fn accumulate_outgoing_args_size(&mut self, size: u32);
fn flags(&self) -> &Flags;
fn call_conv(&self) -> CallConv;
fn liveins(&self) -> Set<RealReg>;
fn liveouts(&self) -> Set<RealReg>;
fn num_args(&self) -> usize;
fn num_retvals(&self) -> usize;
fn num_stackslots(&self) -> usize;
fn gen_copy_arg_to_regs(
&self,
idx: usize,
into_reg: ValueRegs<Writable<Reg>>
) -> SmallInstVec<Self::I>;
fn arg_is_needed_in_body(&self, idx: usize) -> bool;
fn gen_retval_area_setup(&self) -> Option<Self::I>;
fn gen_copy_regs_to_retval(
&self,
idx: usize,
from_reg: ValueRegs<Writable<Reg>>
) -> SmallInstVec<Self::I>;
fn gen_ret(&self) -> Self::I;
fn gen_epilogue_placeholder(&self) -> Self::I;
fn set_num_spillslots(&mut self, slots: usize);
fn set_clobbered(&mut self, clobbered: Set<Writable<RealReg>>);
fn stackslot_addr(
&self,
slot: StackSlot,
offset: u32,
into_reg: Writable<Reg>
) -> Self::I;
fn load_stackslot(
&self,
slot: StackSlot,
offset: u32,
ty: Type,
into_reg: ValueRegs<Writable<Reg>>
) -> SmallInstVec<Self::I>;
fn store_stackslot(
&self,
slot: StackSlot,
offset: u32,
ty: Type,
from_reg: ValueRegs<Reg>
) -> SmallInstVec<Self::I>;
fn load_spillslot(
&self,
slot: SpillSlot,
ty: Type,
into_reg: ValueRegs<Writable<Reg>>
) -> SmallInstVec<Self::I>;
fn store_spillslot(
&self,
slot: SpillSlot,
ty: Type,
from_reg: ValueRegs<Reg>
) -> SmallInstVec<Self::I>;
fn spillslots_to_stack_map(
&self,
slots: &[SpillSlot],
state: &<Self::I as MachInstEmit>::State
) -> StackMap;
fn gen_prologue(&mut self) -> SmallInstVec<Self::I>;
fn gen_epilogue(&self) -> SmallInstVec<Self::I>;
fn frame_size(&self) -> u32;
fn stack_args_size(&self) -> u32;
fn get_spillslot_size(&self, rc: RegClass, ty: Type) -> u32;
fn gen_spill(
&self,
to_slot: SpillSlot,
from_reg: RealReg,
ty: Option<Type>
) -> Self::I;
fn gen_reload(
&self,
to_reg: Writable<RealReg>,
from_slot: SpillSlot,
ty: Option<Type>
) -> Self::I;
fn unwind_info_kind(&self) -> UnwindInfoKind;
}
Expand description
Trait implemented by an object that tracks ABI-related state (e.g., stack layout) and can generate code while emitting the body of a function.
Associated Types
Required methods
fn temp_needed(&self) -> Option<Type>
fn temp_needed(&self) -> Option<Type>
Does the ABI-body code need a temp reg (and if so, of what type)? One
will be provided to init()
as the maybe_tmp
arg if so.
Initialize. This is called after the ABICallee is constructed because it may be provided with a temp vreg, which can only be allocated once the lowering context exists.
fn accumulate_outgoing_args_size(&mut self, size: u32)
fn accumulate_outgoing_args_size(&mut self, size: u32)
Accumulate outgoing arguments. This ensures that at least SIZE bytes are allocated in the prologue to be available for use in function calls to hold arguments and/or return values. If this function is called multiple times, the maximum of all SIZE values will be available.
fn num_retvals(&self) -> usize
fn num_retvals(&self) -> usize
Number of return values.
fn num_stackslots(&self) -> usize
fn num_stackslots(&self) -> usize
Number of stack slots (not spill slots).
fn gen_copy_arg_to_regs(
&self,
idx: usize,
into_reg: ValueRegs<Writable<Reg>>
) -> SmallInstVec<Self::I>
fn gen_copy_arg_to_regs(
&self,
idx: usize,
into_reg: ValueRegs<Writable<Reg>>
) -> SmallInstVec<Self::I>
Generate an instruction which copies an argument to a destination register.
fn arg_is_needed_in_body(&self, idx: usize) -> bool
fn arg_is_needed_in_body(&self, idx: usize) -> bool
Is the given argument needed in the body (as opposed to, e.g., serving only as a special ABI-specific placeholder)? This controls whether lowering will copy it to a virtual reg use by CLIF instructions.
fn gen_retval_area_setup(&self) -> Option<Self::I>
fn gen_retval_area_setup(&self) -> Option<Self::I>
Generate any setup instruction needed to save values to the return-value area. This is usually used when were are multiple return values or an otherwise large return value that must be passed on the stack; typically the ABI specifies an extra hidden argument that is a pointer to that memory.
fn gen_copy_regs_to_retval(
&self,
idx: usize,
from_reg: ValueRegs<Writable<Reg>>
) -> SmallInstVec<Self::I>
fn gen_copy_regs_to_retval(
&self,
idx: usize,
from_reg: ValueRegs<Writable<Reg>>
) -> SmallInstVec<Self::I>
Generate an instruction which copies a source register to a return value slot.
fn gen_epilogue_placeholder(&self) -> Self::I
fn gen_epilogue_placeholder(&self) -> Self::I
Generate an epilogue placeholder. The returned instruction should return true
from
is_epilogue_placeholder()
; this is used to indicate to the lowering driver when
the epilogue should be inserted.
fn set_num_spillslots(&mut self, slots: usize)
fn set_num_spillslots(&mut self, slots: usize)
Update with the number of spillslots, post-regalloc.
fn set_clobbered(&mut self, clobbered: Set<Writable<RealReg>>)
fn set_clobbered(&mut self, clobbered: Set<Writable<RealReg>>)
Update with the clobbered registers, post-regalloc.
Get the address of a stackslot.
fn load_stackslot(
&self,
slot: StackSlot,
offset: u32,
ty: Type,
into_reg: ValueRegs<Writable<Reg>>
) -> SmallInstVec<Self::I>
fn load_stackslot(
&self,
slot: StackSlot,
offset: u32,
ty: Type,
into_reg: ValueRegs<Writable<Reg>>
) -> SmallInstVec<Self::I>
Load from a stackslot.
fn store_stackslot(
&self,
slot: StackSlot,
offset: u32,
ty: Type,
from_reg: ValueRegs<Reg>
) -> SmallInstVec<Self::I>
fn store_stackslot(
&self,
slot: StackSlot,
offset: u32,
ty: Type,
from_reg: ValueRegs<Reg>
) -> SmallInstVec<Self::I>
Store to a stackslot.
fn load_spillslot(
&self,
slot: SpillSlot,
ty: Type,
into_reg: ValueRegs<Writable<Reg>>
) -> SmallInstVec<Self::I>
fn load_spillslot(
&self,
slot: SpillSlot,
ty: Type,
into_reg: ValueRegs<Writable<Reg>>
) -> SmallInstVec<Self::I>
Load from a spillslot.
fn store_spillslot(
&self,
slot: SpillSlot,
ty: Type,
from_reg: ValueRegs<Reg>
) -> SmallInstVec<Self::I>
fn store_spillslot(
&self,
slot: SpillSlot,
ty: Type,
from_reg: ValueRegs<Reg>
) -> SmallInstVec<Self::I>
Store to a spillslot.
fn spillslots_to_stack_map(
&self,
slots: &[SpillSlot],
state: &<Self::I as MachInstEmit>::State
) -> StackMap
fn spillslots_to_stack_map(
&self,
slots: &[SpillSlot],
state: &<Self::I as MachInstEmit>::State
) -> StackMap
Generate a stack map, given a list of spillslots and the emission state at a given program point (prior to emission fo the safepointing instruction).
fn gen_prologue(&mut self) -> SmallInstVec<Self::I>
fn gen_prologue(&mut self) -> SmallInstVec<Self::I>
Generate a prologue, post-regalloc. This should include any stack
frame or other setup necessary to use the other methods (load_arg
,
store_retval
, and spillslot accesses.) self
is mutable so that we
can store information in it which will be useful when creating the
epilogue.
fn gen_epilogue(&self) -> SmallInstVec<Self::I>
fn gen_epilogue(&self) -> SmallInstVec<Self::I>
Generate an epilogue, post-regalloc. Note that this must generate the actual return instruction (rather than emitting this in the lowering logic), because the epilogue code comes before the return and the two are likely closely related.
fn frame_size(&self) -> u32
fn frame_size(&self) -> u32
Returns the full frame size for the given function, after prologue emission has run. This comprises the spill slots and stack-storage slots (but not storage for clobbered callee-save registers, arguments pushed at callsites within this function, or other ephemeral pushes). This is used for ABI variants where the client generates prologue/epilogue code, as in Baldrdash (SpiderMonkey integration).
fn stack_args_size(&self) -> u32
fn stack_args_size(&self) -> u32
Returns the size of arguments expected on the stack.
fn get_spillslot_size(&self, rc: RegClass, ty: Type) -> u32
fn get_spillslot_size(&self, rc: RegClass, ty: Type) -> u32
Get the spill-slot size.
Generate a spill. The type, if known, is given; this can be used to generate a store instruction optimized for the particular type rather than the RegClass (e.g., only F64 that resides in a V128 register). If no type is given, the implementation should spill the whole register.
Generate a reload (fill). As for spills, the type may be given to allow a more optimized load instruction to be generated.
fn unwind_info_kind(&self) -> UnwindInfoKind
fn unwind_info_kind(&self) -> UnwindInfoKind
Desired unwind info type.