Skip to main content

luaur_code_gen/methods/
assembly_builder_a_64_fmla.rs

1use crate::enums::kind_a_64::KindA64;
2use crate::records::assembly_builder_a_64::AssemblyBuilderA64;
3use crate::records::register_a_64::RegisterA64;
4
5impl AssemblyBuilderA64 {
6    pub fn fmla(&mut self, dst: RegisterA64, src1: RegisterA64, src2: RegisterA64) {
7        // There is no scalar version of FMLA instruction
8        // Vector instruction is used for both cases with proper sz bit.
9
10        //                Q U        Sz  Rm    Opcode Rn    Rd
11        let op: u32 = 0b0_0_0_011100_0_1_00000_110011_00000_00000;
12        let q_bit: u32 = 1 << 30;
13        let sz_bit: u32 = 1 << 22;
14
15        if dst.kind() == KindA64::d {
16            assert!(src1.kind() == KindA64::d && src2.kind() == KindA64::d);
17
18            if self.log_text {
19                self.log_append(format_args!(
20                    " {:<12}sd{},d{},d{}\n",
21                    "fmla",
22                    dst.index(),
23                    src1.index(),
24                    src2.index()
25                ));
26            }
27
28            self.place(
29                (dst.index() as u32)
30                    | ((src1.index() as u32) << 5)
31                    | ((src2.index() as u32) << 16)
32                    | op
33                    | q_bit
34                    | sz_bit,
35            );
36        } else if dst.kind() == KindA64::s {
37            assert!(src1.kind() == KindA64::s && src2.kind() == KindA64::s);
38
39            if self.log_text {
40                self.log_append(format_args!(
41                    " {:<12}ss{},s{},s{}\n",
42                    "fmla",
43                    dst.index(),
44                    src1.index(),
45                    src2.index()
46                ));
47            }
48
49            self.place(
50                (dst.index() as u32)
51                    | ((src1.index() as u32) << 5)
52                    | ((src2.index() as u32) << 16)
53                    | op,
54            );
55        } else {
56            assert!(
57                dst.kind() == KindA64::q && src1.kind() == KindA64::q && src2.kind() == KindA64::q
58            );
59
60            if self.log_text {
61                self.log_append(format_args!(
62                    " {:<12}sv{}.4s,v{}.4s,v{}.4s\n",
63                    "fmla",
64                    dst.index(),
65                    src1.index(),
66                    src2.index()
67                ));
68            }
69
70            self.place(
71                (dst.index() as u32)
72                    | ((src1.index() as u32) << 5)
73                    | ((src2.index() as u32) << 16)
74                    | op
75                    | q_bit,
76            );
77        }
78
79        self.commit();
80    }
81}