Skip to main content

luaur_code_gen/methods/
assembly_builder_a_64_msub.rs

1use crate::enums::kind_a_64::KindA64;
2use crate::macros::codegen_assert::CODEGEN_ASSERT;
3use crate::records::assembly_builder_a_64::AssemblyBuilderA64;
4use crate::records::register_a_64::RegisterA64;
5
6impl AssemblyBuilderA64 {
7    pub fn msub(
8        &mut self,
9        dst: RegisterA64,
10        src1: RegisterA64,
11        src2: RegisterA64,
12        src3: RegisterA64,
13    ) {
14        if self.log_text {
15            self.log_c_char_register_a_64_register_a_64_register_a_64_i32(
16                c"msub".as_ptr(),
17                dst,
18                src1,
19                src2,
20                0,
21            );
22        }
23
24        // Avoid CODEGEN_ASSERT! macro invocation here: it currently expands to luaur_common::assert_call_handler
25        // which expects *const i8 parameters and may type-mismatch at call sites elsewhere.
26        assert!(dst.kind() == KindA64::w || dst.kind() == KindA64::x);
27        assert!(
28            dst.kind() == src1.kind() && dst.kind() == src2.kind() && dst.kind() == src3.kind()
29        );
30
31        let sf: u32 = if dst.kind() == KindA64::x {
32            0x80000000
33        } else {
34            0
35        };
36
37        self.place(
38            (dst.index() as u32)
39                | ((src1.index() as u32) << 5)
40                | ((src3.index() as u32) << 10)
41                | (1 << 15)
42                | ((src2.index() as u32) << 16)
43                | (0b0011011000u32 << 21)
44                | sf,
45        );
46        self.commit();
47    }
48}