Revert r354244 "[DAGCombiner] Eliminate dead stores to stack."
[llvm-complete.git] / lib / Target / ARC / ARCInstrFormats.td
blobabacf9100c7bfde95389a515725a182b332807d1
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 //===----------------------------------------------------------------------===//
9 //===----------------------------------------------------------------------===//
10 // Instruction format superclass
11 //===----------------------------------------------------------------------===//
13 class Encoding64 {
14   field bits<64> Inst;
15   field bits<64> SoftFail = 0;
18 // Address operands
20 class immU<int BSz> : Operand<i32>, PatLeaf<(imm),
21     "\n    return isUInt<"#BSz#">(N->getSExtValue());"> {
24 def immU6 : immU<6>;
26 class immS<int BSz> : Operand<i32>, PatLeaf<(imm),
27     "\n    return isInt<"#BSz#">(N->getSExtValue());"> {
28   let DecoderMethod = "DecodeSignedOperand<"#BSz#">";
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
33 class immC<int BSz> : Operand<i32>, PatLeaf<(imm),
34     "\n    return isInt<"#BSz#">(N->getSExtValue());"> {
35   let DecoderMethod = "DecodeFromCyclicRange<"#BSz#">";
38 def MEMii : Operand<i32> {
39   let MIOperandInfo = (ops i32imm, i32imm);
42 def MEMrs9 : Operand<iAny> {
43   let MIOperandInfo = (ops GPR32:$B, immS<9>:$S9);
44   let PrintMethod = "printMemOperandRI";
45   let DecoderMethod = "DecodeMEMrs9";
48 def MEMrlimm : Operand<iAny> {
49   let MIOperandInfo = (ops GPR32:$B, i32imm:$LImm);
50   let PrintMethod = "printMemOperandRI";
51   let DecoderMethod = "DecodeMEMrlimm";
54 def GPR32Reduced : Operand<iAny> {
55   let DecoderMethod = "DecodeGBR32ShortRegister";
58 class InstARC<int sz, dag outs, dag ins, string asmstr, list<dag> pattern>
59     : Instruction, Encoding64 {
61   let Namespace = "ARC";
62   dag OutOperandList = outs;
63   dag InOperandList = ins;
64   let AsmString = asmstr;
65   let Pattern = pattern;
66   let Size = sz;
69 // ARC pseudo instructions format
70 class PseudoInstARC<dag outs, dag ins, string asmstr, list<dag> pattern>
71    : InstARC<0, outs, ins, asmstr, pattern> {
72   let isPseudo = 1;
75 //===----------------------------------------------------------------------===//
76 // Instruction formats
77 //===----------------------------------------------------------------------===//
79 // All 32-bit ARC instructions have a 5-bit "major" opcode class designator
80 // in bits 27-31.   
81 // 
82 // Some general naming conventions:
83 // N  - Delay Slot bit.  ARC v2 branch instructions have an optional delay slot
84 //      which is encoded with this bit.  When set, a delay slot exists.
85 // cc - Condition code.
86 // SX - Signed X-bit immediate.
87 // UX - Unsigned X-bit immediate.
88 // 
89 // [ABC] - 32-bit register operand.  These are 6-bit fields.  This encodes the 
90 //         standard 32 general purpose registers, and allows use of additional
91 //         (extension) registers.  This also encodes an instruction that uses
92 //         a 32-bit Long Immediate (LImm), using 0x3e==62 as the field value.
93 //         This makes 32-bit format instructions with Long Immediates
94 //         64-bit instructions, with the Long Immediate in bits 32-63.
95 // A - Inst[5-0] = A[5-0], when the format has A.  A is always a register.
96 // B - Inst[14-12] = B[5-3], Inst[26-24] = B[2-0], when the format has B.
97 //     B is always a register.
98 // C - Inst[11-6] = C[5-0], when the format has C.  C can either be a register,
99 //     or a 6-bit unsigned immediate (immU6), depending on the format.
100 // F - Many instructions specify a flag bit. When set, the result of these
101 //     instructions will set the ZNCV flags of the STATUS32 register
102 //     (Zero/Negative/Carry/oVerflow).
104 // Branch Instructions.
105 class F32_BR<bits<5> major, dag outs, dag ins, bit b16, string asmstr,
106              list<dag> pattern> :
107   InstARC<4, outs, ins, asmstr, pattern> {
108   bit N;
110   let Inst{31-27} = major;
111   let Inst{16} = b16;
112   let Inst{5} = N;
115 class F32_BR_COND<bits<5> major, dag outs, dag ins, bit b16, string asmstr,
116                   list<dag> pattern> :
117   F32_BR<major, outs, ins, b16, asmstr, pattern> {
118   bits<21> S21; // 2-byte aligned 21-bit byte-offset.
119   bits<5> cc; 
120   let Inst{26-18} = S21{10-2};
121   let Inst{15-6} = S21{20-11};
122   let Inst{4-0} = cc;
125 class F32_BR_UCOND_FAR<bits<5> major, dag outs, dag ins, bit b16, string asmstr,
126                        list<dag> pattern> :
127   F32_BR<major, outs, ins, b16, asmstr, pattern> {
128   bits<25> S25; // 2-byte aligned 25-bit byte-offset.
129   let Inst{26-18} = S25{10-2};
130   let Inst{15-6} = S25{20-11};
131   let Inst{4} = 0;
132   let Inst{3-0} = S25{24-21};
135 class F32_BR0_COND<dag outs, dag ins, string asmstr, list<dag> pat> :
136   F32_BR_COND<0b00000, outs, ins, 0, asmstr, pat> {
137   let Inst{17} = S21{1};
140 // Branch targets are 2-byte aligned, so S25[0] is implied 0.
141 // |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   |
142 // |S25[10-1]                    | 1|S25[20-11]               |N|0|S25[24-21]|
143 class F32_BR0_UCOND_FAR<dag outs, dag ins, string asmstr, list<dag> pat> :
144   F32_BR_UCOND_FAR<0b00000, outs, ins, 1, asmstr, pat> {
145   let Inst{17} = S25{1};
148 // BL targets (functions) are 4-byte aligned, so S25[1-0] = 0b00
149 // |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   |
150 // |S25[10-2]                 | 1| 0|S25[20-11]               |N|0|S25[24-21]|
151 class F32_BR1_BL_UCOND_FAR<dag outs, dag ins, string asmstr, list<dag> pat> :
152   F32_BR_UCOND_FAR<0b00001, outs, ins, 0, asmstr, pat> {
153   let Inst{17} = 1;
156 // BLcc targets have 21 bit range, and are 4-byte aligned.
157 // |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|
158 // |S25[10-2]                 | 0| 0|S25[20-11]               |N|0|cc     |
159 class F32_BR1_BL_COND<dag outs, dag ins, string asmstr, list<dag> pat> :
160   F32_BR_COND<0b00001, outs, ins, 0, asmstr, pat> {
161   let Inst{17} = 0;
164 // BRcc targets have limited 9-bit range.  These are for compare and branch
165 // in single instruction.  Their targets are 2-byte aligned.  They also use
166 // a different (3-bit) set of condition codes.
167 // |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|
168 // |B[2-0]  |S9[7-1]             | 1|S9[8]|B[5-3]  |C            |N|u|0|cc   |
169 class F32_BR1_BCC<dag outs, dag ins, string asmstr, bit IsU6,
170                   list<dag> pattern> :
171   InstARC<4, outs, ins, asmstr, pattern> {
173   bits<3> cc;
174   bits<6> B;
175   bits<6> C;
176   bit N;
177   bits<9> S9; // 2-byte aligned 9-bit byte-offset.
179   let Inst{31-27} = 0b00001;
180   let Inst{26-24} = B{2-0};
181   let Inst{23-17} = S9{7-1};
182   let Inst{16} = 1;
183   let Inst{15} = S9{8};
184   let Inst{14-12} = B{5-3};
185   let Inst{11-6} = C;
186   let Inst{5} = N;
187   let Inst{4} = IsU6;
188   let Inst{3} = 0;
189   let Inst{2-0} = cc;
192 // General operations instructions.
193 // Single Operand Instructions.  Inst[5-0] specifies the specific operation
194 // for this format.
195 // |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|
196 // |B[2-0]  | 0| 0| 1| 0| 1| 1| 1| 1| F|B[5-3]  |C            |subop      |
197 class F32_SOP_RR<bits<5> major, bits<6> subop, bit F, dag outs, dag ins,
198                  string asmstr, list<dag> pattern> :
199   InstARC<4, outs, ins, asmstr, pattern> {
201   bits<6> C;
202   bits<6> B;
204   let Inst{31-27} = major;
205   let Inst{26-24} = B{2-0};
206   let Inst{23-22} = 0b00;
207   let Inst{21-16} = 0b101111;
208   let Inst{15} = F;
209   let Inst{14-12} = B{5-3};
210   let Inst{11-6} = C;
211   let Inst{5-0} = subop;
214 // Dual Operand Instructions.  Inst[21-16] specifies the specific operation
215 // for this format.
217 // 3-register Dual Operand instruction.
218 // |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|
219 // |B[2-0]  | 0| 0|            subop| F|B[5-3]  |C            |A          |
220 class F32_DOP_RR<bits<5> major, bits<6> subop, bit F, dag outs, dag ins,
221                  string asmstr, list<dag> pattern> :
222   InstARC<4, outs, ins, asmstr, pattern> {
223   bits<6> C;
224   bits<6> B;
225   bits<6> A;
227   let Inst{31-27} = major;
228   let Inst{26-24} = B{2-0};
229   let Inst{23-22} = 0b00;
230   let Inst{21-16} = subop;
231   let Inst{15} = F;
232   let Inst{14-12} = B{5-3};
233   let Inst{11-6} = C;
234   let Inst{5-0} = A;
237 // Conditional Dual Operand instruction.  This instruction uses B as the
238 // first 2 operands (i.e, add.cc B, B, C).
239 // |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|
240 // |B[2-0]  | 1| 1|            subop| F|B[5-3]  |C            |A          |
241 class F32_DOP_CC_RR<bits<5> major, bits<6> subop, bit F, dag outs, dag ins,
242                     string asmstr, list<dag> pattern> :
243   InstARC<4, outs, ins, asmstr, pattern> {
244   bits<5> cc;
245   bits<6> C;
246   bits<6> B;
248   let Inst{31-27} = major;
249   let Inst{26-24} = B{2-0};
250   let Inst{23-22} = 0b11;
251   let Inst{21-16} = subop;
252   let Inst{15} = F;
253   let Inst{14-12} = B{5-3};
254   let Inst{11-6} = C;
255   let Inst{5} = 0;
256   let Inst{4-0} = cc;
260 // 2-register, unsigned 6-bit immediate Dual Operand instruction.
261 // |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|
262 // |B[2-0]  | 0| 1|            subop| F|B[5-3]  |U6           |A          |
263 class F32_DOP_RU6<bits<5> major, bits<6> subop, bit F, dag outs, dag ins,
264                   string asmstr, list<dag> pattern> :
265   InstARC<4, outs, ins, asmstr, pattern> {
266   bits<6> U6;
267   bits<6> B;
268   bits<6> A;
270   let Inst{31-27} = major;
271   let Inst{26-24} = B{2-0};
272   let Inst{23-22} = 0b01;
273   let Inst{21-16} = subop;
274   let Inst{15} = F;
275   let Inst{14-12} = B{5-3};
276   let Inst{11-6} = U6;
277   let Inst{5-0} = A;
280 // 2-register, signed 12-bit immediate Dual Operand instruction.
281 // This instruction uses B as the first 2 operands (i.e., add B, B, -128). 
282 // |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|
283 // |B[2-0]  | 1| 0|            subop| F|B[5-3]  |S12[5-0]     |S12[11-6]  |
284 class F32_DOP_RS12<bits<5> major, bits<6> subop, bit F, dag outs, dag ins,
285                    string asmstr, list<dag> pattern> :
286   InstARC<4, outs, ins, asmstr, pattern> {
287   bits<6> B;
288   bits<12> S12;
289   
290   let Inst{31-27} = major;
291   let Inst{26-24} = B{2-0};
292   let Inst{23-22} = 0b10;
293   let Inst{21-16} = subop;
294   let Inst{15} = F;
295   let Inst{14-12} = B{5-3};
296   let Inst{11-6} = S12{5-0};
297   let Inst{5-0} = S12{11-6};
300 // 2-register, 32-bit immediate (LImm) Dual Operand instruction.
301 // This instruction has the 32-bit immediate in bits 32-63, and
302 // 62 in the C register operand slot, but is otherwise F32_DOP_RR.
303 class F32_DOP_RLIMM<bits<5> major, bits<6> subop, bit F, dag outs, dag ins,
304                     string asmstr, list<dag> pattern> :
305   InstARC<8, outs, ins, asmstr, pattern> {
306   bits<6> B;
307   bits<6> A;
308   bits<32> LImm;
310   let Inst{63-32} = LImm;
311   let Inst{31-27} = major;
312   let Inst{26-24} = B{2-0};
313   let Inst{23-22} = 0b00;
314   let Inst{21-16} = subop;
315   let Inst{15} = F;
316   let Inst{14-12} = B{5-3};
317   let Inst{11-6} = 0b111110;
318   let Inst{5-0} = A;
322 // Load and store instructions.
323 // In addition to the previous naming conventions, load and store instructions
324 // have:
325 // di - Uncached bit.  When set, loads/stores bypass the cache and access
326 //      memory directly.
327 // aa - Incrementing mode.  Loads and stores can write-back address pre- or
328 //      post- memory operation.
329 // zz - Memory size (can be 8/16/32 bit load/store).
330 //  x - Sign-extending.  When set, short loads can be sign-extended to 32-bits.
331 // Loads and Stores support different memory addressing modes:
332 // Base Register + Signed 9-bit Immediate: Both Load/Store.
333 // LImm: Both Load/Store (Load/Store from a fixed 32-bit address).
334 // Register + Register: Load Only.
335 // Register + LImm: Load Only.
337 // Register + S9 Load. (B + S9)
338 // |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|
339 // |B[2-0]  |S9[7-0]                |S9[8]|B[5-3]  |di|aa  |zz |x|A          |
340 class F32_LD_RS9<bit x, bits<2> aa, bit di, bits<2> zz, dag outs, dag ins,
341                  string asmstr, list<dag> pattern> :
342   InstARC<4, outs, ins, asmstr, pattern> {
343   bits<6> B;
344   bits<6> A;
345   bits<9> S9;
347   let Inst{31-27} = 0b00010;
348   let Inst{26-24} = B{2-0};
349   let Inst{23-16} = S9{7-0};
350   let Inst{15} = S9{8};
351   let Inst{14-12} = B{5-3};
352   let Inst{11} = di;
353   let Inst{10-9} = aa;
354   let Inst{8-7} = zz;
355   let Inst{6} = x;
356   let Inst{5-0} = A;
359 class F32_LD_ADDR<bit x, bits<2> aa, bit di, bits<2> zz, dag outs, dag ins,
360                   string asmstr, list<dag> pattern> :
361   F32_LD_RS9<x, aa, di, zz, outs, ins, asmstr, pattern> {
362   bits<15> addr;
364   let B = addr{14-9};
365   let S9 = addr{8-0};
369 // LImm Load.  The 32-bit immediate address is in Inst[63-32].
370 // |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|
371 // | 1| 1| 0| 0                        | 1| 1| 1|di| 0|0|zz |x|A          |
372 class F32_LD_LIMM<bit x, bit di, bits<2> zz, dag outs, dag ins,
373                   string asmstr, list<dag> pattern> :
374   InstARC<8, outs, ins, asmstr, pattern> {
375   bits<6> LImmReg = 0b111110;
376   bits<6> A;
377   bits<32> LImm;
379   let Inst{63-32} = LImm;
380   let Inst{31-27} = 0b00010;
381   let Inst{26-24} = LImmReg{2-0};
382   let Inst{23-15} = 0;
383   let Inst{14-12} = LImmReg{5-3};
384   let Inst{11} = di;
385   let Inst{10-9} = 0;
386   let Inst{8-7} = zz;
387   let Inst{6} = x;
388   let Inst{5-0} = A;
389   let DecoderMethod = "DecodeLdLImmInstruction";
392 // Register + LImm load.  The 32-bit immediate address is in Inst[63-32].
393 // |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|
394 // |B[2-0]  |aa   | 1| 1| 0|zz   | x|di|B[5-3]  | 1| 1|1|1|1|0|A          |
395 class F32_LD_RLIMM<bit x, bits<2> aa, bit di, bits<2> zz, dag outs, dag ins,
396                    string asmstr, list<dag> pattern> :
397   InstARC<8, outs, ins, asmstr, pattern> {
398   bits<6> LImmReg = 0b111110;
399   bits<32> LImm;
400   bits<6> B;
401   bits<6> A;
402   bits<38> addr;
403   let B = addr{37-32};
404   let LImm = addr{31-0};
406   let Inst{63-32} = LImm;
407   let Inst{31-27} = 0b00100;
408   let Inst{26-24} = B{2-0};
409   let Inst{23-22} = aa;
410   let Inst{21-19} = 0b110;
411   let Inst{18-17} = zz;
412   let Inst{16} = x;
413   let Inst{15} = di;
414   let Inst{14-12} = B{5-3};
415   let Inst{11-6} = LImmReg;
416   let Inst{5-0} = A;
417   let DecoderMethod = "DecodeLdRLImmInstruction";
420 // Register + S9 Store. (B + S9)
421 // |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|
422 // |B[2-0]  |S9[7-0]                |S9[8]|B[5-3]  |C            |di|aa |zz |0|
423 class F32_ST_RS9<bits<2> aa, bit di, bits<2> zz, dag outs, dag ins,
424                  string asmstr, list<dag> pattern> :
425   InstARC<4, outs, ins, asmstr, pattern> {
426   bits<6> B;
427   bits<6> C;
428   bits<9> S9;
430   let Inst{31-27} = 0b00011;
431   let Inst{26-24} = B{2-0};
432   let Inst{23-16} = S9{7-0};
433   let Inst{15} = S9{8};
434   let Inst{14-12} = B{5-3};
435   let Inst{11-6} = C;
436   let Inst{5} = di;
437   let Inst{4-3} = aa;
438   let Inst{2-1} = zz;
439   let Inst{0} = 0;
442 class F32_ST_ADDR<bits<2> aa, bit di, bits<2> zz, dag outs, dag ins,
443                   string asmstr, list<dag> pattern> :
444   F32_ST_RS9<aa, di, zz, outs, ins, asmstr, pattern> {
445   bits<15> addr;
447   let B = addr{14-9};
448   let S9 = addr{8-0};
451 // LImm Store.
452 // |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|
453 // | 1| 1| 0| 0                        | 1| 1| 1|C            |di|0|0|zz |0|
454 class F32_ST_LIMM<bit di, bits<2> zz, dag outs, dag ins,
455                   string asmstr, list<dag> pattern> :
456   InstARC<8, outs, ins, asmstr, pattern> {
457   bits<6> LImmReg = 0b111110;
458   bits<6> C;
459   bits<32> LImm;
461   let Inst{63-32} = LImm;
462   let Inst{31-27} = 0b00011;
463   let Inst{26-24} = LImmReg{2-0};
464   let Inst{23-15} = 0;
465   let Inst{14-12} = LImmReg{5-3};
466   let Inst{11-6} = C;
467   let Inst{5} = di;
468   let Inst{4-3} = 0;
469   let Inst{2-1} = zz;
470   let Inst{0} = 0;
471   let DecoderMethod = "DecodeStLImmInstruction";
474 // Compact Move/Load.
475 // |10|9|8|7|6|5|4|3|2|1|0|
476 // |      |h    |   |i|H  |
477 class F16_COMPACT<bits<1> i, dag outs, dag ins,
478                  string asmstr> :
479   InstARC<2, outs, ins, asmstr, []> {
481   bits<5> h;
483   let Inst{15-11} = 0b01000;
484   let Inst{7-5} = h{2-0};
485   let Inst{2} = i;
486   let Inst{1-0} = h{4-3};  
489 // Compact Load/Add/Sub.
490 class F16_LD_ADD_SUB<dag outs, dag ins, string asmstr> :
491   InstARC<2, outs, ins, asmstr, []> {
493   bits<3> b;  
494   let Inst{15-11} = 0b01001;
495   let Inst{10-8} = b;
498 class F16_LD_SUB<bit i, string asmstr> :
499   F16_LD_ADD_SUB<(outs GPR32:$a), (ins GPR32:$b, GPR32:$c),
500   asmstr> {
502   bits<3> a;
503   bits<3> c;
505   let Inst{7-5} = c;
506   let Inst{4} = i;
507   let Inst{3} = 0;
508   let Inst{2-0} = a;
511 class F16_ADD :
512   F16_LD_ADD_SUB<(outs GPR32:$r), (ins GPR32:$b, immU<6>:$u6),
513   "add_s\t$r, $b, $u6"> {
514   
515   bit r;
516   bits<6> u6;
517   
518   let Inst{7} = r;
519   let Inst{6-4} = u6{5-3};
520   let Inst{3} = 1;
521   let Inst{2-0} = u6{2-0};
524 // Compact Load/Store.
525 class F16_LD_ST_1<dag outs, dag ins, string asmstr> :
526   InstARC<2, outs, ins, asmstr, []> {
528   let Inst{15-11} = 0b01010;
531 class F16_LD_ST_s11<bit i, string asmstr> :
532   F16_LD_ST_1<(outs), (ins immS<11>:$s11), asmstr> {
534   bits<11> s11;
536   let Inst{10-5} = s11{10-5};
537   let Inst{4} = i;
538   let Inst{3} = 0;
539   let Inst{2-0} = s11{4-2};
540   let s11{1-0} = 0b00;
543 class F16_LDI_u7 :
544   F16_LD_ST_1<(outs GPR32:$b), (ins immU<7>:$u7),
545   "ldi_s\t$b, [$u7]"> {
547   bits<3> b;
548   bits<7> u7;
549   
550   let Inst{10-8} = b;
551   let Inst{7-4} = u7{6-3};
552   let Inst{3} = 1;
553   let Inst{2-0} = u7{2-0};
556 // Indexed Jump or Execute.
557 class F16_JLI_EI<bit i, string asmstr> :
558   InstARC<2, (outs), (ins immU<10>:$u10),
559   !strconcat(asmstr, "\t$u10"), []> {
561   bits<10> u10;
562   
563   let Inst{15-11} = 0b01011;
564   let Inst{10} = i;
565   let Inst{9-0} = u10;
568 // Load/Add Register-Register.
569 class F16_LD_ADD_RR<bits<2> i, string asmstr> :
570   InstARC<2, (outs GPR32:$a), (ins GPR32:$b, GPR32:$c),
571   asmstr, []> {
573   bits<3> a;
574   bits<3> b; 
575   bits<3> c;
577   let Inst{15-11} = 0b01100;
578   let Inst{10-8} = b;
579   let Inst{7-5} = c;
580   let Inst{4-3} = i;
581   let Inst{2-0} = a;
584 // Load/Add GP-Relative.
585 class F16_GP_LD_ADD<bits<2> i, dag ins, string asmstr> :
586   InstARC<2, (outs), ins, asmstr, []> {
588   let Inst{15-11} = 0b11001;
589   let Inst{10-9} = i;
592 // Add/Sub/Shift Register-Immediate.
593 // |10|9|8|7|6|5|4|3|2|1|0|
594 // |b     |c    |i  |u    |
595 class F16_ADD_IMM<bits<2> i, string asmstr> :
596   InstARC<2, (outs GPR32:$c), (ins GPR32:$b, immU<3>:$u3),
597   !strconcat(asmstr, "\t$c, $b, $u3"), []> {
599   bits<3> b;
600   bits<3> c;
601   bits<3> u3;
602   
603   let Inst{15-11} = 0b01101;
604   let Inst{10-8} = b;
605   let Inst{7-5} = c;
606   let Inst{4-3} = i;
607   let Inst{2-0} = u3;
610 // Dual Register Operations.
611 // |10|9|8|7|6|5|4|3|2|1|0|
612 // |b/s   |h    |i    |H  |
613 class F16_OP_HREG<bits<3> i, dag outs, dag ins, string asmstr> :
614   InstARC<2, outs, ins, asmstr, []> {
616   bits<3> b_s3;
617   bits<5> h;
619   let Inst{15-11} = 0b01110;
620   let Inst{10-8} = b_s3;
621   let Inst{7-5} = h{2-0};
622   let Inst{4-2} = i;
623   let Inst{1-0} = h{4-3};
626 class F16_OP_HREG30<bits<3> i, dag outs, dag ins, string asmstr> :
627   F16_OP_HREG<i, outs, ins, asmstr> {
628     
629   bits<5> LImmReg = 0b11110;  
630   let Inst{7-5} = LImmReg{2-0};
631   let Inst{1-0} = LImmReg{4-3};
634 class F16_OP_HREG_LIMM<bits<3> i, dag outs, dag ins, string asmstr> :
635   F16_OP_HREG30<i, outs, ins, asmstr> {
637   bits<32> LImm;
638   let Inst{47-16} = LImm;
639   let Size = 6;
642 // General compact DOP format.
643 class F16_GEN_DOP_BASE<bits<5> i, dag outs, dag ins, string asmstr> :
644   InstARC<2, outs, ins, asmstr, []> {
646   bits<3> b;
647   bits<3> c;
648   let Inst{15-11} = 0b01111;
649   let Inst{10-8} = b;
650   let Inst{7-5} = c;
651   let Inst{4-0} = i;
654 class F16_GEN_DOP<bits<5> i, string asmstr> :
655   F16_GEN_DOP_BASE<i, (outs GPR32:$b), (ins GPR32:$c),
656   !strconcat(asmstr, "\t$b, $b, $c")>;
658 class F16_GEN_DOP_NODST<bits<5> i, string asmstr> :
659   F16_GEN_DOP_BASE<i, (outs), (ins GPR32:$b, GPR32:$c),
660   !strconcat(asmstr, "\t$b, $c")>;
662 class F16_GEN_DOP_SINGLESRC<bits<5> i, string asmstr> :
663   F16_GEN_DOP_BASE<i, (outs GPR32:$b), (ins GPR32:$c),
664   !strconcat(asmstr, "\t$b, $c")>;
666 class F16_GEN_SOP_BASE<bits<3> i, dag outs, dag ins, string asmstr> :
667   F16_GEN_DOP_BASE<0b00000, outs, ins, asmstr> {
669   let c = i;
672 class F16_GEN_SOP<bits<3> i, string asmstr> :
673   F16_GEN_SOP_BASE<i, (outs), (ins GPR32:$b), asmstr>;
675 class F16_GEN_ZOP<bits<3> i, string asmstr> :
676   F16_GEN_SOP_BASE<0b111, (outs), (ins), asmstr> {
678   let b = i;
681 // Compact Load/Store with Offset Format.
682 class F16_LD_ST_OFF<bits<5> opc, dag outs, dag ins, string asmstr> :
683   InstARC<2, outs, ins, !strconcat(asmstr, "\t$c, [$b, $off]"), []> {
685   bits<3> b;
686   bits<3> c;
687   let Inst{15-11} = opc;
688   let Inst{10-8} = b;
689   let Inst{7-5} = c;
692 class F16_LD_ST_WORD_OFF<bits<5> opc, dag outs, dag ins, string asmstr> :
693   F16_LD_ST_OFF<opc, outs, ins, asmstr> {
695   bits<7> off;
696   let Inst{4-0} = off{6-2};
697   let off{1-0} = 0b00;
700 class F16_LD_ST_HALF_OFF<bits<5> opc, dag outs, dag ins, string asmstr> :
701   F16_LD_ST_OFF<opc, outs, ins, asmstr> {
703   bits<6> off;
704   let Inst{4-0} = off{5-1};
705   let off{0} = 0b0;
708 class F16_LD_ST_BYTE_OFF<bits<5> opc, dag outs, dag ins, string asmstr> :
709   F16_LD_ST_OFF<opc, outs, ins, asmstr> {
711   bits<5> off;
712   let Inst{4-0} = off;
715 // Shift/Subtract/Bit Immediate.
716 // |10|9|8|7|6|5|4|3|2|1|0|
717 // |b     |i    |u        |
718 class F16_SH_SUB_BIT<bits<3> i, string asmstr> :
719   InstARC<2, (outs), (ins GPR32:$b, immU<5>:$u5), asmstr, []> {
721   bits<3> b;
722   bits<5> u5;
723   
724   let Inst{15-11} = 0b10111;
725   let Inst{10-8} = b;
726   let Inst{7-5} = i;
727   let Inst{4-0} = u5;
730 class F16_SH_SUB_BIT_DST<bits<3> i, string asmstr> :
731   F16_SH_SUB_BIT<i, !strconcat(asmstr, "\t$b, $b, $u5")>;
733 // 16-bit stack-based operations.
734 // |10|9|8|7|6|5|4|3|2|1|0|
735 // |b     |i    |u        |
736 class F16_SP_OPS<bits<3> i,
737   dag outs, dag ins, string asmstr> :
738   InstARC<2, outs, ins, asmstr, []> {
740   bits<3> fieldB;
741   bits<5> fieldU;
743   let Inst{15-11} = 0b11000;
744   let Inst{10-8} = fieldB;
745   let Inst{7-5} = i;
746   let Inst{4-0} = fieldU;
749 class F16_SP_OPS_u7_aligned<bits<3> i,
750   dag outs, dag ins, string asmstr> :
751   F16_SP_OPS<i, outs, ins, asmstr> {
753   bits<3> b3;
754   bits<7> u7;
755   
756   let fieldB = b3;
757   let fieldU = u7{6-2};
758   let u7{1-0} = 0b00;
761 class F16_SP_OPS_bconst<bits<3> b, string asmop> :
762   F16_SP_OPS_u7_aligned<0b101,
763   (outs), (ins immU<7>:$u7),
764   !strconcat(asmop, "\t%sp, %sp, $u7")> {
765   
766   let fieldB = b;
769 class F16_SP_OPS_uconst<bits<3> i,
770   dag outs, dag ins, string asmop> :
771   F16_SP_OPS_u7_aligned<i, outs, ins,
772   !strconcat(asmop, "\t$b3")> {
773   
774   let fieldU = 0b00001;
777 class F16_SP_OPS_buconst<bits<3> i, string asmop> :
778   F16_SP_OPS_u7_aligned<i, (outs), (ins),
779     !strconcat(asmop, "\t%blink")> {
780   
781   let fieldB = 0x000;
782   let fieldU = 0b10001;
785 class F16_SP_LD<bits<3> i, string asmop> : F16_SP_OPS_u7_aligned<i,
786                          (outs GPR32Reduced:$b3), (ins immU<7>:$u7),
787                          !strconcat(asmop, "\t$b3, [%sp, $u7]")>;
789 class F16_SP_ST<bits<3> i, string asmop> : F16_SP_OPS_u7_aligned<i,
790                          (outs), (ins GPR32Reduced:$b3, immU<7>:$u7),
791                          !strconcat(asmop, "\t$b3, [%sp, $u7]")>;
793 // Compact MOV/ADD/CMP Immediate Format.
794 class F16_OP_IMM<bits<5> opc, dag outs, dag ins, string asmstr> :
795   InstARC<2, outs, ins, asmstr, []> {
797   bits<3> b;
798   let Inst{15-11} = opc;
799   let Inst{10-8} = b;
802 class F16_OP_U7<bit i, string asmstr> :
803   F16_OP_IMM<0b11100, (outs GPR32:$b), (ins immU<7>:$u7), asmstr> {
805   bits<7> u7;
806   let Inst{7} = i;
807   let Inst{6-0} = u7;
810 // Special types for different instruction operands.
811 def cmovpred : Operand<i32>, PredicateOp,
812                ComplexPattern<i32, 2, "SelectCMOVPred"> {
813   let MIOperandInfo = (ops i32imm, i32imm);
814   let PrintMethod = "printPredicateOperand";
817 def ccond : Operand<i32> {
818   let MIOperandInfo = (ops i32imm);
819   let PrintMethod = "printPredicateOperand";
822 def brccond : Operand<i32> {
823   let MIOperandInfo = (ops i32imm);
824   let PrintMethod = "printBRCCPredicateOperand";
827 // Branch/call targets of different offset sizes.
828 class BCTarget<ValueType vt> : Operand<vt> {
829   let OperandType = "OPERAND_PCREL";
832 def btarget : BCTarget<OtherVT>;
834 class BCTargetSigned<ValueType vt, int BSz> : BCTarget<vt> {
835   let DecoderMethod = "DecodeBranchTargetS<"#BSz#">";
838 class BranchTargetS<int BSz> : BCTargetSigned<OtherVT, BSz>;
839 def btargetS7 : BranchTargetS<7>;
840 def btargetS8 : BranchTargetS<8>;
841 def btargetS9 : BranchTargetS<9>;
842 def btargetS10 : BranchTargetS<10>;
843 def btargetS13 : BranchTargetS<13>;
844 def btargetS21 : BranchTargetS<21>;
845 def btargetS25 : BranchTargetS<25>;
847 class CallTargetS<int BSz> : BCTargetSigned<i32, BSz>;
848 def calltargetS25: CallTargetS<25>;
850 // Compact Branch on Compare Register with Zero.
851 class F16_BCC_REG<bit i, string asmstr> :
852   InstARC<2, (outs), (ins GPR32:$b, btargetS8:$s8),
853   !strconcat(asmstr, "\t$b, 0, $s8"), []> {
855   bits<3> b;
856   bits<8> s8;
858   let Inst{15-11} = 0b11101;
859   let Inst{10-8} = b;
860   let Inst{7} = i;
861   let Inst{6-0} = s8{7-1};
862   let s8{0} = 0b0;
865 // Compact Branch Conditionally Format.
866 class F16_BCC<bits<2> i, dag ins, string asmstr> :
867   InstARC<2, (outs), ins, asmstr, []> {
869   let Inst{15-11} = 0b11110;
870   let Inst{10-9} = i;
873 class F16_BCC_s10<bits<2> i, string asmstr> :
874   F16_BCC<i, (ins btargetS10:$s),
875   !strconcat(asmstr, "\t$s")> {
877   bits<10> s;
878   let Inst{8-0} = s{9-1};
879   let s{0} = 0b0;
882 class F16_BCC_s7<bits<3> i, string asmstr> :
883   F16_BCC<0b11, (ins btargetS7:$s),
884   !strconcat(asmstr, "\t$s")> {
886   bits<7> s;
887   let Inst{8-6} = i;
888   let Inst{5-0} = s{6-1};
889   let s{0} = 0b0;