1//===- LoongArchInstrFormats.td - LoongArch 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 instructions format
11//
12//  opcode       - operation code.
13//  rd           - destination register operand.
14//  r{j/k}       - source register operand.
15//  immN         - immediate data operand.
16//
17//===----------------------------------------------------------------------===//
18
19class LAInst<dag outs, dag ins, string opcstr, string opnstr,
20             list<dag> pattern = []>
21    : Instruction {
22  field bits<32> Inst;
23  // SoftFail is a field the disassembler can use to provide a way for
24  // instructions to not match without killing the whole decode process. It is
25  // mainly used for ARM, but Tablegen expects this field to exist or it fails
26  // to build the decode table.
27  field bits<32> SoftFail = 0;
28
29  let Namespace = "LoongArch";
30  let Size = 4;
31  let OutOperandList = outs;
32  let InOperandList = ins;
33  let AsmString = opcstr # "\t" # opnstr;
34  let Pattern = pattern;
35}
36
37// Pseudo instructions
38class Pseudo<dag outs, dag ins, list<dag> pattern = [], string opcstr = "",
39             string opnstr = "">
40    : LAInst<outs, ins, opcstr, opnstr, pattern> {
41  let isPseudo = 1;
42  let isCodeGenOnly = 1;
43}
44
45class deriveInsnMnemonic<string name> {
46  string ret = !tolower(!subst("@", "_", !subst("_", ".", !subst("__", "@", name))));
47}
48
49// 2R-type
50// <opcode | rj | rd>
51class Fmt2R<bits<32> op, dag outs, dag ins, string opnstr,
52            list<dag> pattern = []>
53    : LAInst<outs, ins, deriveInsnMnemonic<NAME>.ret, opnstr, pattern> {
54  bits<5> rj;
55  bits<5> rd;
56
57  let Inst{31-0} = op;
58  let Inst{9-5} = rj;
59  let Inst{4-0} = rd;
60}
61
62// 3R-type
63// <opcode | rk | rj | rd>
64class Fmt3R<bits<32> op, dag outs, dag ins, string opnstr,
65            list<dag> pattern = []>
66    : LAInst<outs, ins, deriveInsnMnemonic<NAME>.ret, opnstr, pattern> {
67  bits<5> rk;
68  bits<5> rj;
69  bits<5> rd;
70
71  let Inst{31-0} = op;
72  let Inst{14-10} = rk;
73  let Inst{9-5} = rj;
74  let Inst{4-0} = rd;
75}
76
77// 3RI2-type
78// <opcode | I2 | rk | rj | rd>
79class Fmt3RI2<bits<32> op, dag outs, dag ins, string opnstr,
80              list<dag> pattern = []>
81    : LAInst<outs, ins, deriveInsnMnemonic<NAME>.ret, opnstr, pattern> {
82  bits<2> imm2;
83  bits<5> rk;
84  bits<5> rj;
85  bits<5> rd;
86
87  let Inst{31-0} = op;
88  let Inst{16-15} = imm2;
89  let Inst{14-10} = rk;
90  let Inst{9-5} = rj;
91  let Inst{4-0} = rd;
92}
93
94// 3RI3-type
95// <opcode | I3 | rk | rj | rd>
96class Fmt3RI3<bits<32> op, dag outs, dag ins, string opnstr,
97              list<dag> pattern = []>
98    : LAInst<outs, ins, deriveInsnMnemonic<NAME>.ret, opnstr, pattern> {
99  bits<3> imm3;
100  bits<5> rk;
101  bits<5> rj;
102  bits<5> rd;
103
104  let Inst{31-0} = op;
105  let Inst{17-15} = imm3;
106  let Inst{14-10} = rk;
107  let Inst{9-5} = rj;
108  let Inst{4-0} = rd;
109}
110
111// 2RI5-type
112// <opcode | I5 | rj | rd>
113class Fmt2RI5<bits<32> op, dag outs, dag ins, string opnstr,
114              list<dag> pattern = []>
115    : LAInst<outs, ins, deriveInsnMnemonic<NAME>.ret, opnstr, pattern> {
116  bits<5> imm5;
117  bits<5> rj;
118  bits<5> rd;
119
120  let Inst{31-0} = op;
121  let Inst{14-10} = imm5;
122  let Inst{9-5} = rj;
123  let Inst{4-0} = rd;
124}
125
126// 2RI6-type
127// <opcode | I6 | rj | rd>
128class Fmt2RI6<bits<32> op, dag outs, dag ins, string opnstr,
129              list<dag> pattern = []>
130    : LAInst<outs, ins, deriveInsnMnemonic<NAME>.ret, opnstr, pattern> {
131  bits<6> imm6;
132  bits<5> rj;
133  bits<5> rd;
134
135  let Inst{31-0} = op;
136  let Inst{15-10} = imm6;
137  let Inst{9-5} = rj;
138  let Inst{4-0} = rd;
139}
140
141// 2RI8-type
142// <opcode | I8 | rj | rd>
143class Fmt2RI8<bits<32> op, dag outs, dag ins, string opnstr,
144              list<dag> pattern = []>
145    : LAInst<outs, ins, deriveInsnMnemonic<NAME>.ret, opnstr, pattern> {
146  bits<8> imm8;
147  bits<5> rj;
148  bits<5> rd;
149
150  let Inst{31-0} = op;
151  let Inst{17-10} = imm8;
152  let Inst{9-5} = rj;
153  let Inst{4-0} = rd;
154}
155
156// 2RI12-type
157// <opcode | I12 | rj | rd>
158class Fmt2RI12<bits<32> op, dag outs, dag ins, string opnstr,
159               list<dag> pattern = []>
160    : LAInst<outs, ins, deriveInsnMnemonic<NAME>.ret, opnstr, pattern> {
161  bits<12> imm12;
162  bits<5> rj;
163  bits<5> rd;
164
165  let Inst{31-0} = op;
166  let Inst{21-10} = imm12;
167  let Inst{9-5} = rj;
168  let Inst{4-0} = rd;
169}
170
171// 2RI14-type
172// <opcode | I14 | rj | rd>
173class Fmt2RI14<bits<32> op, dag outs, dag ins, string opnstr,
174               list<dag> pattern = []>
175    : LAInst<outs, ins, deriveInsnMnemonic<NAME>.ret, opnstr, pattern> {
176  bits<14> imm14;
177  bits<5> rj;
178  bits<5> rd;
179
180  let Inst{31-0} = op;
181  let Inst{23-10} = imm14;
182  let Inst{9-5} = rj;
183  let Inst{4-0} = rd;
184}
185
186// 2RI16-type
187// <opcode | I16 | rj | rd>
188class Fmt2RI16<bits<32> op, dag outs, dag ins, string opnstr,
189               list<dag> pattern = []>
190    : LAInst<outs, ins, deriveInsnMnemonic<NAME>.ret, opnstr, pattern> {
191  bits<16> imm16;
192  bits<5> rj;
193  bits<5> rd;
194
195  let Inst{31-0} = op;
196  let Inst{25-10} = imm16;
197  let Inst{9-5} = rj;
198  let Inst{4-0} = rd;
199}
200
201// 1RI20-type
202// <opcode | I20 | rd>
203class Fmt1RI20<bits<32> op, dag outs, dag ins, string opnstr,
204               list<dag> pattern = []>
205    : LAInst<outs, ins, deriveInsnMnemonic<NAME>.ret, opnstr, pattern> {
206  bits<20> imm20;
207  bits<5> rd;
208
209  let Inst{31-0} = op;
210  let Inst{24-5} = imm20;
211  let Inst{4-0} = rd;
212}
213
214// 1RI21-type
215// <opcode | I21[15:0] | rj | I21[20:16]>
216class Fmt1RI21<bits<32> op, dag outs, dag ins, string opnstr,
217               list<dag> pattern = []>
218    : LAInst<outs, ins, deriveInsnMnemonic<NAME>.ret, opnstr, pattern> {
219  bits<21> imm21;
220  bits<5> rj;
221
222  let Inst{31-0} = op;
223  let Inst{25-10} = imm21{15-0};
224  let Inst{9-5} = rj;
225  let Inst{4-0} = imm21{20-16};
226}
227
228// I15-type
229// <opcode | I15>
230class FmtI15<bits<32> op, dag outs, dag ins, string opnstr,
231             list<dag> pattern = []>
232    : LAInst<outs, ins, deriveInsnMnemonic<NAME>.ret, opnstr, pattern> {
233  bits<15> imm15;
234
235  let Inst{31-0} = op;
236  let Inst{14-0} = imm15;
237}
238
239// I26-type
240// <opcode | I26[15:0] | I26[25:16]>
241class FmtI26<bits<32> op, dag outs, dag ins, string opnstr,
242             list<dag> pattern = []>
243    : LAInst<outs, ins, deriveInsnMnemonic<NAME>.ret, opnstr, pattern> {
244  bits<26> imm26;
245
246  let Inst{31-0} = op;
247  let Inst{25-10} = imm26{15-0};
248  let Inst{9-0} = imm26{25-16};
249}
250
251// FmtBSTR_W
252// <opcode | msbw | lsbw | rj | rd>
253class FmtBSTR_W<bits<32> op, dag outs, dag ins, string opnstr,
254                list<dag> pattern = []>
255    : LAInst<outs, ins, deriveInsnMnemonic<NAME>.ret, opnstr, pattern> {
256  bits<5> msbw;
257  bits<5> lsbw;
258  bits<5> rj;
259  bits<5> rd;
260
261  let Inst{31-0} = op;
262  let Inst{20-16} = msbw;
263  let Inst{14-10} = lsbw;
264  let Inst{9-5} = rj;
265  let Inst{4-0} = rd;
266}
267
268// FmtBSTR_D
269// <opcode | msbd | lsbd | rj | rd>
270class FmtBSTR_D<bits<32> op, dag outs, dag ins, string opnstr,
271                list<dag> pattern = []>
272    : LAInst<outs, ins, deriveInsnMnemonic<NAME>.ret, opnstr, pattern> {
273  bits<6> msbd;
274  bits<6> lsbd;
275  bits<5> rj;
276  bits<5> rd;
277
278  let Inst{31-0} = op;
279  let Inst{21-16} = msbd;
280  let Inst{15-10} = lsbd;
281  let Inst{9-5} = rj;
282  let Inst{4-0} = rd;
283}
284
285// FmtASRT
286// <opcode | rk | rj>
287class FmtASRT<bits<32> op, dag outs, dag ins, string opnstr,
288              list<dag> pattern = []>
289    : LAInst<outs, ins, deriveInsnMnemonic<NAME>.ret, opnstr, pattern> {
290  bits<5> rk;
291  bits<5> rj;
292
293  let Inst{31-0} = op;
294  let Inst{14-10} = rk;
295  let Inst{9-5} = rj;
296}
297
298// FmtPRELD
299// < 0b0010101011 | I12 | rj | I5>
300class FmtPRELD<dag outs, dag ins, string opnstr, list<dag> pattern = []>
301    : LAInst<outs, ins, deriveInsnMnemonic<NAME>.ret, opnstr, pattern> {
302  bits<12> imm12;
303  bits<5> rj;
304  bits<5> imm5;
305
306  let Inst{31-22} = 0b0010101011;
307  let Inst{21-10} = imm12;
308  let Inst{9-5} = rj;
309  let Inst{4-0} = imm5;
310}
311
312// FmtPRELDX
313// < 0b00111000001011000 | rk | rj | I5>
314class FmtPRELDX<dag outs, dag ins, string opnstr, list<dag> pattern = []>
315    : LAInst<outs, ins, deriveInsnMnemonic<NAME>.ret, opnstr, pattern> {
316  bits<5> rk;
317  bits<5> rj;
318  bits<5> imm5;
319
320  let Inst{31-15} = 0b00111000001011000;
321  let Inst{14-10} = rk;
322  let Inst{9-5} = rj;
323  let Inst{4-0} = imm5;
324}
325
326// FmtCSR
327// <opcode | csr_num | rd>
328class FmtCSR<bits<32> op, dag outs, dag ins, string opnstr,
329             list<dag> pattern = []>
330    : LAInst<outs, ins, deriveInsnMnemonic<NAME>.ret, opnstr, pattern> {
331  bits<14> csr_num;
332  bits<5> rd;
333
334  let Inst{31-0} = op;
335  let Inst{23-10} = csr_num;
336  let Inst{4-0} = rd;
337}
338
339// FmtCSRXCHG
340// <opcode | csr_num | rj | rd>
341class FmtCSRXCHG<bits<32> op, dag outs, dag ins, string opnstr,
342                 list<dag> pattern = []>
343    : LAInst<outs, ins, deriveInsnMnemonic<NAME>.ret, opnstr, pattern> {
344  bits<14> csr_num;
345  bits<5> rj;
346  bits<5> rd;
347
348  let Inst{31-0} = op;
349  let Inst{23-10} = csr_num;
350  let Inst{9-5} = rj;
351  let Inst{4-0} = rd;
352}
353
354// FmtCACOP
355// <0b0000011000 | I12 | rj | I5>
356class FmtCACOP<dag outs, dag ins, string opnstr, list<dag> pattern = []>
357    : LAInst<outs, ins, deriveInsnMnemonic<NAME>.ret, opnstr, pattern> {
358  bits<12> imm12;
359  bits<5> rj;
360  bits<5> op;
361
362  let Inst{31-22} = 0b0000011000;
363  let Inst{21-10} = imm12;
364  let Inst{9-5} = rj;
365  let Inst{4-0} = op;
366}
367
368// FmtIMM32
369// <I32>
370class FmtI32<bits<32> op, list<dag> pattern = []>
371    : LAInst<(outs), (ins), deriveInsnMnemonic<NAME>.ret, "", pattern> {
372  let Inst{31-0} = op;
373}
374
375// FmtINVTLB
376// <0b00000110010010011 | rk | rj | I5>
377class FmtINVTLB<dag outs, dag ins, string opnstr, list<dag> pattern = []>
378    : LAInst<outs, ins, deriveInsnMnemonic<NAME>.ret, opnstr, pattern> {
379  bits<5> rk;
380  bits<5> rj;
381  bits<5> op;
382
383  let Inst{31-15} = 0b00000110010010011;
384  let Inst{14-10} = rk;
385  let Inst{9-5} = rj;
386  let Inst{4-0} = op;
387}
388
389// FmtLDPTE
390// <0b00000110010001 | seq | rj | 00000>
391class FmtLDPTE<dag outs, dag ins, string opnstr, list<dag> pattern = []>
392    : LAInst<outs, ins, deriveInsnMnemonic<NAME>.ret, opnstr, pattern> {
393  bits<8> seq;
394  bits<5> rj;
395
396  let Inst{31-18} = 0b00000110010001;
397  let Inst{17-10} = seq;
398  let Inst{9-5} = rj;
399  let Inst{4-0} = 0b00000;
400}
401