Push the ABI representation of the results stack.
(
&mut self,
results: &ABIResults,
masm: &mut M,
mut calculate_ret_area: F,
)
| 760 | |
| 761 | /// Push the ABI representation of the results stack. |
| 762 | pub fn push_abi_results<M, F>( |
| 763 | &mut self, |
| 764 | results: &ABIResults, |
| 765 | masm: &mut M, |
| 766 | mut calculate_ret_area: F, |
| 767 | ) -> Result<()> |
| 768 | where |
| 769 | M: MacroAssembler, |
| 770 | F: FnMut(&ABIResults, &mut CodeGenContext<Emission>, &mut M) -> Option<RetArea>, |
| 771 | { |
| 772 | let area = results |
| 773 | .on_stack() |
| 774 | .then(|| calculate_ret_area(&results, self, masm).unwrap()); |
| 775 | |
| 776 | for operand in results.operands().iter() { |
| 777 | match operand { |
| 778 | ABIOperand::Reg { reg, ty, .. } => { |
| 779 | ensure!( |
| 780 | self.regalloc.reg_available(*reg), |
| 781 | CodeGenError::expected_register_to_be_available(), |
| 782 | ); |
| 783 | |
| 784 | let typed_reg = TypedReg::new(*ty, self.reg(*reg, masm)?); |
| 785 | self.stack.push(typed_reg.into()); |
| 786 | } |
| 787 | ABIOperand::Stack { ty, offset, size } => match area.unwrap() { |
| 788 | RetArea::SP(sp_offset) => { |
| 789 | let slot = |
| 790 | StackSlot::new(SPOffset::from_u32(sp_offset.as_u32() - offset), *size); |
| 791 | self.stack.push(Val::mem(*ty, slot)); |
| 792 | } |
| 793 | // This function is only expected to be called when dealing |
| 794 | // with control flow and when calling functions; as a |
| 795 | // callee, only [Self::pop_abi_results] is needed when |
| 796 | // finalizing the function compilation. |
| 797 | _ => bail!(CodeGenError::unexpected_function_call()), |
| 798 | }, |
| 799 | } |
| 800 | } |
| 801 | |
| 802 | Ok(()) |
| 803 | } |
| 804 | |
| 805 | /// Truncates the value stack to the specified target. |
| 806 | /// This function is intended to only be used when restoring the code |