luaur_code_gen/methods/
ir_lowering_x_64_buffer_addr_op.rs1use crate::enums::ir_op_kind::IrOpKind;
2use crate::enums::size_x_64::SizeX64;
3use crate::macros::codegen_assert::CODEGEN_ASSERT;
4use crate::records::ir_lowering_x_64::IrLoweringX64;
5use crate::records::ir_op::IrOp;
6use crate::records::operand_x_64::OperandX64;
7use crate::records::register_x_64::RegisterX64;
8use luaur_vm::enums::lua_type::lua_Type;
9use luaur_vm::records::luau_buffer::LuauBuffer;
10use luaur_vm::records::udata::Udata;
11
12impl IrLoweringX64 {
13 pub fn buffer_addr_op(&mut self, buffer_op: IrOp, index_op: IrOp, tag: u8) -> OperandX64 {
14 CODEGEN_ASSERT!(tag == lua_Type::LUA_TUSERDATA as u8 || tag == lua_Type::LUA_TBUFFER as u8);
15 let data_offset = if tag == lua_Type::LUA_TBUFFER as u8 {
16 core::mem::size_of::<LuauBuffer>() - core::mem::size_of::<[core::ffi::c_char; 1]>()
17 } else {
18 core::mem::offset_of!(Udata, data)
19 };
20
21 if index_op.kind() == IrOpKind::Inst {
22 let inst_op = unsafe { (*self.function).inst_op(index_op) };
23 CODEGEN_ASSERT!(!crate::functions::produces_dirty_high_register_bits::produces_dirty_high_register_bits(inst_op.cmd));
24
25 let buffer_reg = self.reg_op(buffer_op);
26 let index_reg = self.reg_op(index_op);
27 let scaled_index = crate::functions::qword_reg::qword_reg(index_reg);
28 return OperandX64::operand_x_64_size_x_64_register_x_64_u8_register_x_64_i32(
29 SizeX64::qword,
30 scaled_index,
31 1,
32 buffer_reg,
33 data_offset as i32,
34 );
35 } else if index_op.kind() == IrOpKind::Constant {
36 let buffer_reg = self.reg_op(buffer_op);
37 let index_val = self.int_op(index_op);
38 return OperandX64::operand_x_64_size_x_64_register_x_64_u8_register_x_64_i32(
39 SizeX64::qword,
40 RegisterX64::noreg,
41 1,
42 buffer_reg,
43 index_val + data_offset as i32,
44 );
45 }
46
47 CODEGEN_ASSERT!(false, "Unsupported instruction form");
48 OperandX64::operand_x_64_register_x_64(RegisterX64::noreg)
49 }
50}