xref: /freebsd/contrib/llvm-project/llvm/lib/Target/ARC/ARCInstrFormats.td (revision a90b9d0159070121c221b966469c3e36d912bf82)
1//===- ARCInstrFormats.td - ARC Instruction 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// Instruction format superclass
11//===----------------------------------------------------------------------===//
12
13class Encoding64 {
14  field bits<64> Inst;
15  field bits<64> SoftFail = 0;
16}
17
18// Address operands
19
20class immU<int BSz> : Operand<i32>, PatLeaf<(imm),
21    "\n    return isUInt<"#BSz#">(N->getSExtValue());"> {
22}
23
24def immU6 : immU<6>;
25
26class immS<int BSz> : Operand<i32>, PatLeaf<(imm),
27    "\n    return isInt<"#BSz#">(N->getSExtValue());"> {
28  let DecoderMethod = "DecodeSignedOperand<"#BSz#">";
29}
30
31// e.g. s3 field may encode the signed integers values -1 .. 6
32// using binary codes 111, 000, 001, 010, 011, 100, 101, and 110, respectively
33class immC<int BSz> : Operand<i32>, PatLeaf<(imm),
34    "\n    return isInt<"#BSz#">(N->getSExtValue());"> {
35  let DecoderMethod = "DecodeFromCyclicRange<"#BSz#">";
36}
37
38def MEMii : Operand<i32> {
39  let MIOperandInfo = (ops i32imm, i32imm);
40}
41
42def MEMrs9 : Operand<iAny> {
43  let MIOperandInfo = (ops GPR32:$B, immS<9>:$S9);
44  let PrintMethod = "printMemOperandRI";
45  let DecoderMethod = "DecodeMEMrs9";
46}
47
48def MEMrlimm : Operand<iAny> {
49  let MIOperandInfo = (ops GPR32:$B, i32imm:$LImm);
50  let PrintMethod = "printMemOperandRI";
51  let DecoderMethod = "DecodeMEMrlimm";
52}
53
54def GPR32Reduced : Operand<iAny> {
55  let DecoderMethod = "DecodeGBR32ShortRegister";
56}
57
58// Helper classes for load/store instructions
59class DataSizeMode<bits<2> mode, string instSfx, string asmSfx> {
60  bits<2> Value = mode;
61  string  InstSuffix = instSfx;
62  string  AsmSuffix  = asmSfx;
63}
64class ExtMode<bit mode, string instSfx, string asmSfx> {
65  bit     Value = mode;
66  string  InstSuffix = instSfx;
67  string  AsmSuffix  = asmSfx;
68}
69
70class AddrMode<bits<2> mode, string instSfx, string asmSfx> {
71  bits<2> Value = mode;
72  string  InstSuffix = instSfx;
73  string  AsmSuffix  = asmSfx;
74}
75
76class CacheMode<bit mode, string instSfx, string asmSfx> {
77  bit     Value = mode;
78  string  InstSuffix = instSfx;
79  string  AsmSuffix  = asmSfx;
80}
81
82def ByteSM : DataSizeMode<0b01, "B", "b">;
83def HalfSM : DataSizeMode<0b10, "H", "h">;
84def WordSM : DataSizeMode<0b00,  "",  "">;
85
86def NoEM      : ExtMode<0,   "",   "">;
87def SignedEM  : ExtMode<1, "_X", ".x">;
88
89def NoAM      : AddrMode<0b00, "", "">;
90def PreIncAM  : AddrMode<0b01, "_AW", ".aw">;
91def PostIncAM : AddrMode<0b10, "_AB", ".ab">;
92
93def NoCC       : CacheMode<0b0,    "",    "">;
94def UncachedCC : CacheMode<0b1, "_DI", ".di">;
95
96class InstARC<int sz, dag outs, dag ins, string asmstr, list<dag> pattern>
97    : Instruction, Encoding64 {
98
99  let Namespace = "ARC";
100  dag OutOperandList = outs;
101  dag InOperandList = ins;
102  let AsmString = asmstr;
103  let Pattern = pattern;
104  let Size = sz;
105
106  // Load/Store instruction properties
107  DataSizeMode ZZ = WordSM;
108  ExtMode X = NoEM;
109  AddrMode AA = NoAM;
110  CacheMode DI = NoCC;
111
112  // Field used for relation models
113  string BaseOpcode = "";
114
115  //TSFlags
116  let TSFlags{1-0} = AA.Value;
117}
118
119// ARC pseudo instructions format
120class PseudoInstARC<dag outs, dag ins, string asmstr, list<dag> pattern>
121   : InstARC<0, outs, ins, asmstr, pattern> {
122  let isPseudo = 1;
123}
124
125//===----------------------------------------------------------------------===//
126// Instruction formats
127//===----------------------------------------------------------------------===//
128
129// All 32-bit ARC instructions have a 5-bit "major" opcode class designator
130// in bits 27-31.
131//
132// Some general naming conventions:
133// N  - Delay Slot bit.  ARC v2 branch instructions have an optional delay slot
134//      which is encoded with this bit.  When set, a delay slot exists.
135// cc - Condition code.
136// SX - Signed X-bit immediate.
137// UX - Unsigned X-bit immediate.
138//
139// [ABC] - 32-bit register operand.  These are 6-bit fields.  This encodes the
140//         standard 32 general purpose registers, and allows use of additional
141//         (extension) registers.  This also encodes an instruction that uses
142//         a 32-bit Long Immediate (LImm), using 0x3e==62 as the field value.
143//         This makes 32-bit format instructions with Long Immediates
144//         64-bit instructions, with the Long Immediate in bits 32-63.
145// A - Inst[5-0] = A[5-0], when the format has A.  A is always a register.
146// B - Inst[14-12] = B[5-3], Inst[26-24] = B[2-0], when the format has B.
147//     B is always a register.
148// C - Inst[11-6] = C[5-0], when the format has C.  C can either be a register,
149//     or a 6-bit unsigned immediate (immU6), depending on the format.
150// F - Many instructions specify a flag bit. When set, the result of these
151//     instructions will set the ZNCV flags of the STATUS32 register
152//     (Zero/Negative/Carry/oVerflow).
153
154// Branch Instructions.
155class F32_BR<bits<5> major, dag outs, dag ins, bit b16, string asmstr,
156             list<dag> pattern> :
157  InstARC<4, outs, ins, asmstr, pattern> {
158  bit N;
159
160  let Inst{31-27} = major;
161  let Inst{16} = b16;
162  let Inst{5} = N;
163}
164
165class F32_BR_COND<bits<5> major, dag outs, dag ins, bit b16, string asmstr,
166                  list<dag> pattern> :
167  F32_BR<major, outs, ins, b16, asmstr, pattern> {
168  bits<21> S21; // 2-byte aligned 21-bit byte-offset.
169  bits<5> cc;
170  let Inst{26-18} = S21{10-2};
171  let Inst{15-6} = S21{20-11};
172  let Inst{4-0} = cc;
173}
174
175class F32_BR_UCOND_FAR<bits<5> major, dag outs, dag ins, bit b16, string asmstr,
176                       list<dag> pattern> :
177  F32_BR<major, outs, ins, b16, asmstr, pattern> {
178  bits<25> S25; // 2-byte aligned 25-bit byte-offset.
179  let Inst{26-18} = S25{10-2};
180  let Inst{15-6} = S25{20-11};
181  let Inst{4} = 0;
182  let Inst{3-0} = S25{24-21};
183}
184
185class F32_BR0_COND<dag outs, dag ins, string asmstr, list<dag> pat> :
186  F32_BR_COND<0b00000, outs, ins, 0, asmstr, pat> {
187  let Inst{17} = S21{1};
188}
189
190// Branch targets are 2-byte aligned, so S25[0] is implied 0.
191// |26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|9|8|7|6|5|4|3|2|1|0   |
192// |S25[10-1]                    | 1|S25[20-11]               |N|0|S25[24-21]|
193class F32_BR0_UCOND_FAR<dag outs, dag ins, string asmstr, list<dag> pat> :
194  F32_BR_UCOND_FAR<0b00000, outs, ins, 1, asmstr, pat> {
195  let Inst{17} = S25{1};
196}
197
198// BL targets (functions) are 4-byte aligned, so S25[1-0] = 0b00
199// |26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|9|8|7|6|5|4|3|2|1|0   |
200// |S25[10-2]                 | 1| 0|S25[20-11]               |N|0|S25[24-21]|
201class F32_BR1_BL_UCOND_FAR<dag outs, dag ins, string asmstr, list<dag> pat> :
202  F32_BR_UCOND_FAR<0b00001, outs, ins, 0, asmstr, pat> {
203  let Inst{17} = 1;
204}
205
206// BLcc targets have 21 bit range, and are 4-byte aligned.
207// |26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|9|8|7|6|5|4|3|2|1|0|
208// |S25[10-2]                 | 0| 0|S25[20-11]               |N|0|cc     |
209class F32_BR1_BL_COND<dag outs, dag ins, string asmstr, list<dag> pat> :
210  F32_BR_COND<0b00001, outs, ins, 0, asmstr, pat> {
211  let Inst{17} = 0;
212}
213
214// BRcc targets have limited 9-bit range.  These are for compare and branch
215// in single instruction.  Their targets are 2-byte aligned.  They also use
216// a different (3-bit) set of condition codes.
217// |26|25|24|23|22|21|20|19|18|17|16|15   |14|13|12|11|10|9|8|7|6|5|4|3|2|1|0|
218// |B[2-0]  |S9[7-1]             | 1|S9[8]|B[5-3]  |C            |N|u|0|cc   |
219class F32_BR1_BCC<dag outs, dag ins, string asmstr, bit IsU6,
220                  list<dag> pattern> :
221  InstARC<4, outs, ins, asmstr, pattern> {
222
223  bits<3> cc;
224  bits<6> B;
225  bits<6> C;
226  bit N;
227  bits<9> S9; // 2-byte aligned 9-bit byte-offset.
228
229  let Inst{31-27} = 0b00001;
230  let Inst{26-24} = B{2-0};
231  let Inst{23-17} = S9{7-1};
232  let Inst{16} = 1;
233  let Inst{15} = S9{8};
234  let Inst{14-12} = B{5-3};
235  let Inst{11-6} = C;
236  let Inst{5} = N;
237  let Inst{4} = IsU6;
238  let Inst{3} = 0;
239  let Inst{2-0} = cc;
240}
241
242// General operations instructions.
243// Single Operand Instructions.  Inst[5-0] specifies the specific operation
244// for this format.
245// |26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|9|8|7|6|5|4|3|2|1|0|
246// |B[2-0]  | 0| 0| 1| 0| 1| 1| 1| 1| F|B[5-3]  |C            |subop      |
247class F32_SOP_RR<bits<5> major, bits<6> subop, bit F, dag outs, dag ins,
248                 string asmstr, list<dag> pattern> :
249  InstARC<4, outs, ins, asmstr, pattern> {
250
251  bits<6> C;
252  bits<6> B;
253
254  let Inst{31-27} = major;
255  let Inst{26-24} = B{2-0};
256  let Inst{23-22} = 0b00;
257  let Inst{21-16} = 0b101111;
258  let Inst{15} = F;
259  let Inst{14-12} = B{5-3};
260  let Inst{11-6} = C;
261  let Inst{5-0} = subop;
262}
263
264// Dual Operand Instructions.  Inst[21-16] specifies the specific operation
265// for this format.
266
267// 3-register Dual Operand instruction.
268// |26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|9|8|7|6|5|4|3|2|1|0|
269// |B[2-0]  | 0| 0|            subop| F|B[5-3]  |C            |A          |
270class F32_DOP_RR<bits<5> major, bits<6> subop, bit F, dag outs, dag ins,
271                 string asmstr, list<dag> pattern> :
272  InstARC<4, outs, ins, asmstr, pattern> {
273  bits<6> C;
274  bits<6> B;
275  bits<6> A;
276
277  let Inst{31-27} = major;
278  let Inst{26-24} = B{2-0};
279  let Inst{23-22} = 0b00;
280  let Inst{21-16} = subop;
281  let Inst{15} = F;
282  let Inst{14-12} = B{5-3};
283  let Inst{11-6} = C;
284  let Inst{5-0} = A;
285}
286
287// Conditional Dual Operand instruction.  This instruction uses B as the
288// first 2 operands (i.e, add.cc B, B, C).
289// |26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|9|8|7|6|5|4|3|2|1|0|
290// |B[2-0]  | 1| 1|            subop| F|B[5-3]  |C            |A          |
291class F32_DOP_CC_RR<bits<5> major, bits<6> subop, bit F, dag outs, dag ins,
292                    string asmstr, list<dag> pattern> :
293  InstARC<4, outs, ins, asmstr, pattern> {
294  bits<5> cc;
295  bits<6> C;
296  bits<6> B;
297
298  let Inst{31-27} = major;
299  let Inst{26-24} = B{2-0};
300  let Inst{23-22} = 0b11;
301  let Inst{21-16} = subop;
302  let Inst{15} = F;
303  let Inst{14-12} = B{5-3};
304  let Inst{11-6} = C;
305  let Inst{5} = 0;
306  let Inst{4-0} = cc;
307}
308
309
310// 2-register, unsigned 6-bit immediate Dual Operand instruction.
311// |26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|9|8|7|6|5|4|3|2|1|0|
312// |B[2-0]  | 0| 1|            subop| F|B[5-3]  |U6           |A          |
313class F32_DOP_RU6<bits<5> major, bits<6> subop, bit F, dag outs, dag ins,
314                  string asmstr, list<dag> pattern> :
315  InstARC<4, outs, ins, asmstr, pattern> {
316  bits<6> U6;
317  bits<6> B;
318  bits<6> A;
319
320  let Inst{31-27} = major;
321  let Inst{26-24} = B{2-0};
322  let Inst{23-22} = 0b01;
323  let Inst{21-16} = subop;
324  let Inst{15} = F;
325  let Inst{14-12} = B{5-3};
326  let Inst{11-6} = U6;
327  let Inst{5-0} = A;
328}
329
330// 1-register, unsigned 6-bit, immediate Dual Operand instruction with
331// condition code.
332// |26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|9|8|7|6|5|4|3|2|1|0|
333// |B[2-0]  | 1| 1|            subop| F|B[5-3]  |U6           |1|cc       |
334class F32_DOP_CC_RU6<bits<5> major, bits<6> subop, bit F, dag outs, dag ins,
335                     string asmstr, list<dag> pattern> :
336  InstARC<4, outs, ins, asmstr, pattern> {
337
338  bits<5> cc;
339  bits<6> U6;
340  bits<6> B;
341
342  let Inst{31-27} = major;
343  let Inst{26-24} = B{2-0};
344  let Inst{23-22} = 0b11;
345  let Inst{21-16} = subop;
346  let Inst{15} = F;
347  let Inst{14-12} = B{5-3};
348  let Inst{11-6} = U6;
349  let Inst{5} = 1;
350  let Inst{4-0} = cc;
351
352  let DecoderMethod = "DecodeCCRU6Instruction";
353}
354
355// 2-register, unsigned 6-bit immediate Dual Operand instruction with
356// condition code. This instruction uses B as the first 2 operands
357// (i.e, add.cc B, B, u6).
358// |26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|9|8|7|6|5|4|3|2|1|0|
359// |B[2-0]  | 1| 1|            subop| F|B[5-3]  |U6           |1|cc       |
360class F32_DOP_CC_RRU6<bits<5> major, bits<6> subop, bit F, dag outs, dag ins,
361                      string asmstr, list<dag> pattern> :
362  InstARC<4, outs, ins, asmstr, pattern> {
363  bits<5> cc;
364  bits<6> U6;
365  bits<6> B;
366
367  let Inst{31-27} = major;
368  let Inst{26-24} = B{2-0};
369  let Inst{23-22} = 0b11;
370  let Inst{21-16} = subop;
371  let Inst{15} = F;
372  let Inst{14-12} = B{5-3};
373  let Inst{11-6} = U6;
374  let Inst{5} = 1;
375  let Inst{4-0} = cc;
376}
377
378// 2-register, signed 12-bit immediate Dual Operand instruction.
379// This instruction uses B as the first 2 operands (i.e., add B, B, -128).
380// |26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|9|8|7|6|5|4|3|2|1|0|
381// |B[2-0]  | 1| 0|            subop| F|B[5-3]  |S12[5-0]     |S12[11-6]  |
382class F32_DOP_RS12<bits<5> major, bits<6> subop, bit F, dag outs, dag ins,
383                   string asmstr, list<dag> pattern> :
384  InstARC<4, outs, ins, asmstr, pattern> {
385  bits<6> B;
386  bits<12> S12;
387
388  let Inst{31-27} = major;
389  let Inst{26-24} = B{2-0};
390  let Inst{23-22} = 0b10;
391  let Inst{21-16} = subop;
392  let Inst{15} = F;
393  let Inst{14-12} = B{5-3};
394  let Inst{11-6} = S12{5-0};
395  let Inst{5-0} = S12{11-6};
396}
397
398// 1-register, signed 12-bit immediate Dual Operand instruction.
399// This instruction uses B as the first operand (i.e., lr B, [%count0]).
400// |26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|9|8|7|6|5|4|3|2|1|0|
401// |B[2-0]  | 1| 0|            subop| F|B[5-3]  |S12[5-0]     |S12[11-6]  |
402class F32_SOP_RS12<bits<5> major, bits<6> subop, bit F, dag outs, dag ins,
403                   string asmstr, list<dag> pattern> :
404  InstARC<4, outs, ins, asmstr, pattern> {
405  bits<6> B;
406  bits<12> S12;
407
408  let Inst{31-27} = major;
409  let Inst{26-24} = B{2-0};
410  let Inst{23-22} = 0b10;
411  let Inst{21-16} = subop;
412  let Inst{15} = F;
413  let Inst{14-12} = B{5-3};
414  let Inst{11-6} = S12{5-0};
415  let Inst{5-0} = S12{11-6};
416
417  let DecoderMethod = "DecodeSOPwithRS12";
418}
419
420// 1-register, unsigned 6-bit immediate Dual Operand instruction.
421// This instruction uses B as the first operand.
422// |26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|9|8|7|6|5|4|3|2|1|0|
423// |B[2-0]  | 0| 1|            subop| F|B[5-3]  |U6           |0|0|0|0|0|0|
424class F32_SOP_RU6<bits<5> major, bits<6> subop, bit F, dag outs, dag ins,
425                  string asmstr, list<dag> pattern> :
426  InstARC<4, outs, ins, asmstr, pattern> {
427  bits<6> B;
428  bits<6> U6;
429
430  let Inst{31-27} = major;
431  let Inst{26-24} = B{2-0};
432  let Inst{23-22} = 0b01;
433  let Inst{21-16} = subop;
434  let Inst{15} = F;
435  let Inst{14-12} = B{5-3};
436  let Inst{11-6} = U6;
437  let Inst{5-0} = 0;
438
439  let DecoderMethod = "DecodeSOPwithRU6";
440}
441
442// 2-register, 32-bit immediate (LImm) Dual Operand instruction.
443// This instruction has the 32-bit immediate in bits 32-63, and
444// 62 in the C register operand slot, but is otherwise F32_DOP_RR.
445class F32_DOP_RLIMM<bits<5> major, bits<6> subop, bit F, dag outs, dag ins,
446                    string asmstr, list<dag> pattern> :
447  InstARC<8, outs, ins, asmstr, pattern> {
448  bits<6> B;
449  bits<6> A;
450  bits<32> LImm;
451
452  let Inst{63-32} = LImm;
453  let Inst{31-27} = major;
454  let Inst{26-24} = B{2-0};
455  let Inst{23-22} = 0b00;
456  let Inst{21-16} = subop;
457  let Inst{15} = F;
458  let Inst{14-12} = B{5-3};
459  let Inst{11-6} = 0b111110;
460  let Inst{5-0} = A;
461}
462
463
464// Load and store instructions.
465// In addition to the previous naming conventions, load and store instructions
466// have:
467// di - Uncached bit.  When set, loads/stores bypass the cache and access
468//      memory directly.
469// aa - Incrementing mode.  Loads and stores can write-back address pre- or
470//      post- memory operation.
471// zz - Memory size (can be 8/16/32 bit load/store).
472//  x - Sign-extending.  When set, short loads can be sign-extended to 32-bits.
473// Loads and Stores support different memory addressing modes:
474// Base Register + Signed 9-bit Immediate: Both Load/Store.
475// LImm: Both Load/Store (Load/Store from a fixed 32-bit address).
476// Register + Register: Load Only.
477// Register + LImm: Load Only.
478
479// Register + S9 Load. (B + S9)
480// |26|25|24|23|22|21|20|19|18|17|16|15   |14|13|12|11|10|9|8|7|6|5|4|3|2|1|0|
481// |B[2-0]  |S9[7-0]                |S9[8]|B[5-3]  |di|aa  |zz |x|A          |
482class F32_LD_RS9<bit x, bits<2> aa, bit di, bits<2> zz, dag outs, dag ins,
483                 string asmstr, list<dag> pattern> :
484  InstARC<4, outs, ins, asmstr, pattern> {
485  bits<6> B;
486  bits<6> A;
487  bits<9> S9;
488
489  let Inst{31-27} = 0b00010;
490  let Inst{26-24} = B{2-0};
491  let Inst{23-16} = S9{7-0};
492  let Inst{15} = S9{8};
493  let Inst{14-12} = B{5-3};
494  let Inst{11} = di;
495  let Inst{10-9} = aa;
496  let Inst{8-7} = zz;
497  let Inst{6} = x;
498  let Inst{5-0} = A;
499
500  let BaseOpcode = "ld_rs9";
501}
502
503class F32_LD_ADDR<bit x, bits<2> aa, bit di, bits<2> zz, dag outs, dag ins,
504                  string asmstr, list<dag> pattern> :
505  F32_LD_RS9<x, aa, di, zz, outs, ins, asmstr, pattern> {
506  bits<15> addr;
507
508  let B = addr{14-9};
509  let S9 = addr{8-0};
510
511  let BaseOpcode = "ld_rs9";
512}
513
514
515// LImm Load.  The 32-bit immediate address is in Inst[63-32].
516// |26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|9|8|7|6|5|4|3|2|1|0|
517// | 1| 1| 0| 0                        | 1| 1| 1|di| 0|0|zz |x|A          |
518class F32_LD_LIMM<bit x, bit di, bits<2> zz, dag outs, dag ins,
519                  string asmstr, list<dag> pattern> :
520  InstARC<8, outs, ins, asmstr, pattern> {
521  bits<6> LImmReg = 0b111110;
522  bits<6> A;
523  bits<32> LImm;
524
525  let Inst{63-32} = LImm;
526  let Inst{31-27} = 0b00010;
527  let Inst{26-24} = LImmReg{2-0};
528  let Inst{23-15} = 0;
529  let Inst{14-12} = LImmReg{5-3};
530  let Inst{11} = di;
531  let Inst{10-9} = 0;
532  let Inst{8-7} = zz;
533  let Inst{6} = x;
534  let Inst{5-0} = A;
535  let DecoderMethod = "DecodeLdLImmInstruction";
536
537  let BaseOpcode = "ld_limm";
538}
539
540// Register + LImm load.  The 32-bit immediate address is in Inst[63-32].
541// |26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|9|8|7|6|5|4|3|2|1|0|
542// |B[2-0]  |aa   | 1| 1| 0|zz   | x|di|B[5-3]  | 1| 1|1|1|1|0|A          |
543class F32_LD_RLIMM<bit x, bits<2> aa, bit di, bits<2> zz, dag outs, dag ins,
544                   string asmstr, list<dag> pattern> :
545  InstARC<8, outs, ins, asmstr, pattern> {
546  bits<6> LImmReg = 0b111110;
547  bits<32> LImm;
548  bits<6> B;
549  bits<6> A;
550  bits<38> addr;
551  let B = addr{37-32};
552  let LImm = addr{31-0};
553
554  let Inst{63-32} = LImm;
555  let Inst{31-27} = 0b00100;
556  let Inst{26-24} = B{2-0};
557  let Inst{23-22} = aa;
558  let Inst{21-19} = 0b110;
559  let Inst{18-17} = zz;
560  let Inst{16} = x;
561  let Inst{15} = di;
562  let Inst{14-12} = B{5-3};
563  let Inst{11-6} = LImmReg;
564  let Inst{5-0} = A;
565  let DecoderMethod = "DecodeLdRLImmInstruction";
566
567  let BaseOpcode = "ld_rlimm";
568}
569
570// Register + S9 Store. (B + S9)
571// |26|25|24|23|22|21|20|19|18|17|16|15   |14|13|12|11|10|9|8|7|6|5 |4|3|2|1|0|
572// |B[2-0]  |S9[7-0]                |S9[8]|B[5-3]  |C            |di|aa |zz |0|
573class F32_ST_RS9<bits<2> aa, bit di, bits<2> zz, dag outs, dag ins,
574                 string asmstr, list<dag> pattern> :
575  InstARC<4, outs, ins, asmstr, pattern> {
576  bits<6> B;
577  bits<6> C;
578  bits<9> S9;
579
580  let Inst{31-27} = 0b00011;
581  let Inst{26-24} = B{2-0};
582  let Inst{23-16} = S9{7-0};
583  let Inst{15} = S9{8};
584  let Inst{14-12} = B{5-3};
585  let Inst{11-6} = C;
586  let Inst{5} = di;
587  let Inst{4-3} = aa;
588  let Inst{2-1} = zz;
589  let Inst{0} = 0;
590
591  let BaseOpcode = "st_rs9";
592}
593
594class F32_ST_ADDR<bits<2> aa, bit di, bits<2> zz, dag outs, dag ins,
595                  string asmstr, list<dag> pattern> :
596  F32_ST_RS9<aa, di, zz, outs, ins, asmstr, pattern> {
597  bits<15> addr;
598
599  let B = addr{14-9};
600  let S9 = addr{8-0};
601
602  let BaseOpcode = "st_rs9";
603}
604
605// LImm Store.
606// |26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|9|8|7|6|5 |4|3|2|1|0|
607// | 1| 1| 0| 0                        | 1| 1| 1|C            |di|0|0|zz |0|
608class F32_ST_LIMM<bit di, bits<2> zz, dag outs, dag ins,
609                  string asmstr, list<dag> pattern> :
610  InstARC<8, outs, ins, asmstr, pattern> {
611  bits<6> LImmReg = 0b111110;
612  bits<6> C;
613  bits<32> LImm;
614
615  let Inst{63-32} = LImm;
616  let Inst{31-27} = 0b00011;
617  let Inst{26-24} = LImmReg{2-0};
618  let Inst{23-15} = 0;
619  let Inst{14-12} = LImmReg{5-3};
620  let Inst{11-6} = C;
621  let Inst{5} = di;
622  let Inst{4-3} = 0;
623  let Inst{2-1} = zz;
624  let Inst{0} = 0;
625  let DecoderMethod = "DecodeStLImmInstruction";
626
627  let BaseOpcode = "st_limm";
628}
629
630// Compact Move/Load.
631// |10|9|8|7|6|5|4|3|2|1|0|
632// |      |h    |   |i|H  |
633class F16_COMPACT<bits<1> i, dag outs, dag ins,
634                 string asmstr> :
635  InstARC<2, outs, ins, asmstr, []> {
636
637  bits<5> h;
638
639  let Inst{15-11} = 0b01000;
640  let Inst{7-5} = h{2-0};
641  let Inst{2} = i;
642  let Inst{1-0} = h{4-3};
643}
644
645// Compact Load/Add/Sub.
646class F16_LD_ADD_SUB<dag outs, dag ins, string asmstr> :
647  InstARC<2, outs, ins, asmstr, []> {
648
649  bits<3> b;
650  let Inst{15-11} = 0b01001;
651  let Inst{10-8} = b;
652}
653
654class F16_LD_SUB<bit i, string asmstr> :
655  F16_LD_ADD_SUB<(outs GPR32:$a), (ins GPR32:$b, GPR32:$c),
656  asmstr> {
657
658  bits<3> a;
659  bits<3> c;
660
661  let Inst{7-5} = c;
662  let Inst{4} = i;
663  let Inst{3} = 0;
664  let Inst{2-0} = a;
665}
666
667class F16_ADD :
668  F16_LD_ADD_SUB<(outs GPR32:$r), (ins GPR32:$b, immU<6>:$u6),
669  "add_s\t$r, $b, $u6"> {
670
671  bit r;
672  bits<6> u6;
673
674  let Inst{7} = r;
675  let Inst{6-4} = u6{5-3};
676  let Inst{3} = 1;
677  let Inst{2-0} = u6{2-0};
678}
679
680// Compact Load/Store.
681class F16_LD_ST_1<dag outs, dag ins, string asmstr> :
682  InstARC<2, outs, ins, asmstr, []> {
683
684  let Inst{15-11} = 0b01010;
685}
686
687class F16_LD_ST_s11<bit i, string asmstr> :
688  F16_LD_ST_1<(outs), (ins immS<11>:$s11), asmstr> {
689
690  bits<11> s11;
691
692  let Inst{10-5} = s11{10-5};
693  let Inst{4} = i;
694  let Inst{3} = 0;
695  let Inst{2-0} = s11{4-2};
696  let s11{1-0} = 0b00;
697}
698
699class F16_LDI_u7 :
700  F16_LD_ST_1<(outs GPR32:$b), (ins immU<7>:$u7),
701  "ldi_s\t$b, [$u7]"> {
702
703  bits<3> b;
704  bits<7> u7;
705
706  let Inst{10-8} = b;
707  let Inst{7-4} = u7{6-3};
708  let Inst{3} = 1;
709  let Inst{2-0} = u7{2-0};
710}
711
712// Indexed Jump or Execute.
713class F16_JLI_EI<bit i, string asmstr> :
714  InstARC<2, (outs), (ins immU<10>:$u10),
715  !strconcat(asmstr, "\t$u10"), []> {
716
717  bits<10> u10;
718
719  let Inst{15-11} = 0b01011;
720  let Inst{10} = i;
721  let Inst{9-0} = u10;
722}
723
724// Load/Add Register-Register.
725class F16_LD_ADD_RR<bits<2> i, string asmstr> :
726  InstARC<2, (outs GPR32:$a), (ins GPR32:$b, GPR32:$c),
727  asmstr, []> {
728
729  bits<3> a;
730  bits<3> b;
731  bits<3> c;
732
733  let Inst{15-11} = 0b01100;
734  let Inst{10-8} = b;
735  let Inst{7-5} = c;
736  let Inst{4-3} = i;
737  let Inst{2-0} = a;
738}
739
740// Load/Add GP-Relative.
741class F16_GP_LD_ADD<bits<2> i, dag ins, string asmstr> :
742  InstARC<2, (outs), ins, asmstr, []> {
743
744  let Inst{15-11} = 0b11001;
745  let Inst{10-9} = i;
746}
747
748// Add/Sub/Shift Register-Immediate.
749// |10|9|8|7|6|5|4|3|2|1|0|
750// |b     |c    |i  |u    |
751class F16_ADD_IMM<bits<2> i, string asmstr> :
752  InstARC<2, (outs GPR32:$c), (ins GPR32:$b, immU<3>:$u3),
753  !strconcat(asmstr, "\t$c, $b, $u3"), []> {
754
755  bits<3> b;
756  bits<3> c;
757  bits<3> u3;
758
759  let Inst{15-11} = 0b01101;
760  let Inst{10-8} = b;
761  let Inst{7-5} = c;
762  let Inst{4-3} = i;
763  let Inst{2-0} = u3;
764}
765
766// Dual Register Operations.
767// |10|9|8|7|6|5|4|3|2|1|0|
768// |b/s   |h    |i    |H  |
769class F16_OP_HREG<bits<3> i, dag outs, dag ins, string asmstr> :
770  InstARC<2, outs, ins, asmstr, []> {
771
772  bits<3> b_s3;
773  bits<5> h;
774
775  let Inst{15-11} = 0b01110;
776  let Inst{10-8} = b_s3;
777  let Inst{7-5} = h{2-0};
778  let Inst{4-2} = i;
779  let Inst{1-0} = h{4-3};
780}
781
782class F16_OP_HREG30<bits<3> i, dag outs, dag ins, string asmstr> :
783  F16_OP_HREG<i, outs, ins, asmstr> {
784
785  bits<5> LImmReg = 0b11110;
786  let Inst{7-5} = LImmReg{2-0};
787  let Inst{1-0} = LImmReg{4-3};
788}
789
790class F16_OP_HREG_LIMM<bits<3> i, dag outs, dag ins, string asmstr> :
791  F16_OP_HREG30<i, outs, ins, asmstr> {
792
793  bits<32> LImm;
794  let Inst{47-16} = LImm;
795  let Size = 6;
796}
797
798// General compact DOP format.
799class F16_GEN_DOP_BASE<bits<5> i, dag outs, dag ins, string asmstr> :
800  InstARC<2, outs, ins, asmstr, []> {
801
802  bits<3> b;
803  bits<3> c;
804  let Inst{15-11} = 0b01111;
805  let Inst{10-8} = b;
806  let Inst{7-5} = c;
807  let Inst{4-0} = i;
808}
809
810class F16_GEN_DOP<bits<5> i, string asmstr> :
811  F16_GEN_DOP_BASE<i, (outs GPR32:$b), (ins GPR32:$c),
812  !strconcat(asmstr, "\t$b, $b, $c")>;
813
814class F16_GEN_DOP_NODST<bits<5> i, string asmstr> :
815  F16_GEN_DOP_BASE<i, (outs), (ins GPR32:$b, GPR32:$c),
816  !strconcat(asmstr, "\t$b, $c")>;
817
818class F16_GEN_DOP_SINGLESRC<bits<5> i, string asmstr> :
819  F16_GEN_DOP_BASE<i, (outs GPR32:$b), (ins GPR32:$c),
820  !strconcat(asmstr, "\t$b, $c")>;
821
822class F16_GEN_SOP_BASE<bits<3> i, dag outs, dag ins, string asmstr> :
823  F16_GEN_DOP_BASE<0b00000, outs, ins, asmstr> {
824
825  let c = i;
826}
827
828class F16_GEN_SOP<bits<3> i, string asmstr> :
829  F16_GEN_SOP_BASE<i, (outs), (ins GPR32:$b), asmstr>;
830
831class F16_GEN_ZOP<bits<3> i, string asmstr> :
832  F16_GEN_SOP_BASE<0b111, (outs), (ins), asmstr> {
833
834  let b = i;
835}
836
837// Compact Load/Store with Offset Format.
838class F16_LD_ST_OFF<bits<5> opc, dag outs, dag ins, string asmstr> :
839  InstARC<2, outs, ins, !strconcat(asmstr, "\t$c, [$b, $off]"), []> {
840
841  bits<3> b;
842  bits<3> c;
843  let Inst{15-11} = opc;
844  let Inst{10-8} = b;
845  let Inst{7-5} = c;
846}
847
848class F16_LD_ST_WORD_OFF<bits<5> opc, dag outs, dag ins, string asmstr> :
849  F16_LD_ST_OFF<opc, outs, ins, asmstr> {
850
851  bits<7> off;
852  let Inst{4-0} = off{6-2};
853  let off{1-0} = 0b00;
854}
855
856class F16_LD_ST_HALF_OFF<bits<5> opc, dag outs, dag ins, string asmstr> :
857  F16_LD_ST_OFF<opc, outs, ins, asmstr> {
858
859  bits<6> off;
860  let Inst{4-0} = off{5-1};
861  let off{0} = 0b0;
862}
863
864class F16_LD_ST_BYTE_OFF<bits<5> opc, dag outs, dag ins, string asmstr> :
865  F16_LD_ST_OFF<opc, outs, ins, asmstr> {
866
867  bits<5> off;
868  let Inst{4-0} = off;
869}
870
871// Shift/Subtract/Bit Immediate.
872// |10|9|8|7|6|5|4|3|2|1|0|
873// |b     |i    |u        |
874class F16_SH_SUB_BIT<bits<3> i, string asmstr> :
875  InstARC<2, (outs), (ins GPR32:$b, immU<5>:$u5), asmstr, []> {
876
877  bits<3> b;
878  bits<5> u5;
879
880  let Inst{15-11} = 0b10111;
881  let Inst{10-8} = b;
882  let Inst{7-5} = i;
883  let Inst{4-0} = u5;
884}
885
886class F16_SH_SUB_BIT_DST<bits<3> i, string asmstr> :
887  F16_SH_SUB_BIT<i, !strconcat(asmstr, "\t$b, $b, $u5")>;
888
889// 16-bit stack-based operations.
890// |10|9|8|7|6|5|4|3|2|1|0|
891// |b     |i    |u        |
892class F16_SP_OPS<bits<3> i,
893  dag outs, dag ins, string asmstr> :
894  InstARC<2, outs, ins, asmstr, []> {
895
896  bits<3> fieldB;
897  bits<5> fieldU;
898
899  let Inst{15-11} = 0b11000;
900  let Inst{10-8} = fieldB;
901  let Inst{7-5} = i;
902  let Inst{4-0} = fieldU;
903}
904
905class F16_SP_OPS_u7_aligned<bits<3> i,
906  dag outs, dag ins, string asmstr> :
907  F16_SP_OPS<i, outs, ins, asmstr> {
908
909  bits<3> b3;
910  bits<7> u7;
911
912  let fieldB = b3;
913  let fieldU = u7{6-2};
914  let u7{1-0} = 0b00;
915}
916
917class F16_SP_OPS_bconst<bits<3> b, string asmop> :
918  F16_SP_OPS_u7_aligned<0b101,
919  (outs), (ins immU<7>:$u7),
920  !strconcat(asmop, "\t%sp, %sp, $u7")> {
921
922  let fieldB = b;
923}
924
925class F16_SP_OPS_uconst<bits<3> i,
926  dag outs, dag ins, string asmop> :
927  F16_SP_OPS_u7_aligned<i, outs, ins,
928  !strconcat(asmop, "\t$b3")> {
929
930  let fieldU = 0b00001;
931}
932
933class F16_SP_OPS_buconst<bits<3> i, string asmop> :
934  F16_SP_OPS_u7_aligned<i, (outs), (ins),
935    !strconcat(asmop, "\t%blink")> {
936
937  let fieldB = 0x000;
938  let fieldU = 0b10001;
939}
940
941class F16_SP_LD<bits<3> i, string asmop> : F16_SP_OPS_u7_aligned<i,
942                         (outs GPR32Reduced:$b3), (ins immU<7>:$u7),
943                         !strconcat(asmop, "\t$b3, [%sp, $u7]")>;
944
945class F16_SP_ST<bits<3> i, string asmop> : F16_SP_OPS_u7_aligned<i,
946                         (outs), (ins GPR32Reduced:$b3, immU<7>:$u7),
947                         !strconcat(asmop, "\t$b3, [%sp, $u7]")>;
948
949// Compact MOV/ADD/CMP Immediate Format.
950class F16_OP_IMM<bits<5> opc, dag outs, dag ins, string asmstr> :
951  InstARC<2, outs, ins, asmstr, []> {
952
953  bits<3> b;
954  let Inst{15-11} = opc;
955  let Inst{10-8} = b;
956}
957
958class F16_OP_U7<bit i, string asmstr> :
959  F16_OP_IMM<0b11100, (outs GPR32:$b), (ins immU<7>:$u7), asmstr> {
960
961  bits<7> u7;
962  let Inst{7} = i;
963  let Inst{6-0} = u7;
964}
965
966// Special types for different instruction operands.
967def ccond : Operand<i32> {
968  let MIOperandInfo = (ops i32imm);
969  let PrintMethod = "printPredicateOperand";
970}
971
972def brccond : Operand<i32> {
973  let MIOperandInfo = (ops i32imm);
974  let PrintMethod = "printBRCCPredicateOperand";
975}
976
977// Branch/call targets of different offset sizes.
978class BCTarget<ValueType vt> : Operand<vt> {
979  let OperandType = "OPERAND_PCREL";
980}
981
982def btarget : BCTarget<OtherVT>;
983
984class BCTargetSigned<ValueType vt, int BSz> : BCTarget<vt> {
985  let DecoderMethod = "DecodeBranchTargetS<"#BSz#">";
986}
987
988class BranchTargetS<int BSz> : BCTargetSigned<OtherVT, BSz>;
989def btargetS7 : BranchTargetS<7>;
990def btargetS8 : BranchTargetS<8>;
991def btargetS9 : BranchTargetS<9>;
992def btargetS10 : BranchTargetS<10>;
993def btargetS13 : BranchTargetS<13>;
994def btargetS21 : BranchTargetS<21>;
995def btargetS25 : BranchTargetS<25>;
996
997class CallTargetS<int BSz> : BCTargetSigned<i32, BSz>;
998def calltargetS25: CallTargetS<25>;
999
1000// Compact Branch on Compare Register with Zero.
1001class F16_BCC_REG<bit i, string asmstr> :
1002  InstARC<2, (outs), (ins GPR32:$b, btargetS8:$s8),
1003  !strconcat(asmstr, "\t$b, 0, $s8"), []> {
1004
1005  bits<3> b;
1006  bits<8> s8;
1007
1008  let Inst{15-11} = 0b11101;
1009  let Inst{10-8} = b;
1010  let Inst{7} = i;
1011  let Inst{6-0} = s8{7-1};
1012  let s8{0} = 0b0;
1013}
1014
1015// Compact Branch Conditionally Format.
1016class F16_BCC<bits<2> i, dag ins, string asmstr> :
1017  InstARC<2, (outs), ins, asmstr, []> {
1018
1019  let Inst{15-11} = 0b11110;
1020  let Inst{10-9} = i;
1021}
1022
1023class F16_BCC_s10<bits<2> i, string asmstr> :
1024  F16_BCC<i, (ins btargetS10:$s),
1025  !strconcat(asmstr, "\t$s")> {
1026
1027  bits<10> s;
1028  let Inst{8-0} = s{9-1};
1029  let s{0} = 0b0;
1030}
1031
1032class F16_BCC_s7<bits<3> i, string asmstr> :
1033  F16_BCC<0b11, (ins btargetS7:$s),
1034  !strconcat(asmstr, "\t$s")> {
1035
1036  bits<7> s;
1037  let Inst{8-6} = i;
1038  let Inst{5-0} = s{6-1};
1039  let s{0} = 0b0;
1040}
1041