use crate::enums::ir_op_kind::IrOpKind;
use crate::enums::kind_a_64::KindA64;
use crate::macros::codegen_assert::CODEGEN_ASSERT;
use crate::records::ir_lowering_a_64::IrLoweringA64;
use crate::records::ir_op::IrOp;
use crate::records::register_a_64::RegisterA64;
impl IrLoweringA64 {
pub fn ir_lowering_a_64_temp_int_64(&mut self, op: IrOp) -> RegisterA64 {
if op.kind() == IrOpKind::Inst {
self.ir_lowering_a_64_reg_op(op)
} else if op.kind() == IrOpKind::Constant {
let temp = self.regs.alloc_temp(KindA64::x);
let u: u64 = self.ir_lowering_a_64_int_64_op(op) as u64;
let mut movz_count = 0;
let mut movn_count = 0;
for shift in (0..64).step_by(16) {
let hw = (u >> shift) as u16;
if hw != 0 {
movz_count += 1;
}
if hw != 0xFFFF {
movn_count += 1;
}
}
if movz_count <= movn_count {
let mut first = true;
for shift in (0..64).step_by(16) {
let hw = (u >> shift) as u16;
if hw != 0 {
if first {
unsafe { (*self.build).movz(temp, hw, shift as i32) };
first = false;
} else {
unsafe { (*self.build).movk(temp, hw, shift as i32) };
}
}
}
if first {
unsafe { (*self.build).movz(temp, 0, 0) };
}
} else {
let mut first = true;
for shift in (0..64).step_by(16) {
let hw = (u >> shift) as u16;
if hw != 0xFFFF {
if first {
unsafe { (*self.build).movn(temp, !hw, shift as i32) };
first = false;
} else {
unsafe { (*self.build).movk(temp, hw, shift as i32) };
}
}
}
if first {
unsafe { (*self.build).movn(temp, 0, 0) };
}
}
temp
} else {
CODEGEN_ASSERT!(false, "Unsupported instruction form");
RegisterA64::noreg
}
}
}