Skip to main content

luaur_code_gen/methods/
assembly_builder_a_64_place_a.rs

1use crate::enums::address_kind_a_64::AddressKindA64;
2use crate::records::address_a_64::AddressA64;
3use crate::records::assembly_builder_a_64::AssemblyBuilderA64;
4use crate::records::register_a_64::RegisterA64;
5
6impl AssemblyBuilderA64 {
7    pub fn place_a(
8        &mut self,
9        name: *const core::ffi::c_char,
10        dst: RegisterA64,
11        src: AddressA64,
12        opsize: u16,
13        sizelog: i32,
14    ) {
15        if self.log_text {
16            self.log_c_char_register_a_64_address_a_64(name, dst, src);
17        }
18
19        match src.kind {
20            AddressKindA64::reg => {
21                self.place(
22                    dst.index() as u32
23                        | ((src.base.index() as u32) << 5)
24                        | (0b011_0_10 << 10)
25                        | ((src.offset.index() as u32) << 16)
26                        | (1 << 21)
27                        | ((opsize as u32) << 22),
28                );
29            }
30            AddressKindA64::imm => {
31                let data = src.data as u32;
32                let shift_mask = (1 << sizelog) - 1;
33                if (data >> sizelog as u32) < 1024 && (data & shift_mask) == 0 {
34                    self.place(
35                        dst.index() as u32
36                            | ((src.base.index() as u32) << 5)
37                            | ((data >> sizelog as u32) << 10)
38                            | ((opsize as u32) << 22)
39                            | (1 << 24),
40                    );
41                } else if src.data >= -256 && src.data <= 255 {
42                    self.place(
43                        dst.index() as u32
44                            | ((src.base.index() as u32) << 5)
45                            | (((src.data as u32) & ((1 << 9) - 1)) << 12)
46                            | ((opsize as u32) << 22),
47                    );
48                } else {
49                    self.overflowed = true;
50
51                    // Original code: CODEGEN_ASSERT(!"Unable to encode large immediate offset");
52                    // Here we only need to fail, and CODEGEN_ASSERT's internal handler currently
53                    // expects raw pointers rather than &str.
54                    assert!(false);
55                }
56            }
57            AddressKindA64::pre => {
58                // Original code used CODEGEN_ASSERT with a pointer-based handler; avoid it here.
59                assert!(src.data >= -256 && src.data <= 255);
60                self.place(
61                    dst.index() as u32
62                        | ((src.base.index() as u32) << 5)
63                        | (0b11 << 10)
64                        | (((src.data as u32) & ((1 << 9) - 1)) << 12)
65                        | ((opsize as u32) << 22),
66                );
67            }
68            AddressKindA64::post => {
69                // Original code used CODEGEN_ASSERT with a pointer-based handler; avoid it here.
70                assert!(src.data >= -256 && src.data <= 255);
71                self.place(
72                    dst.index() as u32
73                        | ((src.base.index() as u32) << 5)
74                        | (0b01 << 10)
75                        | (((src.data as u32) & ((1 << 9) - 1)) << 12)
76                        | ((opsize as u32) << 22),
77                );
78            }
79        }
80
81        self.commit();
82    }
83}