luaur_code_gen/methods/
ir_lowering_x_64_finish_function.rs1use crate::enums::code_gen_counter::CodeGenCounter;
2use crate::functions::dword_reg::dword_reg;
3use crate::records::emit_common_x_64::{K_EXTRA_SPILL_SLOTS, K_SPILL_SLOTS};
4use crate::records::ir_lowering_x_64::IrLoweringX64;
5use crate::records::operand_x_64::OperandX64;
6use crate::records::register_x_64::RegisterX64;
7use crate::type_aliases::instruction_ir_translation::Instruction;
8
9const K_VM_EXIT_ENTRY_GUARD_PC: u32 = (1u32 << 28) - 1;
10
11impl IrLoweringX64 {
12 pub fn ir_lowering_x_64_finish_function(&mut self) {
13 unsafe {
14 if (*self.build).log_text {
15 (*self.build).log_append(format_args!("; interrupt handlers\n"));
16 }
17
18 for i in 0..self.interrupt_handlers.len() {
19 let mut handler = self.interrupt_handlers[i];
20 (*self.build).set_label_label(&mut handler.self_);
21 (*self.build).mov(
22 OperandX64::reg(dword_reg(RegisterX64::rax)),
23 OperandX64::imm((handler.pcpos + 1) as i32),
24 );
25 (*self.build).lea_register_x_64_label(RegisterX64::rbx, &mut handler.next);
26 (*self.build).jmp_label(&mut (*self.helpers).interrupt);
27 }
28
29 if (*self.build).log_text {
30 (*self.build).log_append(format_args!("; exit handlers\n"));
31 }
32
33 for i in 0..self.exit_handlers.len() {
34 let mut handler = self.exit_handlers[i];
35 if handler.pcpos == K_VM_EXIT_ENTRY_GUARD_PC {
36 (*self.build).set_label_label(&mut handler.self_);
37
38 self.ir_lowering_x_64_alloc_and_increment_counter_at(
39 CodeGenCounter::VmExitTaken,
40 !0u32,
41 );
42
43 (*self.build).jmp_label(&mut (*self.helpers).exitContinueVmClearNativeFlag);
44 } else {
45 (*self.build).set_label_label(&mut handler.self_);
46
47 self.ir_lowering_x_64_alloc_and_increment_counter_at(
48 CodeGenCounter::VmExitTaken,
49 handler.pcpos,
50 );
51
52 (*self.build).mov(
53 OperandX64::reg(dword_reg(RegisterX64::rdx)),
54 OperandX64::imm(
55 (handler.pcpos * core::mem::size_of::<Instruction>() as u32) as i32,
56 ),
57 );
58 (*self.build).jmp_label(&mut (*self.helpers).updatePcAndContinueInVm);
59 }
60 }
61
62 let mut end = crate::records::label::Label::default();
63 (*self.build).set_label(&mut end);
64 (*self.function).end_location = (*self.build).get_label_offset(&end);
65 (*self.build).ud_2();
66
67 if !self.stats.is_null() {
68 if self.regs.max_used_slot > K_SPILL_SLOTS + K_EXTRA_SPILL_SLOTS {
69 (*self.stats).reg_alloc_errors += 1;
70 }
71
72 if self.regs.max_used_slot > (*self.stats).max_spill_slots_used {
73 (*self.stats).max_spill_slots_used = self.regs.max_used_slot;
74 }
75 }
76 }
77 }
78}