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 // True if the instruction sets CC to 0 when the result is 0.
72 // True if the instruction sets CC to 1 when the result is less than 0
73 // and to 2 when the result is greater than 0.
76 // True if the instruction is conditional and if the CC mask operand
77 // comes first (as for BRC, etc.).
80 // Similar, but true if the CC mask operand comes last (as for LOC, etc.).
83 // True if the instruction is the "logical" rather than "arithmetic" form,
84 // in cases where a distinction exists.
87 let TSFlags{0} = SimpleBDXLoad;
88 let TSFlags{1} = SimpleBDXStore;
89 let TSFlags{2} = Has20BitOffset;
90 let TSFlags{3} = HasIndex;
91 let TSFlags{4} = Is128Bit;
92 let TSFlags{9-5} = AccessBytes;
93 let TSFlags{13-10} = CCValues;
94 let TSFlags{14} = CCHasZero;
95 let TSFlags{15} = CCHasOrder;
96 let TSFlags{16} = CCMaskFirst;
97 let TSFlags{17} = CCMaskLast;
98 let TSFlags{18} = IsLogical;
101 //===----------------------------------------------------------------------===//
102 // Mappings between instructions
103 //===----------------------------------------------------------------------===//
105 // Return the version of an instruction that has an unsigned 12-bit
107 def getDisp12Opcode : InstrMapping {
108 let FilterClass = "InstSystemZ";
109 let RowFields = ["DispKey"];
110 let ColFields = ["DispSize"];
112 let ValueCols = [["12"]];
115 // Return the version of an instruction that has a signed 20-bit displacement.
116 def getDisp20Opcode : InstrMapping {
117 let FilterClass = "InstSystemZ";
118 let RowFields = ["DispKey"];
119 let ColFields = ["DispSize"];
121 let ValueCols = [["20"]];
124 // Return the memory form of a register instruction.
125 def getMemOpcode : InstrMapping {
126 let FilterClass = "InstSystemZ";
127 let RowFields = ["OpKey"];
128 let ColFields = ["OpType"];
129 let KeyCol = ["reg"];
130 let ValueCols = [["mem"]];
133 // Return the 3-operand form of a 2-operand instruction.
134 def getThreeOperandOpcode : InstrMapping {
135 let FilterClass = "InstSystemZ";
136 let RowFields = ["NumOpsKey"];
137 let ColFields = ["NumOpsValue"];
139 let ValueCols = [["3"]];
142 //===----------------------------------------------------------------------===//
143 // Instruction formats
144 //===----------------------------------------------------------------------===//
146 // Formats are specified using operand field declarations of the form:
148 // bits<4> Rn : register input or output for operand n
149 // bits<m> In : immediate value of width m for operand n
150 // bits<4> BDn : address operand n, which has a base and a displacement
151 // bits<m> XBDn : address operand n, which has an index, a base and a
153 // bits<4> Xn : index register for address operand n
154 // bits<4> Mn : mode value for operand n
156 // The operand numbers ("n" in the list above) follow the architecture manual.
157 // Assembly operands sometimes have a different order; in particular, R3 often
158 // is often written between operands 1 and 2.
160 //===----------------------------------------------------------------------===//
162 class InstRI<bits<12> op, dag outs, dag ins, string asmstr, list<dag> pattern>
163 : InstSystemZ<4, outs, ins, asmstr, pattern> {
165 field bits<32> SoftFail = 0;
170 let Inst{31-24} = op{11-4};
171 let Inst{23-20} = R1;
172 let Inst{19-16} = op{3-0};
176 class InstRIEb<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
177 : InstSystemZ<6, outs, ins, asmstr, pattern> {
179 field bits<48> SoftFail = 0;
186 let Inst{47-40} = op{15-8};
187 let Inst{39-36} = R1;
188 let Inst{35-32} = R2;
189 let Inst{31-16} = RI4;
190 let Inst{15-12} = M3;
192 let Inst{7-0} = op{7-0};
195 class InstRIEc<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
196 : InstSystemZ<6, outs, ins, asmstr, pattern> {
198 field bits<48> SoftFail = 0;
205 let Inst{47-40} = op{15-8};
206 let Inst{39-36} = R1;
207 let Inst{35-32} = M3;
208 let Inst{31-16} = RI4;
210 let Inst{7-0} = op{7-0};
213 class InstRIEd<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
214 : InstSystemZ<6, outs, ins, asmstr, pattern> {
216 field bits<48> SoftFail = 0;
222 let Inst{47-40} = op{15-8};
223 let Inst{39-36} = R1;
224 let Inst{35-32} = R3;
225 let Inst{31-16} = I2;
227 let Inst{7-0} = op{7-0};
230 class InstRIEf<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
231 : InstSystemZ<6, outs, ins, asmstr, pattern> {
233 field bits<48> SoftFail = 0;
241 let Inst{47-40} = op{15-8};
242 let Inst{39-36} = R1;
243 let Inst{35-32} = R2;
244 let Inst{31-24} = I3;
245 let Inst{23-16} = I4;
247 let Inst{7-0} = op{7-0};
250 class InstRIL<bits<12> op, dag outs, dag ins, string asmstr, list<dag> pattern>
251 : InstSystemZ<6, outs, ins, asmstr, pattern> {
253 field bits<48> SoftFail = 0;
258 let Inst{47-40} = op{11-4};
259 let Inst{39-36} = R1;
260 let Inst{35-32} = op{3-0};
264 class InstRR<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
265 : InstSystemZ<2, outs, ins, asmstr, pattern> {
267 field bits<16> SoftFail = 0;
277 class InstRRD<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
278 : InstSystemZ<4, outs, ins, asmstr, pattern> {
280 field bits<32> SoftFail = 0;
286 let Inst{31-16} = op;
287 let Inst{15-12} = R1;
293 class InstRRE<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
294 : InstSystemZ<4, outs, ins, asmstr, pattern> {
296 field bits<32> SoftFail = 0;
301 let Inst{31-16} = op;
307 class InstRRF<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
308 : InstSystemZ<4, outs, ins, asmstr, pattern> {
310 field bits<32> SoftFail = 0;
316 let Inst{31-16} = op;
317 let Inst{15-12} = R3;
323 class InstRX<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
324 : InstSystemZ<4, outs, ins, asmstr, pattern> {
326 field bits<32> SoftFail = 0;
331 let Inst{31-24} = op;
332 let Inst{23-20} = R1;
333 let Inst{19-0} = XBD2;
338 class InstRXE<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
339 : InstSystemZ<6, outs, ins, asmstr, pattern> {
341 field bits<48> SoftFail = 0;
346 let Inst{47-40} = op{15-8};
347 let Inst{39-36} = R1;
348 let Inst{35-16} = XBD2;
350 let Inst{7-0} = op{7-0};
355 class InstRXF<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
356 : InstSystemZ<6, outs, ins, asmstr, pattern> {
358 field bits<48> SoftFail = 0;
364 let Inst{47-40} = op{15-8};
365 let Inst{39-36} = R3;
366 let Inst{35-16} = XBD2;
367 let Inst{15-12} = R1;
369 let Inst{7-0} = op{7-0};
374 class InstRXY<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
375 : InstSystemZ<6, outs, ins, asmstr, pattern> {
377 field bits<48> SoftFail = 0;
382 let Inst{47-40} = op{15-8};
383 let Inst{39-36} = R1;
384 let Inst{35-8} = XBD2;
385 let Inst{7-0} = op{7-0};
387 let Has20BitOffset = 1;
391 class InstRS<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
392 : InstSystemZ<4, outs, ins, asmstr, pattern> {
394 field bits<32> SoftFail = 0;
400 let Inst{31-24} = op;
401 let Inst{23-20} = R1;
402 let Inst{19-16} = R3;
403 let Inst{15-0} = BD2;
406 class InstRSY<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
407 : InstSystemZ<6, outs, ins, asmstr, pattern> {
409 field bits<48> SoftFail = 0;
415 let Inst{47-40} = op{15-8};
416 let Inst{39-36} = R1;
417 let Inst{35-32} = R3;
418 let Inst{31-8} = BD2;
419 let Inst{7-0} = op{7-0};
421 let Has20BitOffset = 1;
424 class InstSI<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
425 : InstSystemZ<4, outs, ins, asmstr, pattern> {
427 field bits<32> SoftFail = 0;
432 let Inst{31-24} = op;
433 let Inst{23-16} = I2;
434 let Inst{15-0} = BD1;
437 class InstSIL<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
438 : InstSystemZ<6, outs, ins, asmstr, pattern> {
440 field bits<48> SoftFail = 0;
445 let Inst{47-32} = op;
446 let Inst{31-16} = BD1;
450 class InstSIY<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
451 : InstSystemZ<6, outs, ins, asmstr, pattern> {
453 field bits<48> SoftFail = 0;
458 let Inst{47-40} = op{15-8};
459 let Inst{39-32} = I2;
460 let Inst{31-8} = BD1;
461 let Inst{7-0} = op{7-0};
463 let Has20BitOffset = 1;
466 class InstSS<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
467 : InstSystemZ<6, outs, ins, asmstr, pattern> {
469 field bits<48> SoftFail = 0;
474 let Inst{47-40} = op;
475 let Inst{39-16} = BDL1;
476 let Inst{15-0} = BD2;
479 //===----------------------------------------------------------------------===//
480 // Instruction definitions with semantics
481 //===----------------------------------------------------------------------===//
483 // These classes have the form [Cond]<Category><Format>, where <Format> is one
484 // of the formats defined above and where <Category> describes the inputs
485 // and outputs. "Cond" is used if the instruction is conditional,
486 // in which case the 4-bit condition-code mask is added as a final operand.
487 // <Category> can be one of:
490 // One register output operand and no input operands.
493 // One register output operand, one register input operand and
494 // one branch displacement. The instructions stores a modified
495 // form of the source register in the destination register and
496 // branches on the result.
499 // One register or immediate input operand and one address input operand.
500 // The instruction stores the first operand to the address.
502 // This category is used for both pure and truncating stores.
505 // One address input operand and two explicit output operands.
506 // The instruction loads a range of registers from the address,
507 // with the explicit operands giving the first and last register
508 // to load. Other loaded registers are added as implicit definitions.
511 // Two explicit input register operands and an address operand.
512 // The instruction stores a range of registers to the address,
513 // with the explicit operands giving the first and last register
514 // to store. Other stored registers are added as implicit uses.
517 // One register output operand and one input operand. The input
518 // operand may be a register, immediate or memory.
521 // One register output operand and two input operands. The first
522 // input operand is always a register and he second may be a register,
523 // immediate or memory.
526 // One register output operand and two input operands. The first
527 // input operand is a register and the second has the same form as
528 // an address (although it isn't actually used to address memory).
531 // Two input operands. The first operand is always a register,
532 // the second may be a register, immediate or memory.
535 // One register output operand and three register input operands.
538 // One output operand and three input operands. The first two
539 // operands are registers and the third is an address. The instruction
540 // both reads from and writes to the address.
543 // One output operand and five input operands. The first two operands
544 // are registers and the other three are immediates.
546 // The format determines which input operands are tied to output operands,
547 // and also determines the shape of any address operand.
549 // Multiclasses of the form <Category><Format>Pair define two instructions,
550 // one with <Category><Format> and one with <Category><Format>Y. The name
551 // of the first instruction has no suffix, the name of the second has
554 //===----------------------------------------------------------------------===//
556 class InherentRRE<string mnemonic, bits<16> opcode, RegisterOperand cls,
558 : InstRRE<opcode, (outs cls:$R1), (ins),
560 [(set cls:$R1, src)]> {
564 class BranchUnaryRI<string mnemonic, bits<12> opcode, RegisterOperand cls>
565 : InstRI<opcode, (outs cls:$R1), (ins cls:$R1src, brtarget16:$I2),
566 mnemonic##"\t$R1, $I2", []> {
568 let isTerminator = 1;
569 let Constraints = "$R1 = $R1src";
570 let DisableEncoding = "$R1src";
573 class LoadMultipleRSY<string mnemonic, bits<16> opcode, RegisterOperand cls>
574 : InstRSY<opcode, (outs cls:$R1, cls:$R3), (ins bdaddr20only:$BD2),
575 mnemonic#"\t$R1, $R3, $BD2", []> {
579 class StoreRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator,
581 : InstRIL<opcode, (outs), (ins cls:$R1, pcrel32:$I2),
582 mnemonic#"\t$R1, $I2",
583 [(operator cls:$R1, pcrel32:$I2)]> {
585 // We want PC-relative addresses to be tried ahead of BD and BDX addresses.
586 // However, BDXs have two extra operands and are therefore 6 units more
588 let AddedComplexity = 7;
591 class StoreRX<string mnemonic, bits<8> opcode, SDPatternOperator operator,
592 RegisterOperand cls, bits<5> bytes,
593 AddressingMode mode = bdxaddr12only>
594 : InstRX<opcode, (outs), (ins cls:$R1, mode:$XBD2),
595 mnemonic#"\t$R1, $XBD2",
596 [(operator cls:$R1, mode:$XBD2)]> {
597 let OpKey = mnemonic ## cls;
600 let AccessBytes = bytes;
603 class StoreRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
604 RegisterOperand cls, bits<5> bytes,
605 AddressingMode mode = bdxaddr20only>
606 : InstRXY<opcode, (outs), (ins cls:$R1, mode:$XBD2),
607 mnemonic#"\t$R1, $XBD2",
608 [(operator cls:$R1, mode:$XBD2)]> {
609 let OpKey = mnemonic ## cls;
612 let AccessBytes = bytes;
615 multiclass StoreRXPair<string mnemonic, bits<8> rxOpcode, bits<16> rxyOpcode,
616 SDPatternOperator operator, RegisterOperand cls,
618 let DispKey = mnemonic ## #cls in {
619 let DispSize = "12" in
620 def "" : StoreRX<mnemonic, rxOpcode, operator, cls, bytes, bdxaddr12pair>;
621 let DispSize = "20" in
622 def Y : StoreRXY<mnemonic#"y", rxyOpcode, operator, cls, bytes,
627 class StoreMultipleRSY<string mnemonic, bits<16> opcode, RegisterOperand cls>
628 : InstRSY<opcode, (outs), (ins cls:$R1, cls:$R3, bdaddr20only:$BD2),
629 mnemonic#"\t$R1, $R3, $BD2", []> {
633 class StoreSI<string mnemonic, bits<8> opcode, SDPatternOperator operator,
634 Immediate imm, AddressingMode mode = bdaddr12only>
635 : InstSI<opcode, (outs), (ins mode:$BD1, imm:$I2),
636 mnemonic#"\t$BD1, $I2",
637 [(operator imm:$I2, mode:$BD1)]> {
641 class StoreSIY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
642 Immediate imm, AddressingMode mode = bdaddr20only>
643 : InstSIY<opcode, (outs), (ins mode:$BD1, imm:$I2),
644 mnemonic#"\t$BD1, $I2",
645 [(operator imm:$I2, mode:$BD1)]> {
649 class StoreSIL<string mnemonic, bits<16> opcode, SDPatternOperator operator,
651 : InstSIL<opcode, (outs), (ins bdaddr12only:$BD1, imm:$I2),
652 mnemonic#"\t$BD1, $I2",
653 [(operator imm:$I2, bdaddr12only:$BD1)]> {
657 multiclass StoreSIPair<string mnemonic, bits<8> siOpcode, bits<16> siyOpcode,
658 SDPatternOperator operator, Immediate imm> {
659 let DispKey = mnemonic in {
660 let DispSize = "12" in
661 def "" : StoreSI<mnemonic, siOpcode, operator, imm, bdaddr12pair>;
662 let DispSize = "20" in
663 def Y : StoreSIY<mnemonic#"y", siyOpcode, operator, imm, bdaddr20pair>;
667 class CondStoreRSY<string mnemonic, bits<16> opcode,
668 RegisterOperand cls, bits<5> bytes,
669 AddressingMode mode = bdaddr20only>
670 : InstRSY<opcode, (outs), (ins cls:$R1, mode:$BD2, cond4:$valid, cond4:$R3),
671 mnemonic#"$R3\t$R1, $BD2", []>,
672 Requires<[FeatureLoadStoreOnCond]> {
674 let AccessBytes = bytes;
678 // Like CondStoreRSY, but used for the raw assembly form. The condition-code
679 // mask is the third operand rather than being part of the mnemonic.
680 class AsmCondStoreRSY<string mnemonic, bits<16> opcode,
681 RegisterOperand cls, bits<5> bytes,
682 AddressingMode mode = bdaddr20only>
683 : InstRSY<opcode, (outs), (ins cls:$R1, mode:$BD2, uimm8zx4:$R3),
684 mnemonic#"\t$R1, $BD2, $R3", []>,
685 Requires<[FeatureLoadStoreOnCond]> {
687 let AccessBytes = bytes;
690 // Like CondStoreRSY, but with a fixed CC mask.
691 class FixedCondStoreRSY<string mnemonic, bits<16> opcode,
692 RegisterOperand cls, bits<4> ccmask, bits<5> bytes,
693 AddressingMode mode = bdaddr20only>
694 : InstRSY<opcode, (outs), (ins cls:$R1, mode:$BD2),
695 mnemonic#"\t$R1, $BD2", []>,
696 Requires<[FeatureLoadStoreOnCond]> {
698 let AccessBytes = bytes;
702 class UnaryRR<string mnemonic, bits<8> opcode, SDPatternOperator operator,
703 RegisterOperand cls1, RegisterOperand cls2>
704 : InstRR<opcode, (outs cls1:$R1), (ins cls2:$R2),
705 mnemonic#"r\t$R1, $R2",
706 [(set cls1:$R1, (operator cls2:$R2))]> {
707 let OpKey = mnemonic ## cls1;
711 class UnaryRRE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
712 RegisterOperand cls1, RegisterOperand cls2>
713 : InstRRE<opcode, (outs cls1:$R1), (ins cls2:$R2),
714 mnemonic#"r\t$R1, $R2",
715 [(set cls1:$R1, (operator cls2:$R2))]> {
716 let OpKey = mnemonic ## cls1;
720 class UnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1,
721 RegisterOperand cls2>
722 : InstRRF<opcode, (outs cls1:$R1), (ins uimm8zx4:$R3, cls2:$R2),
723 mnemonic#"r\t$R1, $R3, $R2", []> {
724 let OpKey = mnemonic ## cls1;
728 // These instructions are generated by if conversion. The old value of R1
729 // is added as an implicit use.
730 class CondUnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1,
731 RegisterOperand cls2>
732 : InstRRF<opcode, (outs cls1:$R1), (ins cls2:$R2, cond4:$valid, cond4:$R3),
733 mnemonic#"r$R3\t$R1, $R2", []>,
734 Requires<[FeatureLoadStoreOnCond]> {
738 // Like CondUnaryRRF, but used for the raw assembly form. The condition-code
739 // mask is the third operand rather than being part of the mnemonic.
740 class AsmCondUnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1,
741 RegisterOperand cls2>
742 : InstRRF<opcode, (outs cls1:$R1), (ins cls1:$R1src, cls2:$R2, uimm8zx4:$R3),
743 mnemonic#"r\t$R1, $R2, $R3", []>,
744 Requires<[FeatureLoadStoreOnCond]> {
745 let Constraints = "$R1 = $R1src";
746 let DisableEncoding = "$R1src";
749 // Like CondUnaryRRF, but with a fixed CC mask.
750 class FixedCondUnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1,
751 RegisterOperand cls2, bits<4> ccmask>
752 : InstRRF<opcode, (outs cls1:$R1), (ins cls1:$R1src, cls2:$R2),
753 mnemonic#"\t$R1, $R2", []>,
754 Requires<[FeatureLoadStoreOnCond]> {
755 let Constraints = "$R1 = $R1src";
756 let DisableEncoding = "$R1src";
760 class UnaryRI<string mnemonic, bits<12> opcode, SDPatternOperator operator,
761 RegisterOperand cls, Immediate imm>
762 : InstRI<opcode, (outs cls:$R1), (ins imm:$I2),
763 mnemonic#"\t$R1, $I2",
764 [(set cls:$R1, (operator imm:$I2))]>;
766 class UnaryRIL<string mnemonic, bits<12> opcode, SDPatternOperator operator,
767 RegisterOperand cls, Immediate imm>
768 : InstRIL<opcode, (outs cls:$R1), (ins imm:$I2),
769 mnemonic#"\t$R1, $I2",
770 [(set cls:$R1, (operator imm:$I2))]>;
772 class UnaryRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator,
774 : InstRIL<opcode, (outs cls:$R1), (ins pcrel32:$I2),
775 mnemonic#"\t$R1, $I2",
776 [(set cls:$R1, (operator pcrel32:$I2))]> {
778 // We want PC-relative addresses to be tried ahead of BD and BDX addresses.
779 // However, BDXs have two extra operands and are therefore 6 units more
781 let AddedComplexity = 7;
784 class CondUnaryRSY<string mnemonic, bits<16> opcode,
785 SDPatternOperator operator, RegisterOperand cls,
786 bits<5> bytes, AddressingMode mode = bdaddr20only>
787 : InstRSY<opcode, (outs cls:$R1),
788 (ins cls:$R1src, mode:$BD2, cond4:$valid, cond4:$R3),
789 mnemonic#"$R3\t$R1, $BD2",
791 (z_select_ccmask (load bdaddr20only:$BD2), cls:$R1src,
792 cond4:$valid, cond4:$R3))]>,
793 Requires<[FeatureLoadStoreOnCond]> {
794 let Constraints = "$R1 = $R1src";
795 let DisableEncoding = "$R1src";
797 let AccessBytes = bytes;
801 // Like CondUnaryRSY, but used for the raw assembly form. The condition-code
802 // mask is the third operand rather than being part of the mnemonic.
803 class AsmCondUnaryRSY<string mnemonic, bits<16> opcode,
804 RegisterOperand cls, bits<5> bytes,
805 AddressingMode mode = bdaddr20only>
806 : InstRSY<opcode, (outs cls:$R1), (ins cls:$R1src, mode:$BD2, uimm8zx4:$R3),
807 mnemonic#"\t$R1, $BD2, $R3", []>,
808 Requires<[FeatureLoadStoreOnCond]> {
810 let AccessBytes = bytes;
811 let Constraints = "$R1 = $R1src";
812 let DisableEncoding = "$R1src";
815 // Like CondUnaryRSY, but with a fixed CC mask.
816 class FixedCondUnaryRSY<string mnemonic, bits<16> opcode,
817 RegisterOperand cls, bits<4> ccmask, bits<5> bytes,
818 AddressingMode mode = bdaddr20only>
819 : InstRSY<opcode, (outs cls:$R1), (ins cls:$R1src, mode:$BD2),
820 mnemonic#"\t$R1, $BD2", []>,
821 Requires<[FeatureLoadStoreOnCond]> {
822 let Constraints = "$R1 = $R1src";
823 let DisableEncoding = "$R1src";
826 let AccessBytes = bytes;
829 class UnaryRX<string mnemonic, bits<8> opcode, SDPatternOperator operator,
830 RegisterOperand cls, bits<5> bytes,
831 AddressingMode mode = bdxaddr12only>
832 : InstRX<opcode, (outs cls:$R1), (ins mode:$XBD2),
833 mnemonic#"\t$R1, $XBD2",
834 [(set cls:$R1, (operator mode:$XBD2))]> {
835 let OpKey = mnemonic ## cls;
838 let AccessBytes = bytes;
841 class UnaryRXE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
842 RegisterOperand cls, bits<5> bytes>
843 : InstRXE<opcode, (outs cls:$R1), (ins bdxaddr12only:$XBD2),
844 mnemonic#"\t$R1, $XBD2",
845 [(set cls:$R1, (operator bdxaddr12only:$XBD2))]> {
846 let OpKey = mnemonic ## cls;
849 let AccessBytes = bytes;
852 class UnaryRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
853 RegisterOperand cls, bits<5> bytes,
854 AddressingMode mode = bdxaddr20only>
855 : InstRXY<opcode, (outs cls:$R1), (ins mode:$XBD2),
856 mnemonic#"\t$R1, $XBD2",
857 [(set cls:$R1, (operator mode:$XBD2))]> {
858 let OpKey = mnemonic ## cls;
861 let AccessBytes = bytes;
864 multiclass UnaryRXPair<string mnemonic, bits<8> rxOpcode, bits<16> rxyOpcode,
865 SDPatternOperator operator, RegisterOperand cls,
867 let DispKey = mnemonic ## #cls in {
868 let DispSize = "12" in
869 def "" : UnaryRX<mnemonic, rxOpcode, operator, cls, bytes, bdxaddr12pair>;
870 let DispSize = "20" in
871 def Y : UnaryRXY<mnemonic#"y", rxyOpcode, operator, cls, bytes,
876 class BinaryRR<string mnemonic, bits<8> opcode, SDPatternOperator operator,
877 RegisterOperand cls1, RegisterOperand cls2>
878 : InstRR<opcode, (outs cls1:$R1), (ins cls1:$R1src, cls2:$R2),
879 mnemonic#"r\t$R1, $R2",
880 [(set cls1:$R1, (operator cls1:$R1src, cls2:$R2))]> {
881 let OpKey = mnemonic ## cls1;
883 let Constraints = "$R1 = $R1src";
884 let DisableEncoding = "$R1src";
887 class BinaryRRE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
888 RegisterOperand cls1, RegisterOperand cls2>
889 : InstRRE<opcode, (outs cls1:$R1), (ins cls1:$R1src, cls2:$R2),
890 mnemonic#"r\t$R1, $R2",
891 [(set cls1:$R1, (operator cls1:$R1src, cls2:$R2))]> {
892 let OpKey = mnemonic ## cls1;
894 let Constraints = "$R1 = $R1src";
895 let DisableEncoding = "$R1src";
898 class BinaryRRF<string mnemonic, bits<16> opcode, SDPatternOperator operator,
899 RegisterOperand cls1, RegisterOperand cls2>
900 : InstRRF<opcode, (outs cls1:$R1), (ins cls1:$R3, cls2:$R2),
901 mnemonic#"r\t$R1, $R3, $R2",
902 [(set cls1:$R1, (operator cls1:$R3, cls2:$R2))]> {
903 let OpKey = mnemonic ## cls1;
907 class BinaryRRFK<string mnemonic, bits<16> opcode, SDPatternOperator operator,
908 RegisterOperand cls1, RegisterOperand cls2>
909 : InstRRF<opcode, (outs cls1:$R1), (ins cls1:$R2, cls2:$R3),
910 mnemonic#"rk\t$R1, $R2, $R3",
911 [(set cls1:$R1, (operator cls1:$R2, cls2:$R3))]>;
913 multiclass BinaryRRAndK<string mnemonic, bits<8> opcode1, bits<16> opcode2,
914 SDPatternOperator operator, RegisterOperand cls1,
915 RegisterOperand cls2> {
916 let NumOpsKey = mnemonic in {
917 let NumOpsValue = "3" in
918 def K : BinaryRRFK<mnemonic, opcode2, null_frag, cls1, cls2>,
919 Requires<[FeatureDistinctOps]>;
920 let NumOpsValue = "2", isConvertibleToThreeAddress = 1 in
921 def "" : BinaryRR<mnemonic, opcode1, operator, cls1, cls2>;
925 multiclass BinaryRREAndK<string mnemonic, bits<16> opcode1, bits<16> opcode2,
926 SDPatternOperator operator, RegisterOperand cls1,
927 RegisterOperand cls2> {
928 let NumOpsKey = mnemonic in {
929 let NumOpsValue = "3" in
930 def K : BinaryRRFK<mnemonic, opcode2, null_frag, cls1, cls2>,
931 Requires<[FeatureDistinctOps]>;
932 let NumOpsValue = "2", isConvertibleToThreeAddress = 1 in
933 def "" : BinaryRRE<mnemonic, opcode1, operator, cls1, cls2>;
937 class BinaryRI<string mnemonic, bits<12> opcode, SDPatternOperator operator,
938 RegisterOperand cls, Immediate imm>
939 : InstRI<opcode, (outs cls:$R1), (ins cls:$R1src, imm:$I2),
940 mnemonic#"\t$R1, $I2",
941 [(set cls:$R1, (operator cls:$R1src, imm:$I2))]> {
942 let Constraints = "$R1 = $R1src";
943 let DisableEncoding = "$R1src";
946 class BinaryRIE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
947 RegisterOperand cls, Immediate imm>
948 : InstRIEd<opcode, (outs cls:$R1), (ins cls:$R3, imm:$I2),
949 mnemonic#"\t$R1, $R3, $I2",
950 [(set cls:$R1, (operator cls:$R3, imm:$I2))]>;
952 multiclass BinaryRIAndK<string mnemonic, bits<12> opcode1, bits<16> opcode2,
953 SDPatternOperator operator, RegisterOperand cls,
955 let NumOpsKey = mnemonic in {
956 let NumOpsValue = "3" in
957 def K : BinaryRIE<mnemonic##"k", opcode2, null_frag, cls, imm>,
958 Requires<[FeatureDistinctOps]>;
959 let NumOpsValue = "2", isConvertibleToThreeAddress = 1 in
960 def "" : BinaryRI<mnemonic, opcode1, operator, cls, imm>;
964 class BinaryRIL<string mnemonic, bits<12> opcode, SDPatternOperator operator,
965 RegisterOperand cls, Immediate imm>
966 : InstRIL<opcode, (outs cls:$R1), (ins cls:$R1src, imm:$I2),
967 mnemonic#"\t$R1, $I2",
968 [(set cls:$R1, (operator cls:$R1src, imm:$I2))]> {
969 let Constraints = "$R1 = $R1src";
970 let DisableEncoding = "$R1src";
973 class BinaryRX<string mnemonic, bits<8> opcode, SDPatternOperator operator,
974 RegisterOperand cls, SDPatternOperator load, bits<5> bytes,
975 AddressingMode mode = bdxaddr12only>
976 : InstRX<opcode, (outs cls:$R1), (ins cls:$R1src, mode:$XBD2),
977 mnemonic#"\t$R1, $XBD2",
978 [(set cls:$R1, (operator cls:$R1src, (load mode:$XBD2)))]> {
979 let OpKey = mnemonic ## cls;
981 let Constraints = "$R1 = $R1src";
982 let DisableEncoding = "$R1src";
984 let AccessBytes = bytes;
987 class BinaryRXE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
988 RegisterOperand cls, SDPatternOperator load, bits<5> bytes>
989 : InstRXE<opcode, (outs cls:$R1), (ins cls:$R1src, bdxaddr12only:$XBD2),
990 mnemonic#"\t$R1, $XBD2",
991 [(set cls:$R1, (operator cls:$R1src,
992 (load bdxaddr12only:$XBD2)))]> {
993 let OpKey = mnemonic ## cls;
995 let Constraints = "$R1 = $R1src";
996 let DisableEncoding = "$R1src";
998 let AccessBytes = bytes;
1001 class BinaryRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1002 RegisterOperand cls, SDPatternOperator load, bits<5> bytes,
1003 AddressingMode mode = bdxaddr20only>
1004 : InstRXY<opcode, (outs cls:$R1), (ins cls:$R1src, mode:$XBD2),
1005 mnemonic#"\t$R1, $XBD2",
1006 [(set cls:$R1, (operator cls:$R1src, (load mode:$XBD2)))]> {
1007 let OpKey = mnemonic ## cls;
1009 let Constraints = "$R1 = $R1src";
1010 let DisableEncoding = "$R1src";
1012 let AccessBytes = bytes;
1015 multiclass BinaryRXPair<string mnemonic, bits<8> rxOpcode, bits<16> rxyOpcode,
1016 SDPatternOperator operator, RegisterOperand cls,
1017 SDPatternOperator load, bits<5> bytes> {
1018 let DispKey = mnemonic ## #cls in {
1019 let DispSize = "12" in
1020 def "" : BinaryRX<mnemonic, rxOpcode, operator, cls, load, bytes,
1022 let DispSize = "20" in
1023 def Y : BinaryRXY<mnemonic#"y", rxyOpcode, operator, cls, load, bytes,
1028 class BinarySI<string mnemonic, bits<8> opcode, SDPatternOperator operator,
1029 Operand imm, AddressingMode mode = bdaddr12only>
1030 : InstSI<opcode, (outs), (ins mode:$BD1, imm:$I2),
1031 mnemonic#"\t$BD1, $I2",
1032 [(store (operator (load mode:$BD1), imm:$I2), mode:$BD1)]> {
1037 class BinarySIY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1038 Operand imm, AddressingMode mode = bdaddr20only>
1039 : InstSIY<opcode, (outs), (ins mode:$BD1, imm:$I2),
1040 mnemonic#"\t$BD1, $I2",
1041 [(store (operator (load mode:$BD1), imm:$I2), mode:$BD1)]> {
1046 multiclass BinarySIPair<string mnemonic, bits<8> siOpcode,
1047 bits<16> siyOpcode, SDPatternOperator operator,
1049 let DispKey = mnemonic ## #cls in {
1050 let DispSize = "12" in
1051 def "" : BinarySI<mnemonic, siOpcode, operator, imm, bdaddr12pair>;
1052 let DispSize = "20" in
1053 def Y : BinarySIY<mnemonic#"y", siyOpcode, operator, imm, bdaddr20pair>;
1057 class ShiftRS<string mnemonic, bits<8> opcode, SDPatternOperator operator,
1058 RegisterOperand cls>
1059 : InstRS<opcode, (outs cls:$R1), (ins cls:$R1src, shift12only:$BD2),
1060 mnemonic#"\t$R1, $BD2",
1061 [(set cls:$R1, (operator cls:$R1src, shift12only:$BD2))]> {
1063 let Constraints = "$R1 = $R1src";
1064 let DisableEncoding = "$R1src";
1067 class ShiftRSY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1068 RegisterOperand cls>
1069 : InstRSY<opcode, (outs cls:$R1), (ins cls:$R3, shift20only:$BD2),
1070 mnemonic#"\t$R1, $R3, $BD2",
1071 [(set cls:$R1, (operator cls:$R3, shift20only:$BD2))]>;
1073 multiclass ShiftRSAndK<string mnemonic, bits<8> opcode1, bits<16> opcode2,
1074 SDPatternOperator operator, RegisterOperand cls> {
1075 let NumOpsKey = mnemonic in {
1076 let NumOpsValue = "3" in
1077 def K : ShiftRSY<mnemonic##"k", opcode2, null_frag, cls>,
1078 Requires<[FeatureDistinctOps]>;
1079 let NumOpsValue = "2", isConvertibleToThreeAddress = 1 in
1080 def "" : ShiftRS<mnemonic, opcode1, operator, cls>;
1084 class CompareRR<string mnemonic, bits<8> opcode, SDPatternOperator operator,
1085 RegisterOperand cls1, RegisterOperand cls2>
1086 : InstRR<opcode, (outs), (ins cls1:$R1, cls2:$R2),
1087 mnemonic#"r\t$R1, $R2",
1088 [(operator cls1:$R1, cls2:$R2)]> {
1089 let OpKey = mnemonic ## cls1;
1094 class CompareRRE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1095 RegisterOperand cls1, RegisterOperand cls2>
1096 : InstRRE<opcode, (outs), (ins cls1:$R1, cls2:$R2),
1097 mnemonic#"r\t$R1, $R2",
1098 [(operator cls1:$R1, cls2:$R2)]> {
1099 let OpKey = mnemonic ## cls1;
1104 class CompareRI<string mnemonic, bits<12> opcode, SDPatternOperator operator,
1105 RegisterOperand cls, Immediate imm>
1106 : InstRI<opcode, (outs), (ins cls:$R1, imm:$I2),
1107 mnemonic#"\t$R1, $I2",
1108 [(operator cls:$R1, imm:$I2)]> {
1112 class CompareRIL<string mnemonic, bits<12> opcode, SDPatternOperator operator,
1113 RegisterOperand cls, Immediate imm>
1114 : InstRIL<opcode, (outs), (ins cls:$R1, imm:$I2),
1115 mnemonic#"\t$R1, $I2",
1116 [(operator cls:$R1, imm:$I2)]> {
1120 class CompareRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator,
1121 RegisterOperand cls, SDPatternOperator load>
1122 : InstRIL<opcode, (outs), (ins cls:$R1, pcrel32:$I2),
1123 mnemonic#"\t$R1, $I2",
1124 [(operator cls:$R1, (load pcrel32:$I2))]> {
1127 // We want PC-relative addresses to be tried ahead of BD and BDX addresses.
1128 // However, BDXs have two extra operands and are therefore 6 units more
1130 let AddedComplexity = 7;
1133 class CompareRX<string mnemonic, bits<8> opcode, SDPatternOperator operator,
1134 RegisterOperand cls, SDPatternOperator load, bits<5> bytes,
1135 AddressingMode mode = bdxaddr12only>
1136 : InstRX<opcode, (outs), (ins cls:$R1, mode:$XBD2),
1137 mnemonic#"\t$R1, $XBD2",
1138 [(operator cls:$R1, (load mode:$XBD2))]> {
1139 let OpKey = mnemonic ## cls;
1143 let AccessBytes = bytes;
1146 class CompareRXE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1147 RegisterOperand cls, SDPatternOperator load, bits<5> bytes>
1148 : InstRXE<opcode, (outs), (ins cls:$R1, bdxaddr12only:$XBD2),
1149 mnemonic#"\t$R1, $XBD2",
1150 [(operator cls:$R1, (load bdxaddr12only:$XBD2))]> {
1151 let OpKey = mnemonic ## cls;
1155 let AccessBytes = bytes;
1158 class CompareRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1159 RegisterOperand cls, SDPatternOperator load, bits<5> bytes,
1160 AddressingMode mode = bdxaddr20only>
1161 : InstRXY<opcode, (outs), (ins cls:$R1, mode:$XBD2),
1162 mnemonic#"\t$R1, $XBD2",
1163 [(operator cls:$R1, (load mode:$XBD2))]> {
1164 let OpKey = mnemonic ## cls;
1168 let AccessBytes = bytes;
1171 multiclass CompareRXPair<string mnemonic, bits<8> rxOpcode, bits<16> rxyOpcode,
1172 SDPatternOperator operator, RegisterOperand cls,
1173 SDPatternOperator load, bits<5> bytes> {
1174 let DispKey = mnemonic ## #cls in {
1175 let DispSize = "12" in
1176 def "" : CompareRX<mnemonic, rxOpcode, operator, cls,
1177 load, bytes, bdxaddr12pair>;
1178 let DispSize = "20" in
1179 def Y : CompareRXY<mnemonic#"y", rxyOpcode, operator, cls,
1180 load, bytes, bdxaddr20pair>;
1184 class CompareSI<string mnemonic, bits<8> opcode, SDPatternOperator operator,
1185 SDPatternOperator load, Immediate imm,
1186 AddressingMode mode = bdaddr12only>
1187 : InstSI<opcode, (outs), (ins mode:$BD1, imm:$I2),
1188 mnemonic#"\t$BD1, $I2",
1189 [(operator (load mode:$BD1), imm:$I2)]> {
1194 class CompareSIL<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1195 SDPatternOperator load, Immediate imm>
1196 : InstSIL<opcode, (outs), (ins bdaddr12only:$BD1, imm:$I2),
1197 mnemonic#"\t$BD1, $I2",
1198 [(operator (load bdaddr12only:$BD1), imm:$I2)]> {
1203 class CompareSIY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1204 SDPatternOperator load, Immediate imm,
1205 AddressingMode mode = bdaddr20only>
1206 : InstSIY<opcode, (outs), (ins mode:$BD1, imm:$I2),
1207 mnemonic#"\t$BD1, $I2",
1208 [(operator (load mode:$BD1), imm:$I2)]> {
1213 multiclass CompareSIPair<string mnemonic, bits<8> siOpcode, bits<16> siyOpcode,
1214 SDPatternOperator operator, SDPatternOperator load,
1216 let DispKey = mnemonic in {
1217 let DispSize = "12" in
1218 def "" : CompareSI<mnemonic, siOpcode, operator, load, imm, bdaddr12pair>;
1219 let DispSize = "20" in
1220 def Y : CompareSIY<mnemonic#"y", siyOpcode, operator, load, imm,
1225 class TernaryRRD<string mnemonic, bits<16> opcode,
1226 SDPatternOperator operator, RegisterOperand cls>
1227 : InstRRD<opcode, (outs cls:$R1), (ins cls:$R1src, cls:$R3, cls:$R2),
1228 mnemonic#"r\t$R1, $R3, $R2",
1229 [(set cls:$R1, (operator cls:$R1src, cls:$R3, cls:$R2))]> {
1230 let OpKey = mnemonic ## cls;
1232 let Constraints = "$R1 = $R1src";
1233 let DisableEncoding = "$R1src";
1236 class TernaryRXF<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1237 RegisterOperand cls, SDPatternOperator load, bits<5> bytes>
1238 : InstRXF<opcode, (outs cls:$R1),
1239 (ins cls:$R1src, cls:$R3, bdxaddr12only:$XBD2),
1240 mnemonic#"\t$R1, $R3, $XBD2",
1241 [(set cls:$R1, (operator cls:$R1src, cls:$R3,
1242 (load bdxaddr12only:$XBD2)))]> {
1243 let OpKey = mnemonic ## cls;
1245 let Constraints = "$R1 = $R1src";
1246 let DisableEncoding = "$R1src";
1248 let AccessBytes = bytes;
1251 class CmpSwapRS<string mnemonic, bits<8> opcode, SDPatternOperator operator,
1252 RegisterOperand cls, AddressingMode mode = bdaddr12only>
1253 : InstRS<opcode, (outs cls:$R1), (ins cls:$R1src, cls:$R3, mode:$BD2),
1254 mnemonic#"\t$R1, $R3, $BD2",
1255 [(set cls:$R1, (operator mode:$BD2, cls:$R1src, cls:$R3))]> {
1256 let Constraints = "$R1 = $R1src";
1257 let DisableEncoding = "$R1src";
1262 class CmpSwapRSY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1263 RegisterOperand cls, AddressingMode mode = bdaddr20only>
1264 : InstRSY<opcode, (outs cls:$R1), (ins cls:$R1src, cls:$R3, mode:$BD2),
1265 mnemonic#"\t$R1, $R3, $BD2",
1266 [(set cls:$R1, (operator mode:$BD2, cls:$R1src, cls:$R3))]> {
1267 let Constraints = "$R1 = $R1src";
1268 let DisableEncoding = "$R1src";
1273 multiclass CmpSwapRSPair<string mnemonic, bits<8> rsOpcode, bits<16> rsyOpcode,
1274 SDPatternOperator operator, RegisterOperand cls> {
1275 let DispKey = mnemonic ## #cls in {
1276 let DispSize = "12" in
1277 def "" : CmpSwapRS<mnemonic, rsOpcode, operator, cls, bdaddr12pair>;
1278 let DispSize = "20" in
1279 def Y : CmpSwapRSY<mnemonic#"y", rsyOpcode, operator, cls, bdaddr20pair>;
1283 class RotateSelectRIEf<string mnemonic, bits<16> opcode, RegisterOperand cls1,
1284 RegisterOperand cls2>
1285 : InstRIEf<opcode, (outs cls1:$R1),
1286 (ins cls1:$R1src, cls2:$R2, uimm8:$I3, uimm8:$I4, uimm8zx6:$I5),
1287 mnemonic#"\t$R1, $R2, $I3, $I4, $I5", []> {
1288 let Constraints = "$R1 = $R1src";
1289 let DisableEncoding = "$R1src";
1292 // A floating-point load-and test operation. Create both a normal unary
1293 // operation and one that acts as a comparison against zero.
1294 multiclass LoadAndTestRRE<string mnemonic, bits<16> opcode,
1295 RegisterOperand cls> {
1296 def "" : UnaryRRE<mnemonic, opcode, null_frag, cls, cls>;
1297 let isCodeGenOnly = 1 in
1298 def Compare : CompareRRE<mnemonic, opcode, null_frag, cls, cls>;
1301 //===----------------------------------------------------------------------===//
1302 // Pseudo instructions
1303 //===----------------------------------------------------------------------===//
1305 // Convenience instructions that get lowered to real instructions
1306 // by either SystemZTargetLowering::EmitInstrWithCustomInserter()
1307 // or SystemZInstrInfo::expandPostRAPseudo().
1309 //===----------------------------------------------------------------------===//
1311 class Pseudo<dag outs, dag ins, list<dag> pattern>
1312 : InstSystemZ<0, outs, ins, "", pattern> {
1314 let isCodeGenOnly = 1;
1317 // Implements "$dst = $cc & (8 >> CC) ? $src1 : $src2", where CC is
1318 // the value of the PSW's 2-bit condition code field.
1319 class SelectWrapper<RegisterOperand cls>
1320 : Pseudo<(outs cls:$dst),
1321 (ins cls:$src1, cls:$src2, uimm8zx4:$valid, uimm8zx4:$cc),
1322 [(set cls:$dst, (z_select_ccmask cls:$src1, cls:$src2,
1323 uimm8zx4:$valid, uimm8zx4:$cc))]> {
1324 let usesCustomInserter = 1;
1325 // Although the instructions used by these nodes do not in themselves
1326 // change CC, the insertion requires new blocks, and CC cannot be live
1332 // Stores $new to $addr if $cc is true ("" case) or false (Inv case).
1333 multiclass CondStores<RegisterOperand cls, SDPatternOperator store,
1334 SDPatternOperator load, AddressingMode mode> {
1335 let Defs = [CC], Uses = [CC], usesCustomInserter = 1 in {
1336 def "" : Pseudo<(outs),
1337 (ins cls:$new, mode:$addr, uimm8zx4:$valid, uimm8zx4:$cc),
1338 [(store (z_select_ccmask cls:$new, (load mode:$addr),
1339 uimm8zx4:$valid, uimm8zx4:$cc),
1341 def Inv : Pseudo<(outs),
1342 (ins cls:$new, mode:$addr, uimm8zx4:$valid, uimm8zx4:$cc),
1343 [(store (z_select_ccmask (load mode:$addr), cls:$new,
1344 uimm8zx4:$valid, uimm8zx4:$cc),
1349 // OPERATOR is ATOMIC_SWAP or an ATOMIC_LOAD_* operation. PAT and OPERAND
1350 // describe the second (non-memory) operand.
1351 class AtomicLoadBinary<SDPatternOperator operator, RegisterOperand cls,
1352 dag pat, DAGOperand operand>
1353 : Pseudo<(outs cls:$dst), (ins bdaddr20only:$ptr, operand:$src2),
1354 [(set cls:$dst, (operator bdaddr20only:$ptr, pat))]> {
1356 let Has20BitOffset = 1;
1359 let usesCustomInserter = 1;
1362 // Specializations of AtomicLoadWBinary.
1363 class AtomicLoadBinaryReg32<SDPatternOperator operator>
1364 : AtomicLoadBinary<operator, GR32, (i32 GR32:$src2), GR32>;
1365 class AtomicLoadBinaryImm32<SDPatternOperator operator, Immediate imm>
1366 : AtomicLoadBinary<operator, GR32, (i32 imm:$src2), imm>;
1367 class AtomicLoadBinaryReg64<SDPatternOperator operator>
1368 : AtomicLoadBinary<operator, GR64, (i64 GR64:$src2), GR64>;
1369 class AtomicLoadBinaryImm64<SDPatternOperator operator, Immediate imm>
1370 : AtomicLoadBinary<operator, GR64, (i64 imm:$src2), imm>;
1372 // OPERATOR is ATOMIC_SWAPW or an ATOMIC_LOADW_* operation. PAT and OPERAND
1373 // describe the second (non-memory) operand.
1374 class AtomicLoadWBinary<SDPatternOperator operator, dag pat,
1376 : Pseudo<(outs GR32:$dst),
1377 (ins bdaddr20only:$ptr, operand:$src2, ADDR32:$bitshift,
1378 ADDR32:$negbitshift, uimm32:$bitsize),
1379 [(set GR32:$dst, (operator bdaddr20only:$ptr, pat, ADDR32:$bitshift,
1380 ADDR32:$negbitshift, uimm32:$bitsize))]> {
1382 let Has20BitOffset = 1;
1385 let usesCustomInserter = 1;
1388 // Specializations of AtomicLoadWBinary.
1389 class AtomicLoadWBinaryReg<SDPatternOperator operator>
1390 : AtomicLoadWBinary<operator, (i32 GR32:$src2), GR32>;
1391 class AtomicLoadWBinaryImm<SDPatternOperator operator, Immediate imm>
1392 : AtomicLoadWBinary<operator, (i32 imm:$src2), imm>;