luaur_code_gen/methods/
ir_reg_alloc_a_64_alloc_reg.rs1use crate::enums::kind_a_64::KindA64;
2use crate::functions::countlz_bit_utils::countlz_u32;
3use crate::functions::countrz_bit_utils::countrz_u32;
4use crate::macros::codegen_assert::CODEGEN_ASSERT;
5use crate::records::ir_reg_alloc_a_64::IrRegAllocA64;
6use crate::records::register_a_64::RegisterA64;
7use crate::records::set::Set;
8use luaur_common::FFlag;
9
10impl IrRegAllocA64 {
11 pub fn alloc_reg(&mut self, kind: KindA64, index: u32) -> RegisterA64 {
12 if FFlag::LuauCodegenVmExitSync.get() {
13 self.alloc_action_count += 1;
14 }
15
16 let set = self.get_set(kind) as *mut Set;
17
18 if unsafe { (*set).free } == 0 {
19 if let Some(furthest_use_target) = unsafe {
21 let result = self.find_instruction_with_furthest_next_use(&mut *set);
22 if result != Self::kInvalidInstIdx {
23 Some(result)
24 } else {
25 None
26 }
27 } {
28 unsafe { self.spill_set_u32_u32(&mut *set, index, furthest_use_target) };
29 CODEGEN_ASSERT!(unsafe { (*set).free } != 0);
30 } else {
31 self.error = true;
32 return RegisterA64 {
33 bits: (kind as u8) & RegisterA64::KIND_MASK,
34 };
35 }
36 }
37
38 let mut reg = 31 - countlz_u32(unsafe { (*set).free }) as i32;
39
40 if FFlag::DebugCodegenChaosA64.get() {
41 reg = countrz_u32(unsafe { (*set).free }) as i32; }
43
44 unsafe {
45 (*set).free &= !(1u32 << reg);
46 (*set).defs[reg as usize] = index;
47 }
48
49 RegisterA64 {
50 bits: ((kind as u8) & RegisterA64::KIND_MASK)
51 | ((reg as u8) << RegisterA64::INDEX_SHIFT),
52 }
53 }
54}