luaur_code_gen/methods/
ir_lowering_a_64_temp_double.rs1use crate::enums::ir_op_kind::IrOpKind;
2use crate::enums::kind_a_64::KindA64;
3use crate::functions::get_double_bits::get_double_bits;
4use crate::macros::codegen_assert::CODEGEN_ASSERT;
5use crate::records::ir_lowering_a_64::IrLoweringA64;
6use crate::records::ir_op::IrOp;
7use crate::records::register_a_64::RegisterA64;
8
9impl IrLoweringA64 {
10 pub fn ir_lowering_a_64_temp_double(&mut self, op: IrOp) -> RegisterA64 {
11 if op.kind() == IrOpKind::Inst {
12 self.ir_lowering_a_64_reg_op(op)
13 } else if op.kind() == IrOpKind::Constant {
14 let val = self.ir_lowering_a_64_double_op(op);
15
16 if unsafe { (*self.build).is_fmov_supported_fp_64(val) } {
17 let temp = self.regs.alloc_temp(KindA64::d);
18 unsafe { (*self.build).fmov_register_a_64_f64(temp, val) };
19 return temp;
20 } else {
21 let temp1 = self.regs.alloc_temp(KindA64::x);
22 let temp2 = self.regs.alloc_temp(KindA64::d);
23
24 let vali = get_double_bits(val);
25
26 if (vali << 16) == 0 {
27 unsafe {
28 (*self.build).movz(temp1, (vali >> 48) as u16, 48);
29 (*self.build).fmov_register_a_64_register_a_64(temp2, temp1);
30 }
31 } else if (vali << 32) == 0 {
32 unsafe {
33 (*self.build).movz(temp1, (vali >> 48) as u16, 48);
34 (*self.build).movk(temp1, (vali >> 32) as u16, 32);
35 (*self.build).fmov_register_a_64_register_a_64(temp2, temp1);
36 }
37 } else {
38 unsafe {
39 (*self.build).adr_register_a_64_f64(temp1, val);
40 (*self.build).ldr(
41 temp2,
42 crate::records::address_a_64::AddressA64 {
43 kind: crate::enums::address_kind_a_64::AddressKindA64::imm,
44 base: temp1,
45 offset: RegisterA64::noreg,
46 data: 0,
47 },
48 );
49 }
50 }
51
52 return temp2;
53 }
54 } else {
55 CODEGEN_ASSERT!(false, "Unsupported instruction form");
56 return RegisterA64::noreg;
57 }
58 }
59}