luaur_code_gen/functions/
get_reload_address.rs1use crate::enums::address_kind_a_64::AddressKindA64;
2use crate::enums::ir_op_kind::IrOpKind;
3use crate::enums::kind_a_64::KindA64;
4use crate::functions::get_reload_offset::get_reload_offset;
5use crate::functions::vm_const_op::vm_const_op;
6use crate::functions::vm_reg_op::vm_reg_op;
7use crate::records::address_a_64::AddressA64;
8use crate::records::register_a_64::RegisterA64;
9use crate::records::value_restore_location::ValueRestoreLocation;
10use luaur_vm::type_aliases::t_value::TValue;
11
12const fn reg(kind: KindA64, index: u8) -> RegisterA64 {
13 RegisterA64 {
14 bits: kind as u8 | (index << RegisterA64::INDEX_SHIFT),
15 }
16}
17
18const R_BASE: RegisterA64 = reg(KindA64::x, 25);
19const R_CONSTANTS: RegisterA64 = reg(KindA64::x, 22);
20const XZR: RegisterA64 = reg(KindA64::x, 31);
21
22fn mem(base: RegisterA64, data: i32) -> AddressA64 {
23 AddressA64 {
24 kind: AddressKindA64::imm,
25 base,
26 offset: RegisterA64::noreg,
27 data,
28 }
29}
30
31pub fn get_reload_address(location: ValueRestoreLocation) -> AddressA64 {
32 let op = location.op;
33
34 if op.kind() == IrOpKind::VmReg {
35 let offset = vm_reg_op(op) as i32 * core::mem::size_of::<TValue>() as i32
36 + get_reload_offset(location.kind);
37 return mem(R_BASE, offset);
38 }
39
40 if op.kind() == IrOpKind::VmConst
42 && (vm_const_op(op) as usize * core::mem::size_of::<TValue>() <= AddressA64::kMaxOffset * 4)
43 {
44 let offset = vm_const_op(op) as i32 * core::mem::size_of::<TValue>() as i32
45 + get_reload_offset(location.kind);
46 return mem(R_CONSTANTS, offset);
47 }
48
49 AddressA64::address_a_64_register_a_64_register_a_64(XZR, XZR)
50}