use crate::enums::category_x_64::CategoryX64;
use crate::macros::codegen_assert::CODEGEN_ASSERT;
use crate::macros::mod_rm::MOD_RM;
use crate::macros::sib::SIB;
use crate::records::assembly_builder_x_64::AssemblyBuilderX64;
use crate::records::operand_x_64::OperandX64;
use crate::records::register_x_64::RegisterX64;
impl AssemblyBuilderX64 {
pub fn place_mod_reg_mem(&mut self, rhs: OperandX64, regop: u8, extra_code_bytes: i32) {
if rhs.cat == CategoryX64::reg {
self.place(MOD_RM(0b11, regop, rhs.base.index()));
} else if rhs.cat == CategoryX64::mem {
let index = rhs.index;
let base = rhs.base;
let mut mod_ = 0b00;
if rhs.imm != 0 {
if (rhs.imm as i8) as i32 == rhs.imm {
mod_ = 0b01;
} else {
mod_ = 0b10;
}
} else {
if (base.index() & 0x7) == 0b101 {
mod_ = 0b01;
}
}
if index != RegisterX64::noreg && base != RegisterX64::noreg {
self.place(MOD_RM(mod_, regop, 0b100));
self.place(SIB(rhs.scale, index.index(), base.index()));
if mod_ != 0b00 {
self.place_imm_8_or_32(rhs.imm);
}
} else if index != RegisterX64::noreg && rhs.scale != 1 {
self.place(MOD_RM(0b00, regop, 0b100));
self.place(SIB(rhs.scale, index.index(), 0b101));
self.place_imm_32(rhs.imm);
} else if (base.index() & 0x7) == 0b100 {
if !(rhs.scale == 1) {
luaur_common::LUAU_DEBUGBREAK!();
}
if !(index == RegisterX64::noreg) {
luaur_common::LUAU_DEBUGBREAK!();
}
self.place(MOD_RM(mod_, regop, 0b100));
self.place(SIB(rhs.scale, 0b100, base.index()));
if rhs.imm != 0 {
self.place_imm_8_or_32(rhs.imm);
}
} else if base == RegisterX64::rip {
self.place(MOD_RM(0b00, regop, 0b101));
self.place_imm_32(
-((self.get_code_size() + 4 + extra_code_bytes as u32) as i32) + rhs.imm,
);
} else if base != RegisterX64::noreg {
self.place(MOD_RM(mod_, regop, base.index()));
if mod_ != 0b00 {
self.place_imm_8_or_32(rhs.imm);
}
} else {
self.place(MOD_RM(0b00, regop, 0b100));
self.place(SIB(1, 0b100, 0b101));
self.place_imm_32(rhs.imm);
}
} else {
luaur_common::LUAU_DEBUGBREAK!();
}
}
}