Generate the return instruction.
(&mut self, rets: &[ValueRegs<Reg>])
| 568 | |
| 569 | /// Generate the return instruction. |
| 570 | pub fn gen_return(&mut self, rets: &[ValueRegs<Reg>]) { |
| 571 | let mut out_rets = vec![]; |
| 572 | |
| 573 | let mut rets = rets.into_iter(); |
| 574 | for (i, ret) in self |
| 575 | .abi() |
| 576 | .signature() |
| 577 | .returns |
| 578 | .clone() |
| 579 | .into_iter() |
| 580 | .enumerate() |
| 581 | { |
| 582 | let regs = if ret.purpose == ArgumentPurpose::StructReturn { |
| 583 | self.sret_reg.unwrap() |
| 584 | } else { |
| 585 | *rets.next().unwrap() |
| 586 | }; |
| 587 | |
| 588 | let (regs, insns) = self.vcode.abi().gen_copy_regs_to_retval( |
| 589 | self.vcode.sigs(), |
| 590 | i, |
| 591 | regs, |
| 592 | &mut self.vregs, |
| 593 | ); |
| 594 | out_rets.extend(regs); |
| 595 | for insn in insns { |
| 596 | self.emit(insn); |
| 597 | } |
| 598 | } |
| 599 | |
| 600 | // Hack: generate a virtual instruction that uses vmctx in |
| 601 | // order to keep it alive for the duration of the function, |
| 602 | // for the benefit of debuginfo. |
| 603 | if self.f.dfg.values_labels.is_some() { |
| 604 | if let Some(vmctx_val) = self.f.special_param(ArgumentPurpose::VMContext) { |
| 605 | if self.value_ir_uses[vmctx_val] != ValueUseState::Unused { |
| 606 | let vmctx_reg = self.value_regs[vmctx_val].only_reg().unwrap(); |
| 607 | self.emit(I::gen_dummy_use(vmctx_reg)); |
| 608 | } |
| 609 | } |
| 610 | } |
| 611 | |
| 612 | let inst = self.abi().gen_rets(out_rets); |
| 613 | self.emit(inst); |
| 614 | } |
| 615 | |
| 616 | /// Generate list of registers to hold the output of a call with |
| 617 | /// signature `sig`. |
nothing calls this directly
no test coverage detected