Emit the instructions to a `MachBuffer`, containing fixed-up code and external reloc/trap/etc. records ready for use. Takes the regalloc results as well. Returns the machine code itself, and optionally metadata and/or a disassembly, as an `EmitResult`. The `VCode` itself is consumed by the emission process.
(
mut self,
regalloc: ®alloc2::Output,
want_disasm: bool,
flags: &settings::Flags,
ctrl_plane: &mut ControlPlane,
)
| 734 | /// and/or a disassembly, as an `EmitResult`. The `VCode` itself |
| 735 | /// is consumed by the emission process. |
| 736 | pub fn emit( |
| 737 | mut self, |
| 738 | regalloc: ®alloc2::Output, |
| 739 | want_disasm: bool, |
| 740 | flags: &settings::Flags, |
| 741 | ctrl_plane: &mut ControlPlane, |
| 742 | ) -> EmitResult |
| 743 | where |
| 744 | I: VCodeInst, |
| 745 | { |
| 746 | let _tt = timing::vcode_emit(); |
| 747 | let mut buffer = MachBuffer::new(); |
| 748 | buffer.set_log2_min_function_alignment(self.log2_min_function_alignment); |
| 749 | let mut bb_starts: Vec<Option<CodeOffset>> = vec![]; |
| 750 | |
| 751 | // The first M MachLabels are reserved for block indices. |
| 752 | buffer.reserve_labels_for_blocks(self.num_blocks()); |
| 753 | |
| 754 | // Register all allocated constants with the `MachBuffer` to ensure that |
| 755 | // any references to the constants during instructions can be handled |
| 756 | // correctly. |
| 757 | buffer.register_constants(&self.constants); |
| 758 | |
| 759 | // Construct the final order we emit code in: cold blocks at the end. |
| 760 | let mut final_order: SmallVec<[BlockIndex; 16]> = smallvec![]; |
| 761 | let mut cold_blocks: SmallVec<[BlockIndex; 16]> = smallvec![]; |
| 762 | for block in 0..self.num_blocks() { |
| 763 | let block = BlockIndex::new(block); |
| 764 | if self.block_order.is_cold(block) { |
| 765 | cold_blocks.push(block); |
| 766 | } else { |
| 767 | final_order.push(block); |
| 768 | } |
| 769 | } |
| 770 | final_order.extend(cold_blocks.clone()); |
| 771 | |
| 772 | // Compute/save info we need for the prologue: clobbers and |
| 773 | // number of spillslots. |
| 774 | // |
| 775 | // We clone `abi` here because we will mutate it as we |
| 776 | // generate the prologue and set other info, but we can't |
| 777 | // mutate `VCode`. The info it usually carries prior to |
| 778 | // setting clobbers is fairly minimal so this should be |
| 779 | // relatively cheap. |
| 780 | let (clobbers, function_calls) = self.compute_clobbers_and_function_calls(regalloc); |
| 781 | self.abi.compute_frame_layout( |
| 782 | &self.sigs, |
| 783 | regalloc.num_spillslots, |
| 784 | clobbers, |
| 785 | function_calls, |
| 786 | ); |
| 787 | |
| 788 | // Emit blocks. |
| 789 | let mut cur_srcloc = None; |
| 790 | let mut last_offset = None; |
| 791 | let mut inst_offsets = vec![]; |
| 792 | let mut state = I::State::new(&self.abi, core::mem::take(ctrl_plane)); |
| 793 |
nothing calls this directly
no test coverage detected