f853fca5c8b6757239e73b56152141a0130d62e8
[platform/upstream/llvm.git] / llvm / lib / Target / LoongArch / LoongArchFloatInstrFormats.td
1 // LoongArchFloatInstrFormats.td - LoongArch FP Instr Formats -*- tablegen -*-//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 //===----------------------------------------------------------------------===//
10 //  Describe LoongArch floating-point instructions format
11 //
12 //  opcode       - operation code.
13 //  fd           - destination register operand.
14 //  {c/f}{j/k/a} - source register operand.
15 //  immN         - immediate data operand.
16 //
17 //===----------------------------------------------------------------------===//
18
19 // Some FP instructions are defined twice, for accepting FPR32 and FPR64, but
20 // with the same mnemonic. Also some are codegen-only definitions that
21 // nevertheless require a "normal" mnemonic.
22 //
23 // In order to accommodate these needs, the instruction defs have names
24 // suffixed with `_x[SD]` or `_64`, that will get trimmed before the mnemonics
25 // are derived.
26 class deriveFPInsnMnemonic<string name> {
27   string ret = deriveInsnMnemonic<!subst("_64", "",
28                                          !subst("_xD", "",
29                                                 !subst("_xS", "", name)))>.ret;
30 }
31
32 // 2R-type
33 // <opcode | fj | fd>
34 class FPFmt2R<bits<32> op, dag outs, dag ins, string opnstr,
35               list<dag> pattern = []>
36     : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {
37   bits<5> fj;
38   bits<5> fd;
39
40   let Inst{31-0} = op;
41   let Inst{9-5} = fj;
42   let Inst{4-0} = fd;
43 }
44
45 // 3R-type
46 // <opcode | fk | fj | fd>
47 class FPFmt3R<bits<32> op, dag outs, dag ins, string opnstr,
48               list<dag> pattern = []>
49     : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {
50   bits<5> fk;
51   bits<5> fj;
52   bits<5> fd;
53
54   let Inst{31-0} = op;
55   let Inst{14-10} = fk;
56   let Inst{9-5} = fj;
57   let Inst{4-0} = fd;
58 }
59
60 // 4R-type
61 // <opcode | fa | fk | fj | fd>
62 class FPFmt4R<bits<32> op, dag outs, dag ins, string opnstr,
63               list<dag> pattern = []>
64     : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {
65   bits<5> fa;
66   bits<5> fk;
67   bits<5> fj;
68   bits<5> fd;
69
70   let Inst{31-0} = op;
71   let Inst{19-15} = fa;
72   let Inst{14-10} = fk;
73   let Inst{9-5} = fj;
74   let Inst{4-0} = fd;
75 }
76
77 // 2RI12-type
78 // <opcode | I12 | rj | fd>
79 class FPFmt2RI12<bits<32> op, dag outs, dag ins, string opnstr,
80                  list<dag> pattern = []>
81     : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {
82   bits<12> imm12;
83   bits<5> rj;
84   bits<5> fd;
85
86   let Inst{31-0} = op;
87   let Inst{21-10} = imm12;
88   let Inst{9-5} = rj;
89   let Inst{4-0} = fd;
90 }
91
92 // FmtFCMP
93 // <opcode | fk | fj | cd>
94 class FPFmtFCMP<bits<32> op, dag outs, dag ins, string opnstr,
95                 list<dag> pattern = []>
96     : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {
97   bits<5> fk;
98   bits<5> fj;
99   bits<3> cd;
100
101   let Inst{31-0} = op;
102   let Inst{14-10} = fk;
103   let Inst{9-5} = fj;
104   let Inst{2-0} = cd;
105 }
106
107 // FPFmtBR
108 // <opcode | I21[15:0] | cj | I21[20:16]>
109 class FPFmtBR<bits<32> op, dag outs, dag ins, string opnstr,
110               list<dag> pattern = []>
111     : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {
112   bits<21> imm21;
113   bits<3> cj;
114
115   let Inst{31-0} = op;
116   let Inst{25-10} = imm21{15-0};
117   let Inst{7-5} = cj;
118   let Inst{4-0} = imm21{20-16};
119 }
120
121 // FmtFSEL
122 // <opcode | ca | fk | fj | fd>
123 class FPFmtFSEL<bits<32> op, dag outs, dag ins, string opnstr,
124                 list<dag> pattern = []>
125     : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {
126   bits<3> ca;
127   bits<5> fk;
128   bits<5> fj;
129   bits<5> fd;
130
131   let Inst{31-0} = op;
132   let Inst{17-15} = ca;
133   let Inst{14-10} = fk;
134   let Inst{9-5} = fj;
135   let Inst{4-0} = fd;
136 }
137
138 // FPFmtMOV
139 // <opcode | src | dst>
140 class FPFmtMOV<bits<32> op, dag outs, dag ins, string opnstr,
141                list<dag> pattern = []>
142     : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {
143   bits<5> src;
144   bits<5> dst;
145
146   let Inst{31-0} = op;
147   let Inst{9-5} = src;
148   let Inst{4-0} = dst;
149 }
150
151 // FPFmtMEM
152 // <opcode | rk | rj | fd>
153 class FPFmtMEM<bits<32> op, dag outs, dag ins, string opnstr,
154                list<dag> pattern = []>
155     : LAInst<outs, ins, deriveFPInsnMnemonic<NAME>.ret, opnstr, pattern> {
156   bits<5> rk;
157   bits<5> rj;
158   bits<5> fd;
159
160   let Inst{31-0} = op;
161   let Inst{14-10} = rk;
162   let Inst{9-5} = rj;
163   let Inst{4-0} = fd;
164 }
165
166 //===----------------------------------------------------------------------===//
167 // Instruction class templates
168 //===----------------------------------------------------------------------===//
169
170 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
171 class FP_ALU_2R<bits<32> op, RegisterClass rc = FPR32>
172     : FPFmt2R<op, (outs rc:$fd), (ins rc:$fj), "$fd, $fj">;
173
174 class FP_ALU_3R<bits<32> op, RegisterClass rc = FPR32>
175     : FPFmt3R<op, (outs rc:$fd), (ins rc:$fj, rc:$fk), "$fd, $fj, $fk">;
176
177 class FP_ALU_4R<bits<32> op, RegisterClass rc = FPR32>
178     : FPFmt4R<op, (outs rc:$fd), (ins rc:$fj, rc:$fk, rc:$fa),
179               "$fd, $fj, $fk, $fa">;
180 } // hasSideEffects = 0, mayLoad = 0, mayStore = 0
181
182 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
183 class FP_CMP<bits<32> op, RegisterClass rc = FPR32>
184     : FPFmtFCMP<op, (outs CFR:$cd), (ins rc:$fj, rc:$fk), "$cd, $fj, $fk">;
185
186 class FP_CONV<bits<32> op, RegisterClass rcd = FPR32, RegisterClass rcs = FPR32>
187     : FPFmt2R<op, (outs rcd:$fd), (ins rcs:$fj), "$fd, $fj">;
188
189 class FP_MOV<bits<32> op, RegisterClass rcd = FPR32, RegisterClass rcs = FPR32>
190     : FPFmtMOV<op, (outs rcd:$dst), (ins rcs:$src), "$dst, $src">;
191
192 class FP_SEL<bits<32> op, RegisterClass rc = FPR32>
193     : FPFmtFSEL<op, (outs rc:$fd), (ins rc:$fj, rc:$fk, CFR:$ca),
194                 "$fd, $fj, $fk, $ca">;
195
196 class FP_BRANCH<bits<32> opcode>
197     : FPFmtBR<opcode, (outs), (ins CFR:$cj, simm21_lsl2:$imm21),
198               "$cj, $imm21"> {
199   let isBranch = 1;
200   let isTerminator = 1;
201 }
202 } // hasSideEffects = 0, mayLoad = 0, mayStore = 0
203
204 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
205 class FP_LOAD_3R<bits<32> op, RegisterClass rc = FPR32>
206     : FPFmtMEM<op, (outs rc:$fd), (ins GPR:$rj, GPR:$rk),
207                "$fd, $rj, $rk">;
208 class FP_LOAD_2RI12<bits<32> op, RegisterClass rc = FPR32>
209     : FPFmt2RI12<op, (outs rc:$fd), (ins GPR:$rj, simm12:$imm12),
210                  "$fd, $rj, $imm12">;
211 } // hasSideEffects = 0, mayLoad = 1, mayStore = 0
212
213 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
214 class FP_STORE_3R<bits<32> op, RegisterClass rc = FPR32>
215     : FPFmtMEM<op, (outs), (ins rc:$fd, GPR:$rj, GPR:$rk),
216                "$fd, $rj, $rk">;
217 class FP_STORE_2RI12<bits<32> op, RegisterClass rc = FPR32>
218     : FPFmt2RI12<op, (outs), (ins rc:$fd, GPR:$rj, simm12:$imm12),
219                  "$fd, $rj, $imm12">;
220 } // hasSideEffects = 0, mayLoad = 0, mayStore = 1