Shared implementation for popping the ABI results. This is needed because, in some cases, params must be interpreted and used as the results of the block. When emitting code at control flow joins, the block params are interpreted as results, to ensure that they can correctly "flow" as the results of the block. This is especially important in the presence of empty then, else and loop blocks. This i
(
results: &mut ABIResults,
context: &mut CodeGenContext<Emission>,
masm: &mut M,
mut calculate_ret_area: F,
)
| 710 | /// a shared implementation allows the caller to decide how the |
| 711 | /// results should be interpreted. |
| 712 | pub fn pop_abi_results_impl<M, F>( |
| 713 | results: &mut ABIResults, |
| 714 | context: &mut CodeGenContext<Emission>, |
| 715 | masm: &mut M, |
| 716 | mut calculate_ret_area: F, |
| 717 | ) -> Result<()> |
| 718 | where |
| 719 | M: MacroAssembler, |
| 720 | F: FnMut(&ABIResults, &mut CodeGenContext<Emission>, &mut M) -> Result<Option<RetArea>>, |
| 721 | { |
| 722 | let mut iter = results.operands().iter().rev().peekable(); |
| 723 | |
| 724 | while let Some(ABIOperand::Reg { reg, .. }) = iter.peek() { |
| 725 | let TypedReg { reg, .. } = context.pop_to_reg(masm, Some(*reg))?; |
| 726 | context.free_reg(reg); |
| 727 | iter.next().unwrap(); |
| 728 | } |
| 729 | |
| 730 | let ret_area = calculate_ret_area(results, context, masm)?; |
| 731 | |
| 732 | let retptr = Self::maybe_load_retptr(ret_area.as_ref(), &results, context, masm)?; |
| 733 | if let Some(area) = ret_area { |
| 734 | if area.is_sp() { |
| 735 | Self::ensure_ret_area(&area, context, masm)?; |
| 736 | } |
| 737 | } |
| 738 | |
| 739 | if let Some(retptr) = retptr { |
| 740 | while let Some(ABIOperand::Stack { offset, .. }) = iter.peek() { |
| 741 | let addr = masm.address_at_reg(retptr, *offset)?; |
| 742 | context.pop_to_addr(masm, addr)?; |
| 743 | iter.next().unwrap(); |
| 744 | } |
| 745 | context.free_reg(retptr); |
| 746 | } |
| 747 | |
| 748 | if let Some(area) = ret_area { |
| 749 | if area.is_sp() { |
| 750 | Self::adjust_stack_results(area, results, context, masm)?; |
| 751 | } |
| 752 | } |
| 753 | |
| 754 | Ok(()) |
| 755 | } |
| 756 | |
| 757 | /// Convenience wrapper around [CodeGenContext::push_abi_results] using the |
| 758 | /// results of the current frame. |
nothing calls this directly
no test coverage detected