Skip to main content

luaur_code_gen/methods/
ir_lowering_a_64_temp_double.rs

1use 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}