use crate::binemit::StackMap;
use crate::ir::{Signature, StackSlot};
use crate::isa::CallConv;
use crate::machinst::*;
use crate::settings;
use regalloc::{Reg, Set, SpillSlot, Writable};
use smallvec::SmallVec;
pub type SmallInstVec<I> = SmallVec<[I; 4]>;
pub trait ABICallee {
type I: VCodeInst;
fn temp_needed(&self) -> Option<Type>;
fn init(&mut self, maybe_tmp: Option<Writable<Reg>>);
fn signature(&self) -> &Signature;
fn accumulate_outgoing_args_size(&mut self, size: u32);
fn flags(&self) -> &settings::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 stackslot_offsets(&self) -> &PrimaryMap<StackSlot, u32>;
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_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;
}
pub trait ABICaller {
type I: VCodeInst;
fn num_args(&self) -> usize;
fn signature(&self) -> &Signature;
fn emit_copy_regs_to_arg<C: LowerCtx<I = Self::I>>(
&self,
ctx: &mut C,
idx: usize,
from_reg: ValueRegs<Reg>,
);
fn get_copy_to_arg_order(&self) -> SmallVec<[usize; 8]>;
fn emit_copy_retval_to_regs<C: LowerCtx<I = Self::I>>(
&self,
ctx: &mut C,
idx: usize,
into_reg: ValueRegs<Writable<Reg>>,
);
fn emit_stack_pre_adjust<C: LowerCtx<I = Self::I>>(&self, ctx: &mut C);
fn emit_stack_post_adjust<C: LowerCtx<I = Self::I>>(&self, ctx: &mut C);
fn accumulate_outgoing_args_size<C: LowerCtx<I = Self::I>>(&self, ctx: &mut C);
fn emit_call<C: LowerCtx<I = Self::I>>(&mut self, ctx: &mut C);
}