MCPcopy Create free account
hub / github.com/bytecodealliance/wasmtime / gen_call_rets

Method gen_call_rets

cranelift/codegen/src/machinst/abi.rs:1962–2082  ·  view source on GitHub ↗

Set up return values `outputs` for a call with signature `sig`. This does not emit (or return) any instructions, but returns a `CallRetList` representing the return value constraints. This needs to be added to the actual call instruction. If `try_call_payloads` is non-zero, it is expected to hold exception payload registers for try_call instructions. These will be added as needed to the `CallRe

(
        &self,
        sigs: &SigSet,
        sig: Sig,
        outputs: &[ValueRegs<Reg>],
        try_call_payloads: Option<&[Writable<Reg>]>,
        vregs: &mut VRegAllocator<M::I>,
    )

Source from the content-addressed store, hash-verified

1960 /// exception payload registers for try_call instructions. These
1961 /// will be added as needed to the `CallRetList` as well.
1962 pub fn gen_call_rets(
1963 &self,
1964 sigs: &SigSet,
1965 sig: Sig,
1966 outputs: &[ValueRegs<Reg>],
1967 try_call_payloads: Option<&[Writable<Reg>]>,
1968 vregs: &mut VRegAllocator<M::I>,
1969 ) -> CallRetList {
1970 let callee_conv = sigs[sig].call_conv;
1971 let stack_arg_space = sigs[sig].sized_stack_arg_space;
1972
1973 let word_ty = M::word_type();
1974 let word_bits = M::word_bits() as usize;
1975
1976 let mut defs: CallRetList = smallvec![];
1977 let mut outputs = outputs.into_iter();
1978 let num_rets = sigs.num_rets(sig);
1979 for idx in 0..num_rets {
1980 let ret = sigs.rets(sig)[idx].clone();
1981 match ret {
1982 ABIArg::Slots {
1983 ref slots, purpose, ..
1984 } => {
1985 // We do not use the returned copy of the return buffer pointer,
1986 // so skip any StructReturn returns that may be present.
1987 if purpose == ArgumentPurpose::StructReturn {
1988 continue;
1989 }
1990 let retval_regs = outputs.next().unwrap();
1991 assert_eq!(retval_regs.len(), slots.len());
1992 for (slot, retval_reg) in slots.iter().zip(retval_regs.regs().iter()) {
1993 // We do not perform any extension because we're copying out, not in,
1994 // and we ignore high bits in our own registers by convention. However,
1995 // we still need to use the proper extended type to access stack slots
1996 // (this is critical on big-endian systems).
1997 let (ty, extension) = match *slot {
1998 ABIArgSlot::Reg { ty, extension, .. } => (ty, extension),
1999 ABIArgSlot::Stack { ty, extension, .. } => (ty, extension),
2000 };
2001 let ext = M::get_ext_mode(callee_conv, extension);
2002 let ty = if ext != ir::ArgumentExtension::None && ty_bits(ty) < word_bits {
2003 word_ty
2004 } else {
2005 ty
2006 };
2007
2008 match slot {
2009 &ABIArgSlot::Reg { reg, .. } => {
2010 defs.push(CallRetPair {
2011 vreg: Writable::from_reg(*retval_reg),
2012 location: RetLocation::Reg(reg.into(), ty),
2013 });
2014 }
2015 &ABIArgSlot::Stack { offset, .. } => {
2016 let amode =
2017 StackAMode::OutgoingArg(offset + i64::from(stack_arg_space));
2018 defs.push(CallRetPair {
2019 vreg: Writable::from_reg(*retval_reg),

Callers 1

emit_vm_callFunction · 0.45

Calls 15

ty_bitsFunction · 0.85
fromFunction · 0.85
num_retsMethod · 0.80
retsMethod · 0.80
set_vreg_aliasMethod · 0.80
to_regMethod · 0.80
RegClass · 0.70
StackClass · 0.50
into_iterMethod · 0.45
cloneMethod · 0.45
unwrapMethod · 0.45
nextMethod · 0.45

Tested by

no test coverage detected