1 //==- SystemZInstrFormats.td - SystemZ Instruction Formats --*- tablegen -*-==//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 //===----------------------------------------------------------------------===//
11 // Basic SystemZ instruction definition
12 //===----------------------------------------------------------------------===//
14 class InstSystemZ<int size, dag outs, dag ins, string asmstr,
15 list<dag> pattern> : Instruction {
16 let Namespace = "SystemZ";
18 dag OutOperandList = outs;
19 dag InOperandList = ins;
21 let Pattern = pattern;
22 let AsmString = asmstr;
24 // Some instructions come in pairs, one having a 12-bit displacement
25 // and the other having a 20-bit displacement. Both instructions in
26 // the pair have the same DispKey and their DispSizes are "12" and "20"
29 string DispSize = "none";
31 // Many register-based <INSN>R instructions have a memory-based <INSN>
32 // counterpart. OpKey uniquely identifies <INSN>, while OpType is
33 // "reg" for <INSN>R and "mem" for <INSN>.
35 string OpType = "none";
37 // Many distinct-operands instructions have older 2-operand equivalents.
38 // NumOpsKey uniquely identifies one of these 2-operand and 3-operand pairs,
39 // with NumOpsValue being "2" or "3" as appropriate.
40 string NumOpsKey = "";
41 string NumOpsValue = "none";
43 // True if this instruction is a simple D(X,B) load of a register
44 // (with no sign or zero extension).
45 bit SimpleBDXLoad = 0;
47 // True if this instruction is a simple D(X,B) store of a register
48 // (with no truncation).
49 bit SimpleBDXStore = 0;
51 // True if this instruction has a 20-bit displacement field.
52 bit Has20BitOffset = 0;
54 // True if addresses in this instruction have an index register.
57 // True if this is a 128-bit pseudo instruction that combines two 64-bit
61 // The access size of all memory operands in bytes, or 0 if not known.
62 bits<5> AccessBytes = 0;
64 // If the instruction sets CC to a useful value, this gives the mask
65 // of all possible CC results. The mask has the same form as
69 // The subset of CCValues that have the same meaning as they would after
70 // a comparison of the first operand against zero.
71 bits<4> CompareZeroCCMask = 0;
73 // True if the instruction is conditional and if the CC mask operand
74 // comes first (as for BRC, etc.).
77 // Similar, but true if the CC mask operand comes last (as for LOC, etc.).
80 // True if the instruction is the "logical" rather than "arithmetic" form,
81 // in cases where a distinction exists.
84 let TSFlags{0} = SimpleBDXLoad;
85 let TSFlags{1} = SimpleBDXStore;
86 let TSFlags{2} = Has20BitOffset;
87 let TSFlags{3} = HasIndex;
88 let TSFlags{4} = Is128Bit;
89 let TSFlags{9-5} = AccessBytes;
90 let TSFlags{13-10} = CCValues;
91 let TSFlags{17-14} = CompareZeroCCMask;
92 let TSFlags{18} = CCMaskFirst;
93 let TSFlags{19} = CCMaskLast;
94 let TSFlags{20} = IsLogical;
97 //===----------------------------------------------------------------------===//
98 // Mappings between instructions
99 //===----------------------------------------------------------------------===//
101 // Return the version of an instruction that has an unsigned 12-bit
103 def getDisp12Opcode : InstrMapping {
104 let FilterClass = "InstSystemZ";
105 let RowFields = ["DispKey"];
106 let ColFields = ["DispSize"];
108 let ValueCols = [["12"]];
111 // Return the version of an instruction that has a signed 20-bit displacement.
112 def getDisp20Opcode : InstrMapping {
113 let FilterClass = "InstSystemZ";
114 let RowFields = ["DispKey"];
115 let ColFields = ["DispSize"];
117 let ValueCols = [["20"]];
120 // Return the memory form of a register instruction.
121 def getMemOpcode : InstrMapping {
122 let FilterClass = "InstSystemZ";
123 let RowFields = ["OpKey"];
124 let ColFields = ["OpType"];
125 let KeyCol = ["reg"];
126 let ValueCols = [["mem"]];
129 // Return the 3-operand form of a 2-operand instruction.
130 def getThreeOperandOpcode : InstrMapping {
131 let FilterClass = "InstSystemZ";
132 let RowFields = ["NumOpsKey"];
133 let ColFields = ["NumOpsValue"];
135 let ValueCols = [["3"]];
138 //===----------------------------------------------------------------------===//
139 // Instruction formats
140 //===----------------------------------------------------------------------===//
142 // Formats are specified using operand field declarations of the form:
144 // bits<4> Rn : register input or output for operand n
145 // bits<m> In : immediate value of width m for operand n
146 // bits<4> BDn : address operand n, which has a base and a displacement
147 // bits<m> XBDn : address operand n, which has an index, a base and a
149 // bits<4> Xn : index register for address operand n
150 // bits<4> Mn : mode value for operand n
152 // The operand numbers ("n" in the list above) follow the architecture manual.
153 // Assembly operands sometimes have a different order; in particular, R3 often
154 // is often written between operands 1 and 2.
156 //===----------------------------------------------------------------------===//
158 class InstRI<bits<12> op, dag outs, dag ins, string asmstr, list<dag> pattern>
159 : InstSystemZ<4, outs, ins, asmstr, pattern> {
161 field bits<32> SoftFail = 0;
166 let Inst{31-24} = op{11-4};
167 let Inst{23-20} = R1;
168 let Inst{19-16} = op{3-0};
172 class InstRIEb<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
173 : InstSystemZ<6, outs, ins, asmstr, pattern> {
175 field bits<48> SoftFail = 0;
182 let Inst{47-40} = op{15-8};
183 let Inst{39-36} = R1;
184 let Inst{35-32} = R2;
185 let Inst{31-16} = RI4;
186 let Inst{15-12} = M3;
188 let Inst{7-0} = op{7-0};
191 class InstRIEc<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
192 : InstSystemZ<6, outs, ins, asmstr, pattern> {
194 field bits<48> SoftFail = 0;
201 let Inst{47-40} = op{15-8};
202 let Inst{39-36} = R1;
203 let Inst{35-32} = M3;
204 let Inst{31-16} = RI4;
206 let Inst{7-0} = op{7-0};
209 class InstRIEd<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
210 : InstSystemZ<6, outs, ins, asmstr, pattern> {
212 field bits<48> SoftFail = 0;
218 let Inst{47-40} = op{15-8};
219 let Inst{39-36} = R1;
220 let Inst{35-32} = R3;
221 let Inst{31-16} = I2;
223 let Inst{7-0} = op{7-0};
226 class InstRIEf<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
227 : InstSystemZ<6, outs, ins, asmstr, pattern> {
229 field bits<48> SoftFail = 0;
237 let Inst{47-40} = op{15-8};
238 let Inst{39-36} = R1;
239 let Inst{35-32} = R2;
240 let Inst{31-24} = I3;
241 let Inst{23-16} = I4;
243 let Inst{7-0} = op{7-0};
246 class InstRIL<bits<12> op, dag outs, dag ins, string asmstr, list<dag> pattern>
247 : InstSystemZ<6, outs, ins, asmstr, pattern> {
249 field bits<48> SoftFail = 0;
254 let Inst{47-40} = op{11-4};
255 let Inst{39-36} = R1;
256 let Inst{35-32} = op{3-0};
260 class InstRR<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
261 : InstSystemZ<2, outs, ins, asmstr, pattern> {
263 field bits<16> SoftFail = 0;
273 class InstRRD<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
274 : InstSystemZ<4, outs, ins, asmstr, pattern> {
276 field bits<32> SoftFail = 0;
282 let Inst{31-16} = op;
283 let Inst{15-12} = R1;
289 class InstRRE<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
290 : InstSystemZ<4, outs, ins, asmstr, pattern> {
292 field bits<32> SoftFail = 0;
297 let Inst{31-16} = op;
303 class InstRRF<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
304 : InstSystemZ<4, outs, ins, asmstr, pattern> {
306 field bits<32> SoftFail = 0;
313 let Inst{31-16} = op;
314 let Inst{15-12} = R3;
320 class InstRX<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
321 : InstSystemZ<4, outs, ins, asmstr, pattern> {
323 field bits<32> SoftFail = 0;
328 let Inst{31-24} = op;
329 let Inst{23-20} = R1;
330 let Inst{19-0} = XBD2;
335 class InstRXE<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
336 : InstSystemZ<6, outs, ins, asmstr, pattern> {
338 field bits<48> SoftFail = 0;
343 let Inst{47-40} = op{15-8};
344 let Inst{39-36} = R1;
345 let Inst{35-16} = XBD2;
347 let Inst{7-0} = op{7-0};
352 class InstRXF<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
353 : InstSystemZ<6, outs, ins, asmstr, pattern> {
355 field bits<48> SoftFail = 0;
361 let Inst{47-40} = op{15-8};
362 let Inst{39-36} = R3;
363 let Inst{35-16} = XBD2;
364 let Inst{15-12} = R1;
366 let Inst{7-0} = op{7-0};
371 class InstRXY<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
372 : InstSystemZ<6, outs, ins, asmstr, pattern> {
374 field bits<48> SoftFail = 0;
379 let Inst{47-40} = op{15-8};
380 let Inst{39-36} = R1;
381 let Inst{35-8} = XBD2;
382 let Inst{7-0} = op{7-0};
384 let Has20BitOffset = 1;
388 class InstRS<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
389 : InstSystemZ<4, outs, ins, asmstr, pattern> {
391 field bits<32> SoftFail = 0;
397 let Inst{31-24} = op;
398 let Inst{23-20} = R1;
399 let Inst{19-16} = R3;
400 let Inst{15-0} = BD2;
403 class InstRSY<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
404 : InstSystemZ<6, outs, ins, asmstr, pattern> {
406 field bits<48> SoftFail = 0;
412 let Inst{47-40} = op{15-8};
413 let Inst{39-36} = R1;
414 let Inst{35-32} = R3;
415 let Inst{31-8} = BD2;
416 let Inst{7-0} = op{7-0};
418 let Has20BitOffset = 1;
421 class InstSI<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
422 : InstSystemZ<4, outs, ins, asmstr, pattern> {
424 field bits<32> SoftFail = 0;
429 let Inst{31-24} = op;
430 let Inst{23-16} = I2;
431 let Inst{15-0} = BD1;
434 class InstSIL<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
435 : InstSystemZ<6, outs, ins, asmstr, pattern> {
437 field bits<48> SoftFail = 0;
442 let Inst{47-32} = op;
443 let Inst{31-16} = BD1;
447 class InstSIY<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
448 : InstSystemZ<6, outs, ins, asmstr, pattern> {
450 field bits<48> SoftFail = 0;
455 let Inst{47-40} = op{15-8};
456 let Inst{39-32} = I2;
457 let Inst{31-8} = BD1;
458 let Inst{7-0} = op{7-0};
460 let Has20BitOffset = 1;
463 class InstSS<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
464 : InstSystemZ<6, outs, ins, asmstr, pattern> {
466 field bits<48> SoftFail = 0;
471 let Inst{47-40} = op;
472 let Inst{39-16} = BDL1;
473 let Inst{15-0} = BD2;
476 //===----------------------------------------------------------------------===//
477 // Instruction definitions with semantics
478 //===----------------------------------------------------------------------===//
480 // These classes have the form [Cond]<Category><Format>, where <Format> is one
481 // of the formats defined above and where <Category> describes the inputs
482 // and outputs. "Cond" is used if the instruction is conditional,
483 // in which case the 4-bit condition-code mask is added as a final operand.
484 // <Category> can be one of:
487 // One register output operand and no input operands.
490 // One register output operand, one register input operand and
491 // one branch displacement. The instructions stores a modified
492 // form of the source register in the destination register and
493 // branches on the result.
496 // One register or immediate input operand and one address input operand.
497 // The instruction stores the first operand to the address.
499 // This category is used for both pure and truncating stores.
502 // One address input operand and two explicit output operands.
503 // The instruction loads a range of registers from the address,
504 // with the explicit operands giving the first and last register
505 // to load. Other loaded registers are added as implicit definitions.
508 // Two explicit input register operands and an address operand.
509 // The instruction stores a range of registers to the address,
510 // with the explicit operands giving the first and last register
511 // to store. Other stored registers are added as implicit uses.
514 // One register output operand and one input operand.
517 // One register output operand and two input operands.
520 // Two input operands and an implicit CC output operand.
523 // One register output operand and three input operands.
526 // One output operand and two input operands, one of which is an address.
527 // The instruction both reads from and writes to the address.
530 // One output operand and three input operands, one of which is an address.
531 // The instruction both reads from and writes to the address.
534 // One output operand and five input operands. The first two operands
535 // are registers and the other three are immediates.
538 // One 4-bit immediate operand and one address operand. The immediate
539 // operand is 1 for a load prefetch and 2 for a store prefetch.
541 // The format determines which input operands are tied to output operands,
542 // and also determines the shape of any address operand.
544 // Multiclasses of the form <Category><Format>Pair define two instructions,
545 // one with <Category><Format> and one with <Category><Format>Y. The name
546 // of the first instruction has no suffix, the name of the second has
549 //===----------------------------------------------------------------------===//
551 class InherentRRE<string mnemonic, bits<16> opcode, RegisterOperand cls,
553 : InstRRE<opcode, (outs cls:$R1), (ins),
555 [(set cls:$R1, src)]> {
559 class BranchUnaryRI<string mnemonic, bits<12> opcode, RegisterOperand cls>
560 : InstRI<opcode, (outs cls:$R1), (ins cls:$R1src, brtarget16:$I2),
561 mnemonic##"\t$R1, $I2", []> {
563 let isTerminator = 1;
564 let Constraints = "$R1 = $R1src";
565 let DisableEncoding = "$R1src";
568 class LoadMultipleRSY<string mnemonic, bits<16> opcode, RegisterOperand cls>
569 : InstRSY<opcode, (outs cls:$R1, cls:$R3), (ins bdaddr20only:$BD2),
570 mnemonic#"\t$R1, $R3, $BD2", []> {
574 class StoreRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator,
576 : InstRIL<opcode, (outs), (ins cls:$R1, pcrel32:$I2),
577 mnemonic#"\t$R1, $I2",
578 [(operator cls:$R1, pcrel32:$I2)]> {
580 // We want PC-relative addresses to be tried ahead of BD and BDX addresses.
581 // However, BDXs have two extra operands and are therefore 6 units more
583 let AddedComplexity = 7;
586 class StoreRX<string mnemonic, bits<8> opcode, SDPatternOperator operator,
587 RegisterOperand cls, bits<5> bytes,
588 AddressingMode mode = bdxaddr12only>
589 : InstRX<opcode, (outs), (ins cls:$R1, mode:$XBD2),
590 mnemonic#"\t$R1, $XBD2",
591 [(operator cls:$R1, mode:$XBD2)]> {
592 let OpKey = mnemonic ## cls;
595 let AccessBytes = bytes;
598 class StoreRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
599 RegisterOperand cls, bits<5> bytes,
600 AddressingMode mode = bdxaddr20only>
601 : InstRXY<opcode, (outs), (ins cls:$R1, mode:$XBD2),
602 mnemonic#"\t$R1, $XBD2",
603 [(operator cls:$R1, mode:$XBD2)]> {
604 let OpKey = mnemonic ## cls;
607 let AccessBytes = bytes;
610 multiclass StoreRXPair<string mnemonic, bits<8> rxOpcode, bits<16> rxyOpcode,
611 SDPatternOperator operator, RegisterOperand cls,
613 let DispKey = mnemonic ## #cls in {
614 let DispSize = "12" in
615 def "" : StoreRX<mnemonic, rxOpcode, operator, cls, bytes, bdxaddr12pair>;
616 let DispSize = "20" in
617 def Y : StoreRXY<mnemonic#"y", rxyOpcode, operator, cls, bytes,
622 class StoreMultipleRSY<string mnemonic, bits<16> opcode, RegisterOperand cls>
623 : InstRSY<opcode, (outs), (ins cls:$R1, cls:$R3, bdaddr20only:$BD2),
624 mnemonic#"\t$R1, $R3, $BD2", []> {
628 // StoreSI* instructions are used to store an integer to memory, but the
629 // addresses are more restricted than for normal stores. If we are in the
630 // situation of having to force either the address into a register or the
631 // constant into a register, it's usually better to do the latter.
632 // We therefore match the address in the same way as a normal store and
633 // only use the StoreSI* instruction if the matched address is suitable.
634 class StoreSI<string mnemonic, bits<8> opcode, SDPatternOperator operator,
636 : InstSI<opcode, (outs), (ins mviaddr12pair:$BD1, imm:$I2),
637 mnemonic#"\t$BD1, $I2",
638 [(operator imm:$I2, mviaddr12pair:$BD1)]> {
642 class StoreSIY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
644 : InstSIY<opcode, (outs), (ins mviaddr20pair:$BD1, imm:$I2),
645 mnemonic#"\t$BD1, $I2",
646 [(operator imm:$I2, mviaddr20pair:$BD1)]> {
650 class StoreSIL<string mnemonic, bits<16> opcode, SDPatternOperator operator,
652 : InstSIL<opcode, (outs), (ins mviaddr12pair:$BD1, imm:$I2),
653 mnemonic#"\t$BD1, $I2",
654 [(operator imm:$I2, mviaddr12pair:$BD1)]> {
658 multiclass StoreSIPair<string mnemonic, bits<8> siOpcode, bits<16> siyOpcode,
659 SDPatternOperator operator, Immediate imm> {
660 let DispKey = mnemonic in {
661 let DispSize = "12" in
662 def "" : StoreSI<mnemonic, siOpcode, operator, imm>;
663 let DispSize = "20" in
664 def Y : StoreSIY<mnemonic#"y", siyOpcode, operator, imm>;
668 class CondStoreRSY<string mnemonic, bits<16> opcode,
669 RegisterOperand cls, bits<5> bytes,
670 AddressingMode mode = bdaddr20only>
671 : InstRSY<opcode, (outs), (ins cls:$R1, mode:$BD2, cond4:$valid, cond4:$R3),
672 mnemonic#"$R3\t$R1, $BD2", []>,
673 Requires<[FeatureLoadStoreOnCond]> {
675 let AccessBytes = bytes;
679 // Like CondStoreRSY, but used for the raw assembly form. The condition-code
680 // mask is the third operand rather than being part of the mnemonic.
681 class AsmCondStoreRSY<string mnemonic, bits<16> opcode,
682 RegisterOperand cls, bits<5> bytes,
683 AddressingMode mode = bdaddr20only>
684 : InstRSY<opcode, (outs), (ins cls:$R1, mode:$BD2, imm32zx4:$R3),
685 mnemonic#"\t$R1, $BD2, $R3", []>,
686 Requires<[FeatureLoadStoreOnCond]> {
688 let AccessBytes = bytes;
691 // Like CondStoreRSY, but with a fixed CC mask.
692 class FixedCondStoreRSY<string mnemonic, bits<16> opcode,
693 RegisterOperand cls, bits<4> ccmask, bits<5> bytes,
694 AddressingMode mode = bdaddr20only>
695 : InstRSY<opcode, (outs), (ins cls:$R1, mode:$BD2),
696 mnemonic#"\t$R1, $BD2", []>,
697 Requires<[FeatureLoadStoreOnCond]> {
699 let AccessBytes = bytes;
703 class UnaryRR<string mnemonic, bits<8> opcode, SDPatternOperator operator,
704 RegisterOperand cls1, RegisterOperand cls2>
705 : InstRR<opcode, (outs cls1:$R1), (ins cls2:$R2),
706 mnemonic#"r\t$R1, $R2",
707 [(set cls1:$R1, (operator cls2:$R2))]> {
708 let OpKey = mnemonic ## cls1;
712 class UnaryRRE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
713 RegisterOperand cls1, RegisterOperand cls2>
714 : InstRRE<opcode, (outs cls1:$R1), (ins cls2:$R2),
715 mnemonic#"r\t$R1, $R2",
716 [(set cls1:$R1, (operator cls2:$R2))]> {
717 let OpKey = mnemonic ## cls1;
721 class UnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1,
722 RegisterOperand cls2>
723 : InstRRF<opcode, (outs cls1:$R1), (ins imm32zx4:$R3, cls2:$R2),
724 mnemonic#"r\t$R1, $R3, $R2", []> {
725 let OpKey = mnemonic ## cls1;
730 class UnaryRRF4<string mnemonic, bits<16> opcode, RegisterOperand cls1,
731 RegisterOperand cls2>
732 : InstRRF<opcode, (outs cls1:$R1), (ins imm32zx4:$R3, cls2:$R2, imm32zx4:$R4),
733 mnemonic#"\t$R1, $R3, $R2, $R4", []>;
735 // These instructions are generated by if conversion. The old value of R1
736 // is added as an implicit use.
737 class CondUnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1,
738 RegisterOperand cls2>
739 : InstRRF<opcode, (outs cls1:$R1), (ins cls2:$R2, cond4:$valid, cond4:$R3),
740 mnemonic#"r$R3\t$R1, $R2", []>,
741 Requires<[FeatureLoadStoreOnCond]> {
746 // Like CondUnaryRRF, but used for the raw assembly form. The condition-code
747 // mask is the third operand rather than being part of the mnemonic.
748 class AsmCondUnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1,
749 RegisterOperand cls2>
750 : InstRRF<opcode, (outs cls1:$R1), (ins cls1:$R1src, cls2:$R2, imm32zx4:$R3),
751 mnemonic#"r\t$R1, $R2, $R3", []>,
752 Requires<[FeatureLoadStoreOnCond]> {
753 let Constraints = "$R1 = $R1src";
754 let DisableEncoding = "$R1src";
758 // Like CondUnaryRRF, but with a fixed CC mask.
759 class FixedCondUnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1,
760 RegisterOperand cls2, bits<4> ccmask>
761 : InstRRF<opcode, (outs cls1:$R1), (ins cls1:$R1src, cls2:$R2),
762 mnemonic#"\t$R1, $R2", []>,
763 Requires<[FeatureLoadStoreOnCond]> {
764 let Constraints = "$R1 = $R1src";
765 let DisableEncoding = "$R1src";
770 class UnaryRI<string mnemonic, bits<12> opcode, SDPatternOperator operator,
771 RegisterOperand cls, Immediate imm>
772 : InstRI<opcode, (outs cls:$R1), (ins imm:$I2),
773 mnemonic#"\t$R1, $I2",
774 [(set cls:$R1, (operator imm:$I2))]>;
776 class UnaryRIL<string mnemonic, bits<12> opcode, SDPatternOperator operator,
777 RegisterOperand cls, Immediate imm>
778 : InstRIL<opcode, (outs cls:$R1), (ins imm:$I2),
779 mnemonic#"\t$R1, $I2",
780 [(set cls:$R1, (operator imm:$I2))]>;
782 class UnaryRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator,
784 : InstRIL<opcode, (outs cls:$R1), (ins pcrel32:$I2),
785 mnemonic#"\t$R1, $I2",
786 [(set cls:$R1, (operator pcrel32:$I2))]> {
788 // We want PC-relative addresses to be tried ahead of BD and BDX addresses.
789 // However, BDXs have two extra operands and are therefore 6 units more
791 let AddedComplexity = 7;
794 class CondUnaryRSY<string mnemonic, bits<16> opcode,
795 SDPatternOperator operator, RegisterOperand cls,
796 bits<5> bytes, AddressingMode mode = bdaddr20only>
797 : InstRSY<opcode, (outs cls:$R1),
798 (ins cls:$R1src, mode:$BD2, cond4:$valid, cond4:$R3),
799 mnemonic#"$R3\t$R1, $BD2",
801 (z_select_ccmask (load bdaddr20only:$BD2), cls:$R1src,
802 cond4:$valid, cond4:$R3))]>,
803 Requires<[FeatureLoadStoreOnCond]> {
804 let Constraints = "$R1 = $R1src";
805 let DisableEncoding = "$R1src";
807 let AccessBytes = bytes;
811 // Like CondUnaryRSY, but used for the raw assembly form. The condition-code
812 // mask is the third operand rather than being part of the mnemonic.
813 class AsmCondUnaryRSY<string mnemonic, bits<16> opcode,
814 RegisterOperand cls, bits<5> bytes,
815 AddressingMode mode = bdaddr20only>
816 : InstRSY<opcode, (outs cls:$R1), (ins cls:$R1src, mode:$BD2, imm32zx4:$R3),
817 mnemonic#"\t$R1, $BD2, $R3", []>,
818 Requires<[FeatureLoadStoreOnCond]> {
820 let AccessBytes = bytes;
821 let Constraints = "$R1 = $R1src";
822 let DisableEncoding = "$R1src";
825 // Like CondUnaryRSY, but with a fixed CC mask.
826 class FixedCondUnaryRSY<string mnemonic, bits<16> opcode,
827 RegisterOperand cls, bits<4> ccmask, bits<5> bytes,
828 AddressingMode mode = bdaddr20only>
829 : InstRSY<opcode, (outs cls:$R1), (ins cls:$R1src, mode:$BD2),
830 mnemonic#"\t$R1, $BD2", []>,
831 Requires<[FeatureLoadStoreOnCond]> {
832 let Constraints = "$R1 = $R1src";
833 let DisableEncoding = "$R1src";
836 let AccessBytes = bytes;
839 class UnaryRX<string mnemonic, bits<8> opcode, SDPatternOperator operator,
840 RegisterOperand cls, bits<5> bytes,
841 AddressingMode mode = bdxaddr12only>
842 : InstRX<opcode, (outs cls:$R1), (ins mode:$XBD2),
843 mnemonic#"\t$R1, $XBD2",
844 [(set cls:$R1, (operator mode:$XBD2))]> {
845 let OpKey = mnemonic ## cls;
848 let AccessBytes = bytes;
851 class UnaryRXE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
852 RegisterOperand cls, bits<5> bytes>
853 : InstRXE<opcode, (outs cls:$R1), (ins bdxaddr12only:$XBD2),
854 mnemonic#"\t$R1, $XBD2",
855 [(set cls:$R1, (operator bdxaddr12only:$XBD2))]> {
856 let OpKey = mnemonic ## cls;
859 let AccessBytes = bytes;
862 class UnaryRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
863 RegisterOperand cls, bits<5> bytes,
864 AddressingMode mode = bdxaddr20only>
865 : InstRXY<opcode, (outs cls:$R1), (ins mode:$XBD2),
866 mnemonic#"\t$R1, $XBD2",
867 [(set cls:$R1, (operator mode:$XBD2))]> {
868 let OpKey = mnemonic ## cls;
871 let AccessBytes = bytes;
874 multiclass UnaryRXPair<string mnemonic, bits<8> rxOpcode, bits<16> rxyOpcode,
875 SDPatternOperator operator, RegisterOperand cls,
877 let DispKey = mnemonic ## #cls in {
878 let DispSize = "12" in
879 def "" : UnaryRX<mnemonic, rxOpcode, operator, cls, bytes, bdxaddr12pair>;
880 let DispSize = "20" in
881 def Y : UnaryRXY<mnemonic#"y", rxyOpcode, operator, cls, bytes,
886 class BinaryRR<string mnemonic, bits<8> opcode, SDPatternOperator operator,
887 RegisterOperand cls1, RegisterOperand cls2>
888 : InstRR<opcode, (outs cls1:$R1), (ins cls1:$R1src, cls2:$R2),
889 mnemonic#"r\t$R1, $R2",
890 [(set cls1:$R1, (operator cls1:$R1src, cls2:$R2))]> {
891 let OpKey = mnemonic ## cls1;
893 let Constraints = "$R1 = $R1src";
894 let DisableEncoding = "$R1src";
897 class BinaryRRE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
898 RegisterOperand cls1, RegisterOperand cls2>
899 : InstRRE<opcode, (outs cls1:$R1), (ins cls1:$R1src, cls2:$R2),
900 mnemonic#"r\t$R1, $R2",
901 [(set cls1:$R1, (operator cls1:$R1src, cls2:$R2))]> {
902 let OpKey = mnemonic ## cls1;
904 let Constraints = "$R1 = $R1src";
905 let DisableEncoding = "$R1src";
908 class BinaryRRF<string mnemonic, bits<16> opcode, SDPatternOperator operator,
909 RegisterOperand cls1, RegisterOperand cls2>
910 : InstRRF<opcode, (outs cls1:$R1), (ins cls1:$R3, cls2:$R2),
911 mnemonic#"r\t$R1, $R3, $R2",
912 [(set cls1:$R1, (operator cls1:$R3, cls2:$R2))]> {
913 let OpKey = mnemonic ## cls1;
918 class BinaryRRFK<string mnemonic, bits<16> opcode, SDPatternOperator operator,
919 RegisterOperand cls1, RegisterOperand cls2>
920 : InstRRF<opcode, (outs cls1:$R1), (ins cls1:$R2, cls2:$R3),
921 mnemonic#"rk\t$R1, $R2, $R3",
922 [(set cls1:$R1, (operator cls1:$R2, cls2:$R3))]> {
926 multiclass BinaryRRAndK<string mnemonic, bits<8> opcode1, bits<16> opcode2,
927 SDPatternOperator operator, RegisterOperand cls1,
928 RegisterOperand cls2> {
929 let NumOpsKey = mnemonic in {
930 let NumOpsValue = "3" in
931 def K : BinaryRRFK<mnemonic, opcode2, null_frag, cls1, cls2>,
932 Requires<[FeatureDistinctOps]>;
933 let NumOpsValue = "2", isConvertibleToThreeAddress = 1 in
934 def "" : BinaryRR<mnemonic, opcode1, operator, cls1, cls2>;
938 multiclass BinaryRREAndK<string mnemonic, bits<16> opcode1, bits<16> opcode2,
939 SDPatternOperator operator, RegisterOperand cls1,
940 RegisterOperand cls2> {
941 let NumOpsKey = mnemonic in {
942 let NumOpsValue = "3" in
943 def K : BinaryRRFK<mnemonic, opcode2, null_frag, cls1, cls2>,
944 Requires<[FeatureDistinctOps]>;
945 let NumOpsValue = "2", isConvertibleToThreeAddress = 1 in
946 def "" : BinaryRRE<mnemonic, opcode1, operator, cls1, cls2>;
950 class BinaryRI<string mnemonic, bits<12> opcode, SDPatternOperator operator,
951 RegisterOperand cls, Immediate imm>
952 : InstRI<opcode, (outs cls:$R1), (ins cls:$R1src, imm:$I2),
953 mnemonic#"\t$R1, $I2",
954 [(set cls:$R1, (operator cls:$R1src, imm:$I2))]> {
955 let Constraints = "$R1 = $R1src";
956 let DisableEncoding = "$R1src";
959 class BinaryRIE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
960 RegisterOperand cls, Immediate imm>
961 : InstRIEd<opcode, (outs cls:$R1), (ins cls:$R3, imm:$I2),
962 mnemonic#"\t$R1, $R3, $I2",
963 [(set cls:$R1, (operator cls:$R3, imm:$I2))]>;
965 multiclass BinaryRIAndK<string mnemonic, bits<12> opcode1, bits<16> opcode2,
966 SDPatternOperator operator, RegisterOperand cls,
968 let NumOpsKey = mnemonic in {
969 let NumOpsValue = "3" in
970 def K : BinaryRIE<mnemonic##"k", opcode2, null_frag, cls, imm>,
971 Requires<[FeatureDistinctOps]>;
972 let NumOpsValue = "2", isConvertibleToThreeAddress = 1 in
973 def "" : BinaryRI<mnemonic, opcode1, operator, cls, imm>;
977 class BinaryRIL<string mnemonic, bits<12> opcode, SDPatternOperator operator,
978 RegisterOperand cls, Immediate imm>
979 : InstRIL<opcode, (outs cls:$R1), (ins cls:$R1src, imm:$I2),
980 mnemonic#"\t$R1, $I2",
981 [(set cls:$R1, (operator cls:$R1src, imm:$I2))]> {
982 let Constraints = "$R1 = $R1src";
983 let DisableEncoding = "$R1src";
986 class BinaryRS<string mnemonic, bits<8> opcode, SDPatternOperator operator,
988 : InstRS<opcode, (outs cls:$R1), (ins cls:$R1src, shift12only:$BD2),
989 mnemonic#"\t$R1, $BD2",
990 [(set cls:$R1, (operator cls:$R1src, shift12only:$BD2))]> {
992 let Constraints = "$R1 = $R1src";
993 let DisableEncoding = "$R1src";
996 class BinaryRSY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
998 : InstRSY<opcode, (outs cls:$R1), (ins cls:$R3, shift20only:$BD2),
999 mnemonic#"\t$R1, $R3, $BD2",
1000 [(set cls:$R1, (operator cls:$R3, shift20only:$BD2))]>;
1002 multiclass BinaryRSAndK<string mnemonic, bits<8> opcode1, bits<16> opcode2,
1003 SDPatternOperator operator, RegisterOperand cls> {
1004 let NumOpsKey = mnemonic in {
1005 let NumOpsValue = "3" in
1006 def K : BinaryRSY<mnemonic##"k", opcode2, null_frag, cls>,
1007 Requires<[FeatureDistinctOps]>;
1008 let NumOpsValue = "2", isConvertibleToThreeAddress = 1 in
1009 def "" : BinaryRS<mnemonic, opcode1, operator, cls>;
1013 class BinaryRX<string mnemonic, bits<8> opcode, SDPatternOperator operator,
1014 RegisterOperand cls, SDPatternOperator load, bits<5> bytes,
1015 AddressingMode mode = bdxaddr12only>
1016 : InstRX<opcode, (outs cls:$R1), (ins cls:$R1src, mode:$XBD2),
1017 mnemonic#"\t$R1, $XBD2",
1018 [(set cls:$R1, (operator cls:$R1src, (load mode:$XBD2)))]> {
1019 let OpKey = mnemonic ## cls;
1021 let Constraints = "$R1 = $R1src";
1022 let DisableEncoding = "$R1src";
1024 let AccessBytes = bytes;
1027 class BinaryRXE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1028 RegisterOperand cls, SDPatternOperator load, bits<5> bytes>
1029 : InstRXE<opcode, (outs cls:$R1), (ins cls:$R1src, bdxaddr12only:$XBD2),
1030 mnemonic#"\t$R1, $XBD2",
1031 [(set cls:$R1, (operator cls:$R1src,
1032 (load bdxaddr12only:$XBD2)))]> {
1033 let OpKey = mnemonic ## cls;
1035 let Constraints = "$R1 = $R1src";
1036 let DisableEncoding = "$R1src";
1038 let AccessBytes = bytes;
1041 class BinaryRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1042 RegisterOperand cls, SDPatternOperator load, bits<5> bytes,
1043 AddressingMode mode = bdxaddr20only>
1044 : InstRXY<opcode, (outs cls:$R1), (ins cls:$R1src, mode:$XBD2),
1045 mnemonic#"\t$R1, $XBD2",
1046 [(set cls:$R1, (operator cls:$R1src, (load mode:$XBD2)))]> {
1047 let OpKey = mnemonic ## cls;
1049 let Constraints = "$R1 = $R1src";
1050 let DisableEncoding = "$R1src";
1052 let AccessBytes = bytes;
1055 multiclass BinaryRXPair<string mnemonic, bits<8> rxOpcode, bits<16> rxyOpcode,
1056 SDPatternOperator operator, RegisterOperand cls,
1057 SDPatternOperator load, bits<5> bytes> {
1058 let DispKey = mnemonic ## #cls in {
1059 let DispSize = "12" in
1060 def "" : BinaryRX<mnemonic, rxOpcode, operator, cls, load, bytes,
1062 let DispSize = "20" in
1063 def Y : BinaryRXY<mnemonic#"y", rxyOpcode, operator, cls, load, bytes,
1068 class BinarySI<string mnemonic, bits<8> opcode, SDPatternOperator operator,
1069 Operand imm, AddressingMode mode = bdaddr12only>
1070 : InstSI<opcode, (outs), (ins mode:$BD1, imm:$I2),
1071 mnemonic#"\t$BD1, $I2",
1072 [(store (operator (load mode:$BD1), imm:$I2), mode:$BD1)]> {
1077 class BinarySIY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1078 Operand imm, AddressingMode mode = bdaddr20only>
1079 : InstSIY<opcode, (outs), (ins mode:$BD1, imm:$I2),
1080 mnemonic#"\t$BD1, $I2",
1081 [(store (operator (load mode:$BD1), imm:$I2), mode:$BD1)]> {
1086 multiclass BinarySIPair<string mnemonic, bits<8> siOpcode,
1087 bits<16> siyOpcode, SDPatternOperator operator,
1089 let DispKey = mnemonic ## #cls in {
1090 let DispSize = "12" in
1091 def "" : BinarySI<mnemonic, siOpcode, operator, imm, bdaddr12pair>;
1092 let DispSize = "20" in
1093 def Y : BinarySIY<mnemonic#"y", siyOpcode, operator, imm, bdaddr20pair>;
1097 class CompareRR<string mnemonic, bits<8> opcode, SDPatternOperator operator,
1098 RegisterOperand cls1, RegisterOperand cls2>
1099 : InstRR<opcode, (outs), (ins cls1:$R1, cls2:$R2),
1100 mnemonic#"r\t$R1, $R2",
1101 [(operator cls1:$R1, cls2:$R2)]> {
1102 let OpKey = mnemonic ## cls1;
1107 class CompareRRE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1108 RegisterOperand cls1, RegisterOperand cls2>
1109 : InstRRE<opcode, (outs), (ins cls1:$R1, cls2:$R2),
1110 mnemonic#"r\t$R1, $R2",
1111 [(operator cls1:$R1, cls2:$R2)]> {
1112 let OpKey = mnemonic ## cls1;
1117 class CompareRI<string mnemonic, bits<12> opcode, SDPatternOperator operator,
1118 RegisterOperand cls, Immediate imm>
1119 : InstRI<opcode, (outs), (ins cls:$R1, imm:$I2),
1120 mnemonic#"\t$R1, $I2",
1121 [(operator cls:$R1, imm:$I2)]> {
1125 class CompareRIL<string mnemonic, bits<12> opcode, SDPatternOperator operator,
1126 RegisterOperand cls, Immediate imm>
1127 : InstRIL<opcode, (outs), (ins cls:$R1, imm:$I2),
1128 mnemonic#"\t$R1, $I2",
1129 [(operator cls:$R1, imm:$I2)]> {
1133 class CompareRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator,
1134 RegisterOperand cls, SDPatternOperator load>
1135 : InstRIL<opcode, (outs), (ins cls:$R1, pcrel32:$I2),
1136 mnemonic#"\t$R1, $I2",
1137 [(operator cls:$R1, (load pcrel32:$I2))]> {
1140 // We want PC-relative addresses to be tried ahead of BD and BDX addresses.
1141 // However, BDXs have two extra operands and are therefore 6 units more
1143 let AddedComplexity = 7;
1146 class CompareRX<string mnemonic, bits<8> opcode, SDPatternOperator operator,
1147 RegisterOperand cls, SDPatternOperator load, bits<5> bytes,
1148 AddressingMode mode = bdxaddr12only>
1149 : InstRX<opcode, (outs), (ins cls:$R1, mode:$XBD2),
1150 mnemonic#"\t$R1, $XBD2",
1151 [(operator cls:$R1, (load mode:$XBD2))]> {
1152 let OpKey = mnemonic ## cls;
1156 let AccessBytes = bytes;
1159 class CompareRXE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1160 RegisterOperand cls, SDPatternOperator load, bits<5> bytes>
1161 : InstRXE<opcode, (outs), (ins cls:$R1, bdxaddr12only:$XBD2),
1162 mnemonic#"\t$R1, $XBD2",
1163 [(operator cls:$R1, (load bdxaddr12only:$XBD2))]> {
1164 let OpKey = mnemonic ## cls;
1168 let AccessBytes = bytes;
1171 class CompareRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1172 RegisterOperand cls, SDPatternOperator load, bits<5> bytes,
1173 AddressingMode mode = bdxaddr20only>
1174 : InstRXY<opcode, (outs), (ins cls:$R1, mode:$XBD2),
1175 mnemonic#"\t$R1, $XBD2",
1176 [(operator cls:$R1, (load mode:$XBD2))]> {
1177 let OpKey = mnemonic ## cls;
1181 let AccessBytes = bytes;
1184 multiclass CompareRXPair<string mnemonic, bits<8> rxOpcode, bits<16> rxyOpcode,
1185 SDPatternOperator operator, RegisterOperand cls,
1186 SDPatternOperator load, bits<5> bytes> {
1187 let DispKey = mnemonic ## #cls in {
1188 let DispSize = "12" in
1189 def "" : CompareRX<mnemonic, rxOpcode, operator, cls,
1190 load, bytes, bdxaddr12pair>;
1191 let DispSize = "20" in
1192 def Y : CompareRXY<mnemonic#"y", rxyOpcode, operator, cls,
1193 load, bytes, bdxaddr20pair>;
1197 class CompareSI<string mnemonic, bits<8> opcode, SDPatternOperator operator,
1198 SDPatternOperator load, Immediate imm,
1199 AddressingMode mode = bdaddr12only>
1200 : InstSI<opcode, (outs), (ins mode:$BD1, imm:$I2),
1201 mnemonic#"\t$BD1, $I2",
1202 [(operator (load mode:$BD1), imm:$I2)]> {
1207 class CompareSIL<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1208 SDPatternOperator load, Immediate imm>
1209 : InstSIL<opcode, (outs), (ins bdaddr12only:$BD1, imm:$I2),
1210 mnemonic#"\t$BD1, $I2",
1211 [(operator (load bdaddr12only:$BD1), imm:$I2)]> {
1216 class CompareSIY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1217 SDPatternOperator load, Immediate imm,
1218 AddressingMode mode = bdaddr20only>
1219 : InstSIY<opcode, (outs), (ins mode:$BD1, imm:$I2),
1220 mnemonic#"\t$BD1, $I2",
1221 [(operator (load mode:$BD1), imm:$I2)]> {
1226 multiclass CompareSIPair<string mnemonic, bits<8> siOpcode, bits<16> siyOpcode,
1227 SDPatternOperator operator, SDPatternOperator load,
1229 let DispKey = mnemonic in {
1230 let DispSize = "12" in
1231 def "" : CompareSI<mnemonic, siOpcode, operator, load, imm, bdaddr12pair>;
1232 let DispSize = "20" in
1233 def Y : CompareSIY<mnemonic#"y", siyOpcode, operator, load, imm,
1238 class TernaryRRD<string mnemonic, bits<16> opcode,
1239 SDPatternOperator operator, RegisterOperand cls>
1240 : InstRRD<opcode, (outs cls:$R1), (ins cls:$R1src, cls:$R3, cls:$R2),
1241 mnemonic#"r\t$R1, $R3, $R2",
1242 [(set cls:$R1, (operator cls:$R1src, cls:$R3, cls:$R2))]> {
1243 let OpKey = mnemonic ## cls;
1245 let Constraints = "$R1 = $R1src";
1246 let DisableEncoding = "$R1src";
1249 class TernaryRXF<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1250 RegisterOperand cls, SDPatternOperator load, bits<5> bytes>
1251 : InstRXF<opcode, (outs cls:$R1),
1252 (ins cls:$R1src, cls:$R3, bdxaddr12only:$XBD2),
1253 mnemonic#"\t$R1, $R3, $XBD2",
1254 [(set cls:$R1, (operator cls:$R1src, cls:$R3,
1255 (load bdxaddr12only:$XBD2)))]> {
1256 let OpKey = mnemonic ## cls;
1258 let Constraints = "$R1 = $R1src";
1259 let DisableEncoding = "$R1src";
1261 let AccessBytes = bytes;
1264 class LoadAndOpRSY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1265 RegisterOperand cls, AddressingMode mode = bdaddr20only>
1266 : InstRSY<opcode, (outs cls:$R1), (ins cls:$R3, mode:$BD2),
1267 mnemonic#"\t$R1, $R3, $BD2",
1268 [(set cls:$R1, (operator mode:$BD2, cls:$R3))]> {
1273 class CmpSwapRS<string mnemonic, bits<8> opcode, SDPatternOperator operator,
1274 RegisterOperand cls, AddressingMode mode = bdaddr12only>
1275 : InstRS<opcode, (outs cls:$R1), (ins cls:$R1src, cls:$R3, mode:$BD2),
1276 mnemonic#"\t$R1, $R3, $BD2",
1277 [(set cls:$R1, (operator mode:$BD2, cls:$R1src, cls:$R3))]> {
1278 let Constraints = "$R1 = $R1src";
1279 let DisableEncoding = "$R1src";
1284 class CmpSwapRSY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1285 RegisterOperand cls, AddressingMode mode = bdaddr20only>
1286 : InstRSY<opcode, (outs cls:$R1), (ins cls:$R1src, cls:$R3, mode:$BD2),
1287 mnemonic#"\t$R1, $R3, $BD2",
1288 [(set cls:$R1, (operator mode:$BD2, cls:$R1src, cls:$R3))]> {
1289 let Constraints = "$R1 = $R1src";
1290 let DisableEncoding = "$R1src";
1295 multiclass CmpSwapRSPair<string mnemonic, bits<8> rsOpcode, bits<16> rsyOpcode,
1296 SDPatternOperator operator, RegisterOperand cls> {
1297 let DispKey = mnemonic ## #cls in {
1298 let DispSize = "12" in
1299 def "" : CmpSwapRS<mnemonic, rsOpcode, operator, cls, bdaddr12pair>;
1300 let DispSize = "20" in
1301 def Y : CmpSwapRSY<mnemonic#"y", rsyOpcode, operator, cls, bdaddr20pair>;
1305 class RotateSelectRIEf<string mnemonic, bits<16> opcode, RegisterOperand cls1,
1306 RegisterOperand cls2>
1307 : InstRIEf<opcode, (outs cls1:$R1),
1308 (ins cls1:$R1src, cls2:$R2, imm32zx8:$I3, imm32zx8:$I4,
1310 mnemonic#"\t$R1, $R2, $I3, $I4, $I5", []> {
1311 let Constraints = "$R1 = $R1src";
1312 let DisableEncoding = "$R1src";
1315 class PrefetchRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator>
1316 : InstRXY<opcode, (outs), (ins imm32zx4:$R1, bdxaddr20only:$XBD2),
1317 mnemonic##"\t$R1, $XBD2",
1318 [(operator imm32zx4:$R1, bdxaddr20only:$XBD2)]>;
1320 class PrefetchRILPC<string mnemonic, bits<12> opcode,
1321 SDPatternOperator operator>
1322 : InstRIL<opcode, (outs), (ins imm32zx4:$R1, pcrel32:$I2),
1323 mnemonic##"\t$R1, $I2",
1324 [(operator imm32zx4:$R1, pcrel32:$I2)]> {
1325 // We want PC-relative addresses to be tried ahead of BD and BDX addresses.
1326 // However, BDXs have two extra operands and are therefore 6 units more
1328 let AddedComplexity = 7;
1331 // A floating-point load-and test operation. Create both a normal unary
1332 // operation and one that acts as a comparison against zero.
1333 multiclass LoadAndTestRRE<string mnemonic, bits<16> opcode,
1334 RegisterOperand cls> {
1335 def "" : UnaryRRE<mnemonic, opcode, null_frag, cls, cls>;
1336 let isCodeGenOnly = 1 in
1337 def Compare : CompareRRE<mnemonic, opcode, null_frag, cls, cls>;
1340 //===----------------------------------------------------------------------===//
1341 // Pseudo instructions
1342 //===----------------------------------------------------------------------===//
1344 // Convenience instructions that get lowered to real instructions
1345 // by either SystemZTargetLowering::EmitInstrWithCustomInserter()
1346 // or SystemZInstrInfo::expandPostRAPseudo().
1348 //===----------------------------------------------------------------------===//
1350 class Pseudo<dag outs, dag ins, list<dag> pattern>
1351 : InstSystemZ<0, outs, ins, "", pattern> {
1353 let isCodeGenOnly = 1;
1356 // Like UnaryRI, but expanded after RA depending on the choice of register.
1357 class UnaryRIPseudo<SDPatternOperator operator, RegisterOperand cls,
1359 : Pseudo<(outs cls:$R1), (ins imm:$I2),
1360 [(set cls:$R1, (operator imm:$I2))]>;
1362 // Like UnaryRXY, but expanded after RA depending on the choice of register.
1363 class UnaryRXYPseudo<string key, SDPatternOperator operator,
1364 RegisterOperand cls, bits<5> bytes,
1365 AddressingMode mode = bdxaddr20only>
1366 : Pseudo<(outs cls:$R1), (ins mode:$XBD2),
1367 [(set cls:$R1, (operator mode:$XBD2))]> {
1368 let OpKey = key ## cls;
1371 let Has20BitOffset = 1;
1373 let AccessBytes = bytes;
1376 // Like UnaryRR, but expanded after RA depending on the choice of registers.
1377 class UnaryRRPseudo<string key, SDPatternOperator operator,
1378 RegisterOperand cls1, RegisterOperand cls2>
1379 : Pseudo<(outs cls1:$R1), (ins cls2:$R2),
1380 [(set cls1:$R1, (operator cls2:$R2))]> {
1381 let OpKey = key ## cls1;
1385 // Like BinaryRI, but expanded after RA depending on the choice of register.
1386 class BinaryRIPseudo<SDPatternOperator operator, RegisterOperand cls,
1388 : Pseudo<(outs cls:$R1), (ins cls:$R1src, imm:$I2),
1389 [(set cls:$R1, (operator cls:$R1src, imm:$I2))]> {
1390 let Constraints = "$R1 = $R1src";
1393 // Like BinaryRIE, but expanded after RA depending on the choice of register.
1394 class BinaryRIEPseudo<SDPatternOperator operator, RegisterOperand cls,
1396 : Pseudo<(outs cls:$R1), (ins cls:$R3, imm:$I2),
1397 [(set cls:$R1, (operator cls:$R3, imm:$I2))]>;
1399 // Like BinaryRIAndK, but expanded after RA depending on the choice of register.
1400 multiclass BinaryRIAndKPseudo<string key, SDPatternOperator operator,
1401 RegisterOperand cls, Immediate imm> {
1402 let NumOpsKey = key in {
1403 let NumOpsValue = "3" in
1404 def K : BinaryRIEPseudo<null_frag, cls, imm>,
1405 Requires<[FeatureHighWord, FeatureDistinctOps]>;
1406 let NumOpsValue = "2", isConvertibleToThreeAddress = 1 in
1407 def "" : BinaryRIPseudo<operator, cls, imm>,
1408 Requires<[FeatureHighWord]>;
1412 // Like CompareRI, but expanded after RA depending on the choice of register.
1413 class CompareRIPseudo<SDPatternOperator operator, RegisterOperand cls,
1415 : Pseudo<(outs), (ins cls:$R1, imm:$I2), [(operator cls:$R1, imm:$I2)]>;
1417 // Like CompareRXY, but expanded after RA depending on the choice of register.
1418 class CompareRXYPseudo<SDPatternOperator operator, RegisterOperand cls,
1419 SDPatternOperator load, bits<5> bytes,
1420 AddressingMode mode = bdxaddr20only>
1421 : Pseudo<(outs), (ins cls:$R1, mode:$XBD2),
1422 [(operator cls:$R1, (load mode:$XBD2))]> {
1424 let Has20BitOffset = 1;
1426 let AccessBytes = bytes;
1429 // Like StoreRXY, but expanded after RA depending on the choice of register.
1430 class StoreRXYPseudo<SDPatternOperator operator, RegisterOperand cls,
1431 bits<5> bytes, AddressingMode mode = bdxaddr20only>
1432 : Pseudo<(outs), (ins cls:$R1, mode:$XBD2),
1433 [(operator cls:$R1, mode:$XBD2)]> {
1435 let Has20BitOffset = 1;
1437 let AccessBytes = bytes;
1440 // Like RotateSelectRIEf, but expanded after RA depending on the choice
1442 class RotateSelectRIEfPseudo<RegisterOperand cls1, RegisterOperand cls2>
1443 : Pseudo<(outs cls1:$R1),
1444 (ins cls1:$R1src, cls2:$R2, imm32zx8:$I3, imm32zx8:$I4,
1447 let Constraints = "$R1 = $R1src";
1448 let DisableEncoding = "$R1src";
1451 // Implements "$dst = $cc & (8 >> CC) ? $src1 : $src2", where CC is
1452 // the value of the PSW's 2-bit condition code field.
1453 class SelectWrapper<RegisterOperand cls>
1454 : Pseudo<(outs cls:$dst),
1455 (ins cls:$src1, cls:$src2, imm32zx4:$valid, imm32zx4:$cc),
1456 [(set cls:$dst, (z_select_ccmask cls:$src1, cls:$src2,
1457 imm32zx4:$valid, imm32zx4:$cc))]> {
1458 let usesCustomInserter = 1;
1459 // Although the instructions used by these nodes do not in themselves
1460 // change CC, the insertion requires new blocks, and CC cannot be live
1466 // Stores $new to $addr if $cc is true ("" case) or false (Inv case).
1467 multiclass CondStores<RegisterOperand cls, SDPatternOperator store,
1468 SDPatternOperator load, AddressingMode mode> {
1469 let Defs = [CC], Uses = [CC], usesCustomInserter = 1 in {
1470 def "" : Pseudo<(outs),
1471 (ins cls:$new, mode:$addr, imm32zx4:$valid, imm32zx4:$cc),
1472 [(store (z_select_ccmask cls:$new, (load mode:$addr),
1473 imm32zx4:$valid, imm32zx4:$cc),
1475 def Inv : Pseudo<(outs),
1476 (ins cls:$new, mode:$addr, imm32zx4:$valid, imm32zx4:$cc),
1477 [(store (z_select_ccmask (load mode:$addr), cls:$new,
1478 imm32zx4:$valid, imm32zx4:$cc),
1483 // OPERATOR is ATOMIC_SWAP or an ATOMIC_LOAD_* operation. PAT and OPERAND
1484 // describe the second (non-memory) operand.
1485 class AtomicLoadBinary<SDPatternOperator operator, RegisterOperand cls,
1486 dag pat, DAGOperand operand>
1487 : Pseudo<(outs cls:$dst), (ins bdaddr20only:$ptr, operand:$src2),
1488 [(set cls:$dst, (operator bdaddr20only:$ptr, pat))]> {
1490 let Has20BitOffset = 1;
1493 let usesCustomInserter = 1;
1496 // Specializations of AtomicLoadWBinary.
1497 class AtomicLoadBinaryReg32<SDPatternOperator operator>
1498 : AtomicLoadBinary<operator, GR32, (i32 GR32:$src2), GR32>;
1499 class AtomicLoadBinaryImm32<SDPatternOperator operator, Immediate imm>
1500 : AtomicLoadBinary<operator, GR32, (i32 imm:$src2), imm>;
1501 class AtomicLoadBinaryReg64<SDPatternOperator operator>
1502 : AtomicLoadBinary<operator, GR64, (i64 GR64:$src2), GR64>;
1503 class AtomicLoadBinaryImm64<SDPatternOperator operator, Immediate imm>
1504 : AtomicLoadBinary<operator, GR64, (i64 imm:$src2), imm>;
1506 // OPERATOR is ATOMIC_SWAPW or an ATOMIC_LOADW_* operation. PAT and OPERAND
1507 // describe the second (non-memory) operand.
1508 class AtomicLoadWBinary<SDPatternOperator operator, dag pat,
1510 : Pseudo<(outs GR32:$dst),
1511 (ins bdaddr20only:$ptr, operand:$src2, ADDR32:$bitshift,
1512 ADDR32:$negbitshift, uimm32:$bitsize),
1513 [(set GR32:$dst, (operator bdaddr20only:$ptr, pat, ADDR32:$bitshift,
1514 ADDR32:$negbitshift, uimm32:$bitsize))]> {
1516 let Has20BitOffset = 1;
1519 let usesCustomInserter = 1;
1522 // Specializations of AtomicLoadWBinary.
1523 class AtomicLoadWBinaryReg<SDPatternOperator operator>
1524 : AtomicLoadWBinary<operator, (i32 GR32:$src2), GR32>;
1525 class AtomicLoadWBinaryImm<SDPatternOperator operator, Immediate imm>
1526 : AtomicLoadWBinary<operator, (i32 imm:$src2), imm>;
1528 // Define an instruction that operates on two fixed-length blocks of memory,
1529 // and associated pseudo instructions for operating on blocks of any size.
1530 // The Sequence form uses a straight-line sequence of instructions and
1531 // the Loop form uses a loop of length-256 instructions followed by
1532 // another instruction to handle the excess.
1533 multiclass MemorySS<string mnemonic, bits<8> opcode,
1534 SDPatternOperator sequence, SDPatternOperator loop> {
1535 def "" : InstSS<opcode, (outs), (ins bdladdr12onlylen8:$BDL1,
1537 mnemonic##"\t$BDL1, $BD2", []>;
1538 let usesCustomInserter = 1 in {
1539 def Sequence : Pseudo<(outs), (ins bdaddr12only:$dest, bdaddr12only:$src,
1541 [(sequence bdaddr12only:$dest, bdaddr12only:$src,
1543 def Loop : Pseudo<(outs), (ins bdaddr12only:$dest, bdaddr12only:$src,
1544 imm64:$length, GR64:$count256),
1545 [(loop bdaddr12only:$dest, bdaddr12only:$src,
1546 imm64:$length, GR64:$count256)]>;
1550 // Define an instruction that operates on two strings, both terminated
1551 // by the character in R0. The instruction processes a CPU-determinated
1552 // number of bytes at a time and sets CC to 3 if the instruction needs
1553 // to be repeated. Also define a pseudo instruction that represents
1554 // the full loop (the main instruction plus the branch on CC==3).
1555 multiclass StringRRE<string mnemonic, bits<16> opcode,
1556 SDPatternOperator operator> {
1557 def "" : InstRRE<opcode, (outs GR64:$R1, GR64:$R2),
1558 (ins GR64:$R1src, GR64:$R2src),
1559 mnemonic#"\t$R1, $R2", []> {
1560 let Constraints = "$R1 = $R1src, $R2 = $R2src";
1561 let DisableEncoding = "$R1src, $R2src";
1563 let usesCustomInserter = 1 in
1564 def Loop : Pseudo<(outs GR64:$end),
1565 (ins GR64:$start1, GR64:$start2, GR32:$char),
1566 [(set GR64:$end, (operator GR64:$start1, GR64:$start2,
1570 // A pseudo instruction that is a direct alias of a real instruction.
1571 // These aliases are used in cases where a particular register operand is
1572 // fixed or where the same instruction is used with different register sizes.
1573 // The size parameter is the size in bytes of the associated real instruction.
1574 class Alias<int size, dag outs, dag ins, list<dag> pattern>
1575 : InstSystemZ<size, outs, ins, "", pattern> {
1577 let isCodeGenOnly = 1;
1580 // An alias of a BinaryRI, but with different register sizes.
1581 class BinaryAliasRI<SDPatternOperator operator, RegisterOperand cls,
1583 : Alias<4, (outs cls:$R1), (ins cls:$R1src, imm:$I2),
1584 [(set cls:$R1, (operator cls:$R1src, imm:$I2))]> {
1585 let Constraints = "$R1 = $R1src";
1588 // An alias of a BinaryRIL, but with different register sizes.
1589 class BinaryAliasRIL<SDPatternOperator operator, RegisterOperand cls,
1591 : Alias<6, (outs cls:$R1), (ins cls:$R1src, imm:$I2),
1592 [(set cls:$R1, (operator cls:$R1src, imm:$I2))]> {
1593 let Constraints = "$R1 = $R1src";
1596 // An alias of a CompareRI, but with different register sizes.
1597 class CompareAliasRI<SDPatternOperator operator, RegisterOperand cls,
1599 : Alias<4, (outs), (ins cls:$R1, imm:$I2), [(operator cls:$R1, imm:$I2)]> {
1603 // An alias of a RotateSelectRIEf, but with different register sizes.
1604 class RotateSelectAliasRIEf<RegisterOperand cls1, RegisterOperand cls2>
1605 : Alias<6, (outs cls1:$R1),
1606 (ins cls1:$R1src, cls2:$R2, imm32zx8:$I3, imm32zx8:$I4,
1607 imm32zx6:$I5), []> {
1608 let Constraints = "$R1 = $R1src";