1 //===- ARCInstrFormats.td - ARC Instruction Formats --------*- tablegen -*-===//
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
7 //===----------------------------------------------------------------------===//
9 //===----------------------------------------------------------------------===//
10 // Instruction format superclass
11 //===----------------------------------------------------------------------===//
15 field bits<64> SoftFail = 0;
20 class immU<int BSz> : Operand<i32>, PatLeaf<(imm),
21 "\n return isUInt<"#BSz#">(N->getSExtValue());"> {
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 // Helper classes for load/store instructions
59 class DataSizeMode<bits<2> mode, string instSfx, string asmSfx> {
61 string InstSuffix = instSfx;
62 string AsmSuffix = asmSfx;
64 class ExtMode<bit mode, string instSfx, string asmSfx> {
66 string InstSuffix = instSfx;
67 string AsmSuffix = asmSfx;
70 class AddrMode<bits<2> mode, string instSfx, string asmSfx> {
72 string InstSuffix = instSfx;
73 string AsmSuffix = asmSfx;
76 class CacheMode<bit mode, string instSfx, string asmSfx> {
78 string InstSuffix = instSfx;
79 string AsmSuffix = asmSfx;
82 def ByteSM : DataSizeMode<0b01, "B", "b">;
83 def HalfSM : DataSizeMode<0b10, "H", "h">;
84 def WordSM : DataSizeMode<0b00, "", "">;
86 def NoEM : ExtMode<0, "", "">;
87 def SignedEM : ExtMode<1, "_X", ".x">;
89 def NoAM : AddrMode<0b00, "", "">;
90 def PreIncAM : AddrMode<0b01, "_AW", ".aw">;
91 def PostIncAM : AddrMode<0b10, "_AB", ".ab">;
93 def NoCC : CacheMode<0b0, "", "">;
94 def UncachedCC : CacheMode<0b1, "_DI", ".di">;
96 class InstARC<int sz, dag outs, dag ins, string asmstr, list<dag> pattern>
97 : Instruction, Encoding64 {
99 let Namespace = "ARC";
100 dag OutOperandList = outs;
101 dag InOperandList = ins;
102 let AsmString = asmstr;
103 let Pattern = pattern;
106 // Load/Store instruction properties
107 DataSizeMode ZZ = WordSM;
112 // Field used for relation models
113 string BaseOpcode = "";
116 let TSFlags{1-0} = AA.Value;
119 // ARC pseudo instructions format
120 class PseudoInstARC<dag outs, dag ins, string asmstr, list<dag> pattern>
121 : InstARC<0, outs, ins, asmstr, pattern> {
125 //===----------------------------------------------------------------------===//
126 // Instruction formats
127 //===----------------------------------------------------------------------===//
129 // All 32-bit ARC instructions have a 5-bit "major" opcode class designator
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.
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).
154 // Branch Instructions.
155 class F32_BR<bits<5> major, dag outs, dag ins, bit b16, string asmstr,
157 InstARC<4, outs, ins, asmstr, pattern> {
160 let Inst{31-27} = major;
165 class F32_BR_COND<bits<5> major, dag outs, dag ins, bit b16, string asmstr,
167 F32_BR<major, outs, ins, b16, asmstr, pattern> {
168 bits<21> S21; // 2-byte aligned 21-bit byte-offset.
170 let Inst{26-18} = S21{10-2};
171 let Inst{15-6} = S21{20-11};
175 class F32_BR_UCOND_FAR<bits<5> major, dag outs, dag ins, bit b16, string asmstr,
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};
182 let Inst{3-0} = S25{24-21};
185 class 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};
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]|
193 class 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};
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]|
201 class 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> {
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 |
209 class F32_BR1_BL_COND<dag outs, dag ins, string asmstr, list<dag> pat> :
210 F32_BR_COND<0b00001, outs, ins, 0, asmstr, pat> {
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 |
219 class F32_BR1_BCC<dag outs, dag ins, string asmstr, bit IsU6,
221 InstARC<4, outs, ins, asmstr, pattern> {
227 bits<9> S9; // 2-byte aligned 9-bit byte-offset.
229 let Inst{31-27} = 0b00001;
230 let Inst{26-24} = B{2-0};
231 let Inst{23-17} = S9{7-1};
233 let Inst{15} = S9{8};
234 let Inst{14-12} = B{5-3};
242 // General operations instructions.
243 // Single Operand Instructions. Inst[5-0] specifies the specific operation
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 |
247 class 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> {
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;
259 let Inst{14-12} = B{5-3};
261 let Inst{5-0} = subop;
264 // Dual Operand Instructions. Inst[21-16] specifies the specific operation
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 |
270 class 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> {
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;
282 let Inst{14-12} = B{5-3};
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 |
291 class 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> {
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;
303 let Inst{14-12} = B{5-3};
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 |
313 class 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> {
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;
325 let Inst{14-12} = B{5-3};
330 // 2-register, signed 12-bit immediate Dual Operand instruction.
331 // This instruction uses B as the first 2 operands (i.e., add B, B, -128).
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| 0| subop| F|B[5-3] |S12[5-0] |S12[11-6] |
334 class F32_DOP_RS12<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> {
340 let Inst{31-27} = major;
341 let Inst{26-24} = B{2-0};
342 let Inst{23-22} = 0b10;
343 let Inst{21-16} = subop;
345 let Inst{14-12} = B{5-3};
346 let Inst{11-6} = S12{5-0};
347 let Inst{5-0} = S12{11-6};
350 // 2-register, 32-bit immediate (LImm) Dual Operand instruction.
351 // This instruction has the 32-bit immediate in bits 32-63, and
352 // 62 in the C register operand slot, but is otherwise F32_DOP_RR.
353 class F32_DOP_RLIMM<bits<5> major, bits<6> subop, bit F, dag outs, dag ins,
354 string asmstr, list<dag> pattern> :
355 InstARC<8, outs, ins, asmstr, pattern> {
360 let Inst{63-32} = LImm;
361 let Inst{31-27} = major;
362 let Inst{26-24} = B{2-0};
363 let Inst{23-22} = 0b00;
364 let Inst{21-16} = subop;
366 let Inst{14-12} = B{5-3};
367 let Inst{11-6} = 0b111110;
372 // Load and store instructions.
373 // In addition to the previous naming conventions, load and store instructions
375 // di - Uncached bit. When set, loads/stores bypass the cache and access
377 // aa - Incrementing mode. Loads and stores can write-back address pre- or
378 // post- memory operation.
379 // zz - Memory size (can be 8/16/32 bit load/store).
380 // x - Sign-extending. When set, short loads can be sign-extended to 32-bits.
381 // Loads and Stores support different memory addressing modes:
382 // Base Register + Signed 9-bit Immediate: Both Load/Store.
383 // LImm: Both Load/Store (Load/Store from a fixed 32-bit address).
384 // Register + Register: Load Only.
385 // Register + LImm: Load Only.
387 // Register + S9 Load. (B + S9)
388 // |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|
389 // |B[2-0] |S9[7-0] |S9[8]|B[5-3] |di|aa |zz |x|A |
390 class F32_LD_RS9<bit x, bits<2> aa, bit di, bits<2> zz, dag outs, dag ins,
391 string asmstr, list<dag> pattern> :
392 InstARC<4, outs, ins, asmstr, pattern> {
397 let Inst{31-27} = 0b00010;
398 let Inst{26-24} = B{2-0};
399 let Inst{23-16} = S9{7-0};
400 let Inst{15} = S9{8};
401 let Inst{14-12} = B{5-3};
408 let BaseOpcode = "ld_rs9";
411 class F32_LD_ADDR<bit x, bits<2> aa, bit di, bits<2> zz, dag outs, dag ins,
412 string asmstr, list<dag> pattern> :
413 F32_LD_RS9<x, aa, di, zz, outs, ins, asmstr, pattern> {
419 let BaseOpcode = "ld_rs9";
423 // LImm Load. The 32-bit immediate address is in Inst[63-32].
424 // |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|
425 // | 1| 1| 0| 0 | 1| 1| 1|di| 0|0|zz |x|A |
426 class F32_LD_LIMM<bit x, bit di, bits<2> zz, dag outs, dag ins,
427 string asmstr, list<dag> pattern> :
428 InstARC<8, outs, ins, asmstr, pattern> {
429 bits<6> LImmReg = 0b111110;
433 let Inst{63-32} = LImm;
434 let Inst{31-27} = 0b00010;
435 let Inst{26-24} = LImmReg{2-0};
437 let Inst{14-12} = LImmReg{5-3};
443 let DecoderMethod = "DecodeLdLImmInstruction";
445 let BaseOpcode = "ld_limm";
448 // Register + LImm load. The 32-bit immediate address is in Inst[63-32].
449 // |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|
450 // |B[2-0] |aa | 1| 1| 0|zz | x|di|B[5-3] | 1| 1|1|1|1|0|A |
451 class F32_LD_RLIMM<bit x, bits<2> aa, bit di, bits<2> zz, dag outs, dag ins,
452 string asmstr, list<dag> pattern> :
453 InstARC<8, outs, ins, asmstr, pattern> {
454 bits<6> LImmReg = 0b111110;
460 let LImm = addr{31-0};
462 let Inst{63-32} = LImm;
463 let Inst{31-27} = 0b00100;
464 let Inst{26-24} = B{2-0};
465 let Inst{23-22} = aa;
466 let Inst{21-19} = 0b110;
467 let Inst{18-17} = zz;
470 let Inst{14-12} = B{5-3};
471 let Inst{11-6} = LImmReg;
473 let DecoderMethod = "DecodeLdRLImmInstruction";
475 let BaseOpcode = "ld_rlimm";
478 // Register + S9 Store. (B + S9)
479 // |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|
480 // |B[2-0] |S9[7-0] |S9[8]|B[5-3] |C |di|aa |zz |0|
481 class F32_ST_RS9<bits<2> aa, bit di, bits<2> zz, dag outs, dag ins,
482 string asmstr, list<dag> pattern> :
483 InstARC<4, outs, ins, asmstr, pattern> {
488 let Inst{31-27} = 0b00011;
489 let Inst{26-24} = B{2-0};
490 let Inst{23-16} = S9{7-0};
491 let Inst{15} = S9{8};
492 let Inst{14-12} = B{5-3};
499 let BaseOpcode = "st_rs9";
502 class F32_ST_ADDR<bits<2> aa, bit di, bits<2> zz, dag outs, dag ins,
503 string asmstr, list<dag> pattern> :
504 F32_ST_RS9<aa, di, zz, outs, ins, asmstr, pattern> {
510 let BaseOpcode = "st_rs9";
514 // |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|
515 // | 1| 1| 0| 0 | 1| 1| 1|C |di|0|0|zz |0|
516 class F32_ST_LIMM<bit di, bits<2> zz, dag outs, dag ins,
517 string asmstr, list<dag> pattern> :
518 InstARC<8, outs, ins, asmstr, pattern> {
519 bits<6> LImmReg = 0b111110;
523 let Inst{63-32} = LImm;
524 let Inst{31-27} = 0b00011;
525 let Inst{26-24} = LImmReg{2-0};
527 let Inst{14-12} = LImmReg{5-3};
533 let DecoderMethod = "DecodeStLImmInstruction";
535 let BaseOpcode = "st_limm";
538 // Compact Move/Load.
539 // |10|9|8|7|6|5|4|3|2|1|0|
541 class F16_COMPACT<bits<1> i, dag outs, dag ins,
543 InstARC<2, outs, ins, asmstr, []> {
547 let Inst{15-11} = 0b01000;
548 let Inst{7-5} = h{2-0};
550 let Inst{1-0} = h{4-3};
553 // Compact Load/Add/Sub.
554 class F16_LD_ADD_SUB<dag outs, dag ins, string asmstr> :
555 InstARC<2, outs, ins, asmstr, []> {
558 let Inst{15-11} = 0b01001;
562 class F16_LD_SUB<bit i, string asmstr> :
563 F16_LD_ADD_SUB<(outs GPR32:$a), (ins GPR32:$b, GPR32:$c),
576 F16_LD_ADD_SUB<(outs GPR32:$r), (ins GPR32:$b, immU<6>:$u6),
577 "add_s\t$r, $b, $u6"> {
583 let Inst{6-4} = u6{5-3};
585 let Inst{2-0} = u6{2-0};
588 // Compact Load/Store.
589 class F16_LD_ST_1<dag outs, dag ins, string asmstr> :
590 InstARC<2, outs, ins, asmstr, []> {
592 let Inst{15-11} = 0b01010;
595 class F16_LD_ST_s11<bit i, string asmstr> :
596 F16_LD_ST_1<(outs), (ins immS<11>:$s11), asmstr> {
600 let Inst{10-5} = s11{10-5};
603 let Inst{2-0} = s11{4-2};
608 F16_LD_ST_1<(outs GPR32:$b), (ins immU<7>:$u7),
609 "ldi_s\t$b, [$u7]"> {
615 let Inst{7-4} = u7{6-3};
617 let Inst{2-0} = u7{2-0};
620 // Indexed Jump or Execute.
621 class F16_JLI_EI<bit i, string asmstr> :
622 InstARC<2, (outs), (ins immU<10>:$u10),
623 !strconcat(asmstr, "\t$u10"), []> {
627 let Inst{15-11} = 0b01011;
632 // Load/Add Register-Register.
633 class F16_LD_ADD_RR<bits<2> i, string asmstr> :
634 InstARC<2, (outs GPR32:$a), (ins GPR32:$b, GPR32:$c),
641 let Inst{15-11} = 0b01100;
648 // Load/Add GP-Relative.
649 class F16_GP_LD_ADD<bits<2> i, dag ins, string asmstr> :
650 InstARC<2, (outs), ins, asmstr, []> {
652 let Inst{15-11} = 0b11001;
656 // Add/Sub/Shift Register-Immediate.
657 // |10|9|8|7|6|5|4|3|2|1|0|
659 class F16_ADD_IMM<bits<2> i, string asmstr> :
660 InstARC<2, (outs GPR32:$c), (ins GPR32:$b, immU<3>:$u3),
661 !strconcat(asmstr, "\t$c, $b, $u3"), []> {
667 let Inst{15-11} = 0b01101;
674 // Dual Register Operations.
675 // |10|9|8|7|6|5|4|3|2|1|0|
677 class F16_OP_HREG<bits<3> i, dag outs, dag ins, string asmstr> :
678 InstARC<2, outs, ins, asmstr, []> {
683 let Inst{15-11} = 0b01110;
684 let Inst{10-8} = b_s3;
685 let Inst{7-5} = h{2-0};
687 let Inst{1-0} = h{4-3};
690 class F16_OP_HREG30<bits<3> i, dag outs, dag ins, string asmstr> :
691 F16_OP_HREG<i, outs, ins, asmstr> {
693 bits<5> LImmReg = 0b11110;
694 let Inst{7-5} = LImmReg{2-0};
695 let Inst{1-0} = LImmReg{4-3};
698 class F16_OP_HREG_LIMM<bits<3> i, dag outs, dag ins, string asmstr> :
699 F16_OP_HREG30<i, outs, ins, asmstr> {
702 let Inst{47-16} = LImm;
706 // General compact DOP format.
707 class F16_GEN_DOP_BASE<bits<5> i, dag outs, dag ins, string asmstr> :
708 InstARC<2, outs, ins, asmstr, []> {
712 let Inst{15-11} = 0b01111;
718 class F16_GEN_DOP<bits<5> i, string asmstr> :
719 F16_GEN_DOP_BASE<i, (outs GPR32:$b), (ins GPR32:$c),
720 !strconcat(asmstr, "\t$b, $b, $c")>;
722 class F16_GEN_DOP_NODST<bits<5> i, string asmstr> :
723 F16_GEN_DOP_BASE<i, (outs), (ins GPR32:$b, GPR32:$c),
724 !strconcat(asmstr, "\t$b, $c")>;
726 class F16_GEN_DOP_SINGLESRC<bits<5> i, string asmstr> :
727 F16_GEN_DOP_BASE<i, (outs GPR32:$b), (ins GPR32:$c),
728 !strconcat(asmstr, "\t$b, $c")>;
730 class F16_GEN_SOP_BASE<bits<3> i, dag outs, dag ins, string asmstr> :
731 F16_GEN_DOP_BASE<0b00000, outs, ins, asmstr> {
736 class F16_GEN_SOP<bits<3> i, string asmstr> :
737 F16_GEN_SOP_BASE<i, (outs), (ins GPR32:$b), asmstr>;
739 class F16_GEN_ZOP<bits<3> i, string asmstr> :
740 F16_GEN_SOP_BASE<0b111, (outs), (ins), asmstr> {
745 // Compact Load/Store with Offset Format.
746 class F16_LD_ST_OFF<bits<5> opc, dag outs, dag ins, string asmstr> :
747 InstARC<2, outs, ins, !strconcat(asmstr, "\t$c, [$b, $off]"), []> {
751 let Inst{15-11} = opc;
756 class F16_LD_ST_WORD_OFF<bits<5> opc, dag outs, dag ins, string asmstr> :
757 F16_LD_ST_OFF<opc, outs, ins, asmstr> {
760 let Inst{4-0} = off{6-2};
764 class F16_LD_ST_HALF_OFF<bits<5> opc, dag outs, dag ins, string asmstr> :
765 F16_LD_ST_OFF<opc, outs, ins, asmstr> {
768 let Inst{4-0} = off{5-1};
772 class F16_LD_ST_BYTE_OFF<bits<5> opc, dag outs, dag ins, string asmstr> :
773 F16_LD_ST_OFF<opc, outs, ins, asmstr> {
779 // Shift/Subtract/Bit Immediate.
780 // |10|9|8|7|6|5|4|3|2|1|0|
782 class F16_SH_SUB_BIT<bits<3> i, string asmstr> :
783 InstARC<2, (outs), (ins GPR32:$b, immU<5>:$u5), asmstr, []> {
788 let Inst{15-11} = 0b10111;
794 class F16_SH_SUB_BIT_DST<bits<3> i, string asmstr> :
795 F16_SH_SUB_BIT<i, !strconcat(asmstr, "\t$b, $b, $u5")>;
797 // 16-bit stack-based operations.
798 // |10|9|8|7|6|5|4|3|2|1|0|
800 class F16_SP_OPS<bits<3> i,
801 dag outs, dag ins, string asmstr> :
802 InstARC<2, outs, ins, asmstr, []> {
807 let Inst{15-11} = 0b11000;
808 let Inst{10-8} = fieldB;
810 let Inst{4-0} = fieldU;
813 class F16_SP_OPS_u7_aligned<bits<3> i,
814 dag outs, dag ins, string asmstr> :
815 F16_SP_OPS<i, outs, ins, asmstr> {
821 let fieldU = u7{6-2};
825 class F16_SP_OPS_bconst<bits<3> b, string asmop> :
826 F16_SP_OPS_u7_aligned<0b101,
827 (outs), (ins immU<7>:$u7),
828 !strconcat(asmop, "\t%sp, %sp, $u7")> {
833 class F16_SP_OPS_uconst<bits<3> i,
834 dag outs, dag ins, string asmop> :
835 F16_SP_OPS_u7_aligned<i, outs, ins,
836 !strconcat(asmop, "\t$b3")> {
838 let fieldU = 0b00001;
841 class F16_SP_OPS_buconst<bits<3> i, string asmop> :
842 F16_SP_OPS_u7_aligned<i, (outs), (ins),
843 !strconcat(asmop, "\t%blink")> {
846 let fieldU = 0b10001;
849 class F16_SP_LD<bits<3> i, string asmop> : F16_SP_OPS_u7_aligned<i,
850 (outs GPR32Reduced:$b3), (ins immU<7>:$u7),
851 !strconcat(asmop, "\t$b3, [%sp, $u7]")>;
853 class F16_SP_ST<bits<3> i, string asmop> : F16_SP_OPS_u7_aligned<i,
854 (outs), (ins GPR32Reduced:$b3, immU<7>:$u7),
855 !strconcat(asmop, "\t$b3, [%sp, $u7]")>;
857 // Compact MOV/ADD/CMP Immediate Format.
858 class F16_OP_IMM<bits<5> opc, dag outs, dag ins, string asmstr> :
859 InstARC<2, outs, ins, asmstr, []> {
862 let Inst{15-11} = opc;
866 class F16_OP_U7<bit i, string asmstr> :
867 F16_OP_IMM<0b11100, (outs GPR32:$b), (ins immU<7>:$u7), asmstr> {
874 // Special types for different instruction operands.
875 def cmovpred : Operand<i32>, PredicateOp,
876 ComplexPattern<i32, 2, "SelectCMOVPred"> {
877 let MIOperandInfo = (ops i32imm, i32imm);
878 let PrintMethod = "printPredicateOperand";
881 def ccond : Operand<i32> {
882 let MIOperandInfo = (ops i32imm);
883 let PrintMethod = "printPredicateOperand";
886 def brccond : Operand<i32> {
887 let MIOperandInfo = (ops i32imm);
888 let PrintMethod = "printBRCCPredicateOperand";
891 // Branch/call targets of different offset sizes.
892 class BCTarget<ValueType vt> : Operand<vt> {
893 let OperandType = "OPERAND_PCREL";
896 def btarget : BCTarget<OtherVT>;
898 class BCTargetSigned<ValueType vt, int BSz> : BCTarget<vt> {
899 let DecoderMethod = "DecodeBranchTargetS<"#BSz#">";
902 class BranchTargetS<int BSz> : BCTargetSigned<OtherVT, BSz>;
903 def btargetS7 : BranchTargetS<7>;
904 def btargetS8 : BranchTargetS<8>;
905 def btargetS9 : BranchTargetS<9>;
906 def btargetS10 : BranchTargetS<10>;
907 def btargetS13 : BranchTargetS<13>;
908 def btargetS21 : BranchTargetS<21>;
909 def btargetS25 : BranchTargetS<25>;
911 class CallTargetS<int BSz> : BCTargetSigned<i32, BSz>;
912 def calltargetS25: CallTargetS<25>;
914 // Compact Branch on Compare Register with Zero.
915 class F16_BCC_REG<bit i, string asmstr> :
916 InstARC<2, (outs), (ins GPR32:$b, btargetS8:$s8),
917 !strconcat(asmstr, "\t$b, 0, $s8"), []> {
922 let Inst{15-11} = 0b11101;
925 let Inst{6-0} = s8{7-1};
929 // Compact Branch Conditionally Format.
930 class F16_BCC<bits<2> i, dag ins, string asmstr> :
931 InstARC<2, (outs), ins, asmstr, []> {
933 let Inst{15-11} = 0b11110;
937 class F16_BCC_s10<bits<2> i, string asmstr> :
938 F16_BCC<i, (ins btargetS10:$s),
939 !strconcat(asmstr, "\t$s")> {
942 let Inst{8-0} = s{9-1};
946 class F16_BCC_s7<bits<3> i, string asmstr> :
947 F16_BCC<0b11, (ins btargetS7:$s),
948 !strconcat(asmstr, "\t$s")> {
952 let Inst{5-0} = s{6-1};