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 let TSFlags{0} = SimpleBDXLoad;
65 let TSFlags{1} = SimpleBDXStore;
66 let TSFlags{2} = Has20BitOffset;
67 let TSFlags{3} = HasIndex;
68 let TSFlags{4} = Is128Bit;
69 let TSFlags{9-5} = AccessBytes;
72 //===----------------------------------------------------------------------===//
73 // Mappings between instructions
74 //===----------------------------------------------------------------------===//
76 // Return the version of an instruction that has an unsigned 12-bit
78 def getDisp12Opcode : InstrMapping {
79 let FilterClass = "InstSystemZ";
80 let RowFields = ["DispKey"];
81 let ColFields = ["DispSize"];
83 let ValueCols = [["12"]];
86 // Return the version of an instruction that has a signed 20-bit displacement.
87 def getDisp20Opcode : InstrMapping {
88 let FilterClass = "InstSystemZ";
89 let RowFields = ["DispKey"];
90 let ColFields = ["DispSize"];
92 let ValueCols = [["20"]];
95 // Return the memory form of a register instruction.
96 def getMemOpcode : InstrMapping {
97 let FilterClass = "InstSystemZ";
98 let RowFields = ["OpKey"];
99 let ColFields = ["OpType"];
100 let KeyCol = ["reg"];
101 let ValueCols = [["mem"]];
104 // Return the 3-operand form of a 2-operand instruction.
105 def getThreeOperandOpcode : InstrMapping {
106 let FilterClass = "InstSystemZ";
107 let RowFields = ["NumOpsKey"];
108 let ColFields = ["NumOpsValue"];
110 let ValueCols = [["3"]];
113 //===----------------------------------------------------------------------===//
114 // Instruction formats
115 //===----------------------------------------------------------------------===//
117 // Formats are specified using operand field declarations of the form:
119 // bits<4> Rn : register input or output for operand n
120 // bits<m> In : immediate value of width m for operand n
121 // bits<4> BDn : address operand n, which has a base and a displacement
122 // bits<m> XBDn : address operand n, which has an index, a base and a
124 // bits<4> Xn : index register for address operand n
125 // bits<4> Mn : mode value for operand n
127 // The operand numbers ("n" in the list above) follow the architecture manual.
128 // Assembly operands sometimes have a different order; in particular, R3 often
129 // is often written between operands 1 and 2.
131 //===----------------------------------------------------------------------===//
133 class InstRI<bits<12> op, dag outs, dag ins, string asmstr, list<dag> pattern>
134 : InstSystemZ<4, outs, ins, asmstr, pattern> {
136 field bits<32> SoftFail = 0;
141 let Inst{31-24} = op{11-4};
142 let Inst{23-20} = R1;
143 let Inst{19-16} = op{3-0};
147 class InstRIEb<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
148 : InstSystemZ<6, outs, ins, asmstr, pattern> {
150 field bits<48> SoftFail = 0;
157 let Inst{47-40} = op{15-8};
158 let Inst{39-36} = R1;
159 let Inst{35-32} = R2;
160 let Inst{31-16} = RI4;
161 let Inst{15-12} = M3;
163 let Inst{7-0} = op{7-0};
166 class InstRIEc<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
167 : InstSystemZ<6, outs, ins, asmstr, pattern> {
169 field bits<48> SoftFail = 0;
176 let Inst{47-40} = op{15-8};
177 let Inst{39-36} = R1;
178 let Inst{35-32} = M3;
179 let Inst{31-16} = RI4;
181 let Inst{7-0} = op{7-0};
184 class InstRIEf<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
185 : InstSystemZ<6, outs, ins, asmstr, pattern> {
187 field bits<48> SoftFail = 0;
195 let Inst{47-40} = op{15-8};
196 let Inst{39-36} = R1;
197 let Inst{35-32} = R2;
198 let Inst{31-24} = I3;
199 let Inst{23-16} = I4;
201 let Inst{7-0} = op{7-0};
204 class InstRIL<bits<12> op, dag outs, dag ins, string asmstr, list<dag> pattern>
205 : InstSystemZ<6, outs, ins, asmstr, pattern> {
207 field bits<48> SoftFail = 0;
212 let Inst{47-40} = op{11-4};
213 let Inst{39-36} = R1;
214 let Inst{35-32} = op{3-0};
218 class InstRR<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
219 : InstSystemZ<2, outs, ins, asmstr, pattern> {
221 field bits<16> SoftFail = 0;
231 class InstRRD<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
232 : InstSystemZ<4, outs, ins, asmstr, pattern> {
234 field bits<32> SoftFail = 0;
240 let Inst{31-16} = op;
241 let Inst{15-12} = R1;
247 class InstRRE<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
248 : InstSystemZ<4, outs, ins, asmstr, pattern> {
250 field bits<32> SoftFail = 0;
255 let Inst{31-16} = op;
261 class InstRRF<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
262 : InstSystemZ<4, outs, ins, asmstr, pattern> {
264 field bits<32> SoftFail = 0;
270 let Inst{31-16} = op;
271 let Inst{15-12} = R3;
277 class InstRX<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
278 : InstSystemZ<4, outs, ins, asmstr, pattern> {
280 field bits<32> SoftFail = 0;
285 let Inst{31-24} = op;
286 let Inst{23-20} = R1;
287 let Inst{19-0} = XBD2;
292 class InstRXE<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
293 : InstSystemZ<6, outs, ins, asmstr, pattern> {
295 field bits<48> SoftFail = 0;
300 let Inst{47-40} = op{15-8};
301 let Inst{39-36} = R1;
302 let Inst{35-16} = XBD2;
304 let Inst{7-0} = op{7-0};
309 class InstRXF<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
310 : InstSystemZ<6, outs, ins, asmstr, pattern> {
312 field bits<48> SoftFail = 0;
318 let Inst{47-40} = op{15-8};
319 let Inst{39-36} = R3;
320 let Inst{35-16} = XBD2;
321 let Inst{15-12} = R1;
323 let Inst{7-0} = op{7-0};
328 class InstRXY<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
329 : InstSystemZ<6, outs, ins, asmstr, pattern> {
331 field bits<48> SoftFail = 0;
336 let Inst{47-40} = op{15-8};
337 let Inst{39-36} = R1;
338 let Inst{35-8} = XBD2;
339 let Inst{7-0} = op{7-0};
341 let Has20BitOffset = 1;
345 class InstRS<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
346 : InstSystemZ<4, outs, ins, asmstr, pattern> {
348 field bits<32> SoftFail = 0;
354 let Inst{31-24} = op;
355 let Inst{23-20} = R1;
356 let Inst{19-16} = R3;
357 let Inst{15-0} = BD2;
360 class InstRSY<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
361 : InstSystemZ<6, outs, ins, asmstr, pattern> {
363 field bits<48> SoftFail = 0;
369 let Inst{47-40} = op{15-8};
370 let Inst{39-36} = R1;
371 let Inst{35-32} = R3;
372 let Inst{31-8} = BD2;
373 let Inst{7-0} = op{7-0};
375 let Has20BitOffset = 1;
378 class InstSI<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
379 : InstSystemZ<4, outs, ins, asmstr, pattern> {
381 field bits<32> SoftFail = 0;
386 let Inst{31-24} = op;
387 let Inst{23-16} = I2;
388 let Inst{15-0} = BD1;
391 class InstSIL<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
392 : InstSystemZ<6, outs, ins, asmstr, pattern> {
394 field bits<48> SoftFail = 0;
399 let Inst{47-32} = op;
400 let Inst{31-16} = BD1;
404 class InstSIY<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
405 : InstSystemZ<6, outs, ins, asmstr, pattern> {
407 field bits<48> SoftFail = 0;
412 let Inst{47-40} = op{15-8};
413 let Inst{39-32} = I2;
414 let Inst{31-8} = BD1;
415 let Inst{7-0} = op{7-0};
417 let Has20BitOffset = 1;
420 class InstSS<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
421 : InstSystemZ<6, outs, ins, asmstr, pattern> {
423 field bits<48> SoftFail = 0;
428 let Inst{47-40} = op;
429 let Inst{39-16} = BDL1;
430 let Inst{15-0} = BD2;
433 //===----------------------------------------------------------------------===//
434 // Instruction definitions with semantics
435 //===----------------------------------------------------------------------===//
437 // These classes have the form <Category><Format>, where <Format> is one
438 // of the formats defined above and where <Category> describes the inputs
439 // and outputs. <Category> can be one of:
442 // One register output operand and no input operands.
445 // One register or immediate input operand and one address input operand.
446 // The instruction stores the first operand to the address.
448 // This category is used for both pure and truncating stores.
451 // One address input operand and two explicit output operands.
452 // The instruction loads a range of registers from the address,
453 // with the explicit operands giving the first and last register
454 // to load. Other loaded registers are added as implicit definitions.
457 // Two explicit input register operands and an address operand.
458 // The instruction stores a range of registers to the address,
459 // with the explicit operands giving the first and last register
460 // to store. Other stored registers are added as implicit uses.
463 // One register output operand and one input operand. The input
464 // operand may be a register, immediate or memory.
467 // One register output operand and two input operands. The first
468 // input operand is always a register and he second may be a register,
469 // immediate or memory.
472 // One register output operand and two input operands. The first
473 // input operand is a register and the second has the same form as
474 // an address (although it isn't actually used to address memory).
477 // Two input operands. The first operand is always a register,
478 // the second may be a register, immediate or memory.
481 // One register output operand and three register input operands.
484 // One output operand and three input operands. The first two
485 // operands are registers and the third is an address. The instruction
486 // both reads from and writes to the address.
489 // One output operand and five input operands. The first two operands
490 // are registers and the other three are immediates.
492 // The format determines which input operands are tied to output operands,
493 // and also determines the shape of any address operand.
495 // Multiclasses of the form <Category><Format>Pair define two instructions,
496 // one with <Category><Format> and one with <Category><Format>Y. The name
497 // of the first instruction has no suffix, the name of the second has
500 //===----------------------------------------------------------------------===//
502 class InherentRRE<string mnemonic, bits<16> opcode, RegisterOperand cls,
504 : InstRRE<opcode, (outs cls:$R1), (ins),
506 [(set cls:$R1, src)]> {
510 class LoadMultipleRSY<string mnemonic, bits<16> opcode, RegisterOperand cls>
511 : InstRSY<opcode, (outs cls:$R1, cls:$R3), (ins bdaddr20only:$BD2),
512 mnemonic#"\t$R1, $R3, $BD2", []> {
516 class StoreRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator,
518 : InstRIL<opcode, (outs), (ins cls:$R1, pcrel32:$I2),
519 mnemonic#"\t$R1, $I2",
520 [(operator cls:$R1, pcrel32:$I2)]> {
522 // We want PC-relative addresses to be tried ahead of BD and BDX addresses.
523 // However, BDXs have two extra operands and are therefore 6 units more
525 let AddedComplexity = 7;
528 class StoreRX<string mnemonic, bits<8> opcode, SDPatternOperator operator,
529 RegisterOperand cls, bits<5> bytes,
530 AddressingMode mode = bdxaddr12only>
531 : InstRX<opcode, (outs), (ins cls:$R1, mode:$XBD2),
532 mnemonic#"\t$R1, $XBD2",
533 [(operator cls:$R1, mode:$XBD2)]> {
534 let OpKey = mnemonic ## cls;
537 let AccessBytes = bytes;
540 class StoreRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
541 RegisterOperand cls, bits<5> bytes,
542 AddressingMode mode = bdxaddr20only>
543 : InstRXY<opcode, (outs), (ins cls:$R1, mode:$XBD2),
544 mnemonic#"\t$R1, $XBD2",
545 [(operator cls:$R1, mode:$XBD2)]> {
546 let OpKey = mnemonic ## cls;
549 let AccessBytes = bytes;
552 multiclass StoreRXPair<string mnemonic, bits<8> rxOpcode, bits<16> rxyOpcode,
553 SDPatternOperator operator, RegisterOperand cls,
555 let DispKey = mnemonic ## #cls in {
556 let DispSize = "12" in
557 def "" : StoreRX<mnemonic, rxOpcode, operator, cls, bytes, bdxaddr12pair>;
558 let DispSize = "20" in
559 def Y : StoreRXY<mnemonic#"y", rxyOpcode, operator, cls, bytes,
564 class StoreMultipleRSY<string mnemonic, bits<16> opcode, RegisterOperand cls>
565 : InstRSY<opcode, (outs), (ins cls:$R1, cls:$R3, bdaddr20only:$BD2),
566 mnemonic#"\t$R1, $R3, $BD2", []> {
570 class StoreSI<string mnemonic, bits<8> opcode, SDPatternOperator operator,
571 Immediate imm, AddressingMode mode = bdaddr12only>
572 : InstSI<opcode, (outs), (ins mode:$BD1, imm:$I2),
573 mnemonic#"\t$BD1, $I2",
574 [(operator imm:$I2, mode:$BD1)]> {
578 class StoreSIY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
579 Immediate imm, AddressingMode mode = bdaddr20only>
580 : InstSIY<opcode, (outs), (ins mode:$BD1, imm:$I2),
581 mnemonic#"\t$BD1, $I2",
582 [(operator imm:$I2, mode:$BD1)]> {
586 class StoreSIL<string mnemonic, bits<16> opcode, SDPatternOperator operator,
588 : InstSIL<opcode, (outs), (ins bdaddr12only:$BD1, imm:$I2),
589 mnemonic#"\t$BD1, $I2",
590 [(operator imm:$I2, bdaddr12only:$BD1)]> {
594 multiclass StoreSIPair<string mnemonic, bits<8> siOpcode, bits<16> siyOpcode,
595 SDPatternOperator operator, Immediate imm> {
596 let DispKey = mnemonic in {
597 let DispSize = "12" in
598 def "" : StoreSI<mnemonic, siOpcode, operator, imm, bdaddr12pair>;
599 let DispSize = "20" in
600 def Y : StoreSIY<mnemonic#"y", siyOpcode, operator, imm, bdaddr20pair>;
604 class UnaryRR<string mnemonic, bits<8> opcode, SDPatternOperator operator,
605 RegisterOperand cls1, RegisterOperand cls2>
606 : InstRR<opcode, (outs cls1:$R1), (ins cls2:$R2),
607 mnemonic#"r\t$R1, $R2",
608 [(set cls1:$R1, (operator cls2:$R2))]> {
609 let OpKey = mnemonic ## cls1;
613 class UnaryRRE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
614 RegisterOperand cls1, RegisterOperand cls2>
615 : InstRRE<opcode, (outs cls1:$R1), (ins cls2:$R2),
616 mnemonic#"r\t$R1, $R2",
617 [(set cls1:$R1, (operator cls2:$R2))]> {
618 let OpKey = mnemonic ## cls1;
622 class UnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1,
623 RegisterOperand cls2>
624 : InstRRF<opcode, (outs cls1:$R1), (ins uimm8zx4:$R3, cls2:$R2),
625 mnemonic#"r\t$R1, $R3, $R2", []> {
626 let OpKey = mnemonic ## cls1;
630 class UnaryRI<string mnemonic, bits<12> opcode, SDPatternOperator operator,
631 RegisterOperand cls, Immediate imm>
632 : InstRI<opcode, (outs cls:$R1), (ins imm:$I2),
633 mnemonic#"\t$R1, $I2",
634 [(set cls:$R1, (operator imm:$I2))]>;
636 class UnaryRIL<string mnemonic, bits<12> opcode, SDPatternOperator operator,
637 RegisterOperand cls, Immediate imm>
638 : InstRIL<opcode, (outs cls:$R1), (ins imm:$I2),
639 mnemonic#"\t$R1, $I2",
640 [(set cls:$R1, (operator imm:$I2))]>;
642 class UnaryRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator,
644 : InstRIL<opcode, (outs cls:$R1), (ins pcrel32:$I2),
645 mnemonic#"\t$R1, $I2",
646 [(set cls:$R1, (operator pcrel32:$I2))]> {
648 // We want PC-relative addresses to be tried ahead of BD and BDX addresses.
649 // However, BDXs have two extra operands and are therefore 6 units more
651 let AddedComplexity = 7;
654 class UnaryRX<string mnemonic, bits<8> opcode, SDPatternOperator operator,
655 RegisterOperand cls, bits<5> bytes,
656 AddressingMode mode = bdxaddr12only>
657 : InstRX<opcode, (outs cls:$R1), (ins mode:$XBD2),
658 mnemonic#"\t$R1, $XBD2",
659 [(set cls:$R1, (operator mode:$XBD2))]> {
660 let OpKey = mnemonic ## cls;
663 let AccessBytes = bytes;
666 class UnaryRXE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
667 RegisterOperand cls, bits<5> bytes>
668 : InstRXE<opcode, (outs cls:$R1), (ins bdxaddr12only:$XBD2),
669 mnemonic#"\t$R1, $XBD2",
670 [(set cls:$R1, (operator bdxaddr12only:$XBD2))]> {
671 let OpKey = mnemonic ## cls;
674 let AccessBytes = bytes;
677 class UnaryRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
678 RegisterOperand cls, bits<5> bytes,
679 AddressingMode mode = bdxaddr20only>
680 : InstRXY<opcode, (outs cls:$R1), (ins mode:$XBD2),
681 mnemonic#"\t$R1, $XBD2",
682 [(set cls:$R1, (operator mode:$XBD2))]> {
683 let OpKey = mnemonic ## cls;
686 let AccessBytes = bytes;
689 multiclass UnaryRXPair<string mnemonic, bits<8> rxOpcode, bits<16> rxyOpcode,
690 SDPatternOperator operator, RegisterOperand cls,
692 let DispKey = mnemonic ## #cls in {
693 let DispSize = "12" in
694 def "" : UnaryRX<mnemonic, rxOpcode, operator, cls, bytes, bdxaddr12pair>;
695 let DispSize = "20" in
696 def Y : UnaryRXY<mnemonic#"y", rxyOpcode, operator, cls, bytes,
701 class BinaryRR<string mnemonic, bits<8> opcode, SDPatternOperator operator,
702 RegisterOperand cls1, RegisterOperand cls2>
703 : InstRR<opcode, (outs cls1:$R1), (ins cls1:$R1src, cls2:$R2),
704 mnemonic#"r\t$R1, $R2",
705 [(set cls1:$R1, (operator cls1:$R1src, cls2:$R2))]> {
706 let OpKey = mnemonic ## cls1;
708 let Constraints = "$R1 = $R1src";
709 let DisableEncoding = "$R1src";
712 class BinaryRRE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
713 RegisterOperand cls1, RegisterOperand cls2>
714 : InstRRE<opcode, (outs cls1:$R1), (ins cls1:$R1src, cls2:$R2),
715 mnemonic#"r\t$R1, $R2",
716 [(set cls1:$R1, (operator cls1:$R1src, cls2:$R2))]> {
717 let OpKey = mnemonic ## cls1;
719 let Constraints = "$R1 = $R1src";
720 let DisableEncoding = "$R1src";
723 class BinaryRRF<string mnemonic, bits<16> opcode, SDPatternOperator operator,
724 RegisterOperand cls1, RegisterOperand cls2>
725 : InstRRF<opcode, (outs cls1:$R1), (ins cls1:$R3, cls2:$R2),
726 mnemonic#"r\t$R1, $R3, $R2",
727 [(set cls1:$R1, (operator cls1:$R3, cls2:$R2))]> {
728 let OpKey = mnemonic ## cls1;
732 class BinaryRRFK<string mnemonic, bits<16> opcode, SDPatternOperator operator,
733 RegisterOperand cls1, RegisterOperand cls2>
734 : InstRRF<opcode, (outs cls1:$R1), (ins cls1:$R2, cls2:$R3),
735 mnemonic#"rk\t$R1, $R2, $R3",
736 [(set cls1:$R1, (operator cls1:$R2, cls2:$R3))]>;
738 multiclass BinaryRRAndK<string mnemonic, bits<8> opcode1, bits<16> opcode2,
739 SDPatternOperator operator, RegisterOperand cls1,
740 RegisterOperand cls2> {
741 let NumOpsKey = mnemonic in {
742 let NumOpsValue = "3" in
743 def K : BinaryRRFK<mnemonic, opcode2, null_frag, cls1, cls2>,
744 Requires<[FeatureDistinctOps]>;
745 let NumOpsValue = "2", isConvertibleToThreeAddress = 1 in
746 def "" : BinaryRR<mnemonic, opcode1, operator, cls1, cls2>;
750 class BinaryRI<string mnemonic, bits<12> opcode, SDPatternOperator operator,
751 RegisterOperand cls, Immediate imm>
752 : InstRI<opcode, (outs cls:$R1), (ins cls:$R1src, imm:$I2),
753 mnemonic#"\t$R1, $I2",
754 [(set cls:$R1, (operator cls:$R1src, imm:$I2))]> {
755 let Constraints = "$R1 = $R1src";
756 let DisableEncoding = "$R1src";
759 class BinaryRIL<string mnemonic, bits<12> opcode, SDPatternOperator operator,
760 RegisterOperand cls, Immediate imm>
761 : InstRIL<opcode, (outs cls:$R1), (ins cls:$R1src, imm:$I2),
762 mnemonic#"\t$R1, $I2",
763 [(set cls:$R1, (operator cls:$R1src, imm:$I2))]> {
764 let Constraints = "$R1 = $R1src";
765 let DisableEncoding = "$R1src";
768 class BinaryRX<string mnemonic, bits<8> opcode, SDPatternOperator operator,
769 RegisterOperand cls, SDPatternOperator load, bits<5> bytes,
770 AddressingMode mode = bdxaddr12only>
771 : InstRX<opcode, (outs cls:$R1), (ins cls:$R1src, mode:$XBD2),
772 mnemonic#"\t$R1, $XBD2",
773 [(set cls:$R1, (operator cls:$R1src, (load mode:$XBD2)))]> {
774 let OpKey = mnemonic ## cls;
776 let Constraints = "$R1 = $R1src";
777 let DisableEncoding = "$R1src";
779 let AccessBytes = bytes;
782 class BinaryRXE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
783 RegisterOperand cls, SDPatternOperator load, bits<5> bytes>
784 : InstRXE<opcode, (outs cls:$R1), (ins cls:$R1src, bdxaddr12only:$XBD2),
785 mnemonic#"\t$R1, $XBD2",
786 [(set cls:$R1, (operator cls:$R1src,
787 (load bdxaddr12only:$XBD2)))]> {
788 let OpKey = mnemonic ## cls;
790 let Constraints = "$R1 = $R1src";
791 let DisableEncoding = "$R1src";
793 let AccessBytes = bytes;
796 class BinaryRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
797 RegisterOperand cls, SDPatternOperator load, bits<5> bytes,
798 AddressingMode mode = bdxaddr20only>
799 : InstRXY<opcode, (outs cls:$R1), (ins cls:$R1src, mode:$XBD2),
800 mnemonic#"\t$R1, $XBD2",
801 [(set cls:$R1, (operator cls:$R1src, (load mode:$XBD2)))]> {
802 let OpKey = mnemonic ## cls;
804 let Constraints = "$R1 = $R1src";
805 let DisableEncoding = "$R1src";
807 let AccessBytes = bytes;
810 multiclass BinaryRXPair<string mnemonic, bits<8> rxOpcode, bits<16> rxyOpcode,
811 SDPatternOperator operator, RegisterOperand cls,
812 SDPatternOperator load, bits<5> bytes> {
813 let DispKey = mnemonic ## #cls in {
814 let DispSize = "12" in
815 def "" : BinaryRX<mnemonic, rxOpcode, operator, cls, load, bytes,
817 let DispSize = "20" in
818 def Y : BinaryRXY<mnemonic#"y", rxyOpcode, operator, cls, load, bytes,
823 class BinarySI<string mnemonic, bits<8> opcode, SDPatternOperator operator,
824 Operand imm, AddressingMode mode = bdaddr12only>
825 : InstSI<opcode, (outs), (ins mode:$BD1, imm:$I2),
826 mnemonic#"\t$BD1, $I2",
827 [(store (operator (load mode:$BD1), imm:$I2), mode:$BD1)]> {
832 class BinarySIY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
833 Operand imm, AddressingMode mode = bdaddr20only>
834 : InstSIY<opcode, (outs), (ins mode:$BD1, imm:$I2),
835 mnemonic#"\t$BD1, $I2",
836 [(store (operator (load mode:$BD1), imm:$I2), mode:$BD1)]> {
841 multiclass BinarySIPair<string mnemonic, bits<8> siOpcode,
842 bits<16> siyOpcode, SDPatternOperator operator,
844 let DispKey = mnemonic ## #cls in {
845 let DispSize = "12" in
846 def "" : BinarySI<mnemonic, siOpcode, operator, imm, bdaddr12pair>;
847 let DispSize = "20" in
848 def Y : BinarySIY<mnemonic#"y", siyOpcode, operator, imm, bdaddr20pair>;
852 class ShiftRS<string mnemonic, bits<8> opcode, SDPatternOperator operator,
854 : InstRS<opcode, (outs cls:$R1), (ins cls:$R1src, shift12only:$BD2),
855 mnemonic#"\t$R1, $BD2",
856 [(set cls:$R1, (operator cls:$R1src, shift12only:$BD2))]> {
858 let Constraints = "$R1 = $R1src";
859 let DisableEncoding = "$R1src";
862 class ShiftRSY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
864 : InstRSY<opcode, (outs cls:$R1), (ins cls:$R3, shift20only:$BD2),
865 mnemonic#"\t$R1, $R3, $BD2",
866 [(set cls:$R1, (operator cls:$R3, shift20only:$BD2))]>;
868 multiclass ShiftRSAndK<string mnemonic, bits<8> opcode1, bits<16> opcode2,
869 SDPatternOperator operator, RegisterOperand cls> {
870 let NumOpsKey = mnemonic in {
871 let NumOpsValue = "3" in
872 def K : ShiftRSY<mnemonic##"k", opcode2, null_frag, cls>,
873 Requires<[FeatureDistinctOps]>;
874 let NumOpsValue = "2", isConvertibleToThreeAddress = 1 in
875 def "" : ShiftRS<mnemonic, opcode1, operator, cls>;
879 class CompareRR<string mnemonic, bits<8> opcode, SDPatternOperator operator,
880 RegisterOperand cls1, RegisterOperand cls2>
881 : InstRR<opcode, (outs), (ins cls1:$R1, cls2:$R2),
882 mnemonic#"r\t$R1, $R2",
883 [(operator cls1:$R1, cls2:$R2)]> {
884 let OpKey = mnemonic ## cls1;
888 class CompareRRE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
889 RegisterOperand cls1, RegisterOperand cls2>
890 : InstRRE<opcode, (outs), (ins cls1:$R1, cls2:$R2),
891 mnemonic#"r\t$R1, $R2",
892 [(operator cls1:$R1, cls2:$R2)]> {
893 let OpKey = mnemonic ## cls1;
897 class CompareRI<string mnemonic, bits<12> opcode, SDPatternOperator operator,
898 RegisterOperand cls, Immediate imm>
899 : InstRI<opcode, (outs), (ins cls:$R1, imm:$I2),
900 mnemonic#"\t$R1, $I2",
901 [(operator cls:$R1, imm:$I2)]>;
903 class CompareRIL<string mnemonic, bits<12> opcode, SDPatternOperator operator,
904 RegisterOperand cls, Immediate imm>
905 : InstRIL<opcode, (outs), (ins cls:$R1, imm:$I2),
906 mnemonic#"\t$R1, $I2",
907 [(operator cls:$R1, imm:$I2)]>;
909 class CompareRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator,
910 RegisterOperand cls, SDPatternOperator load>
911 : InstRIL<opcode, (outs), (ins cls:$R1, pcrel32:$I2),
912 mnemonic#"\t$R1, $I2",
913 [(operator cls:$R1, (load pcrel32:$I2))]> {
915 // We want PC-relative addresses to be tried ahead of BD and BDX addresses.
916 // However, BDXs have two extra operands and are therefore 6 units more
918 let AddedComplexity = 7;
921 class CompareRX<string mnemonic, bits<8> opcode, SDPatternOperator operator,
922 RegisterOperand cls, SDPatternOperator load, bits<5> bytes,
923 AddressingMode mode = bdxaddr12only>
924 : InstRX<opcode, (outs), (ins cls:$R1, mode:$XBD2),
925 mnemonic#"\t$R1, $XBD2",
926 [(operator cls:$R1, (load mode:$XBD2))]> {
927 let OpKey = mnemonic ## cls;
930 let AccessBytes = bytes;
933 class CompareRXE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
934 RegisterOperand cls, SDPatternOperator load, bits<5> bytes>
935 : InstRXE<opcode, (outs), (ins cls:$R1, bdxaddr12only:$XBD2),
936 mnemonic#"\t$R1, $XBD2",
937 [(operator cls:$R1, (load bdxaddr12only:$XBD2))]> {
938 let OpKey = mnemonic ## cls;
941 let AccessBytes = bytes;
944 class CompareRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
945 RegisterOperand cls, SDPatternOperator load, bits<5> bytes,
946 AddressingMode mode = bdxaddr20only>
947 : InstRXY<opcode, (outs), (ins cls:$R1, mode:$XBD2),
948 mnemonic#"\t$R1, $XBD2",
949 [(operator cls:$R1, (load mode:$XBD2))]> {
950 let OpKey = mnemonic ## cls;
953 let AccessBytes = bytes;
956 multiclass CompareRXPair<string mnemonic, bits<8> rxOpcode, bits<16> rxyOpcode,
957 SDPatternOperator operator, RegisterOperand cls,
958 SDPatternOperator load, bits<5> bytes> {
959 let DispKey = mnemonic ## #cls in {
960 let DispSize = "12" in
961 def "" : CompareRX<mnemonic, rxOpcode, operator, cls,
962 load, bytes, bdxaddr12pair>;
963 let DispSize = "20" in
964 def Y : CompareRXY<mnemonic#"y", rxyOpcode, operator, cls,
965 load, bytes, bdxaddr20pair>;
969 class CompareSI<string mnemonic, bits<8> opcode, SDPatternOperator operator,
970 SDPatternOperator load, Immediate imm,
971 AddressingMode mode = bdaddr12only>
972 : InstSI<opcode, (outs), (ins mode:$BD1, imm:$I2),
973 mnemonic#"\t$BD1, $I2",
974 [(operator (load mode:$BD1), imm:$I2)]> {
978 class CompareSIL<string mnemonic, bits<16> opcode, SDPatternOperator operator,
979 SDPatternOperator load, Immediate imm>
980 : InstSIL<opcode, (outs), (ins bdaddr12only:$BD1, imm:$I2),
981 mnemonic#"\t$BD1, $I2",
982 [(operator (load bdaddr12only:$BD1), imm:$I2)]> {
986 class CompareSIY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
987 SDPatternOperator load, Immediate imm,
988 AddressingMode mode = bdaddr20only>
989 : InstSIY<opcode, (outs), (ins mode:$BD1, imm:$I2),
990 mnemonic#"\t$BD1, $I2",
991 [(operator (load mode:$BD1), imm:$I2)]> {
995 multiclass CompareSIPair<string mnemonic, bits<8> siOpcode, bits<16> siyOpcode,
996 SDPatternOperator operator, SDPatternOperator load,
998 let DispKey = mnemonic in {
999 let DispSize = "12" in
1000 def "" : CompareSI<mnemonic, siOpcode, operator, load, imm, bdaddr12pair>;
1001 let DispSize = "20" in
1002 def Y : CompareSIY<mnemonic#"y", siyOpcode, operator, load, imm,
1007 class TernaryRRD<string mnemonic, bits<16> opcode,
1008 SDPatternOperator operator, RegisterOperand cls>
1009 : InstRRD<opcode, (outs cls:$R1), (ins cls:$R1src, cls:$R3, cls:$R2),
1010 mnemonic#"r\t$R1, $R3, $R2",
1011 [(set cls:$R1, (operator cls:$R1src, cls:$R3, cls:$R2))]> {
1012 let OpKey = mnemonic ## cls;
1014 let Constraints = "$R1 = $R1src";
1015 let DisableEncoding = "$R1src";
1018 class TernaryRXF<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1019 RegisterOperand cls, SDPatternOperator load, bits<5> bytes>
1020 : InstRXF<opcode, (outs cls:$R1),
1021 (ins cls:$R1src, cls:$R3, bdxaddr12only:$XBD2),
1022 mnemonic#"\t$R1, $R3, $XBD2",
1023 [(set cls:$R1, (operator cls:$R1src, cls:$R3,
1024 (load bdxaddr12only:$XBD2)))]> {
1025 let OpKey = mnemonic ## cls;
1027 let Constraints = "$R1 = $R1src";
1028 let DisableEncoding = "$R1src";
1030 let AccessBytes = bytes;
1033 class CmpSwapRS<string mnemonic, bits<8> opcode, SDPatternOperator operator,
1034 RegisterOperand cls, AddressingMode mode = bdaddr12only>
1035 : InstRS<opcode, (outs cls:$R1), (ins cls:$R1src, cls:$R3, mode:$BD2),
1036 mnemonic#"\t$R1, $R3, $BD2",
1037 [(set cls:$R1, (operator mode:$BD2, cls:$R1src, cls:$R3))]> {
1038 let Constraints = "$R1 = $R1src";
1039 let DisableEncoding = "$R1src";
1044 class CmpSwapRSY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1045 RegisterOperand cls, AddressingMode mode = bdaddr20only>
1046 : InstRSY<opcode, (outs cls:$R1), (ins cls:$R1src, cls:$R3, mode:$BD2),
1047 mnemonic#"\t$R1, $R3, $BD2",
1048 [(set cls:$R1, (operator mode:$BD2, cls:$R1src, cls:$R3))]> {
1049 let Constraints = "$R1 = $R1src";
1050 let DisableEncoding = "$R1src";
1055 multiclass CmpSwapRSPair<string mnemonic, bits<8> rsOpcode, bits<16> rsyOpcode,
1056 SDPatternOperator operator, RegisterOperand cls> {
1057 let DispKey = mnemonic ## #cls in {
1058 let DispSize = "12" in
1059 def "" : CmpSwapRS<mnemonic, rsOpcode, operator, cls, bdaddr12pair>;
1060 let DispSize = "20" in
1061 def Y : CmpSwapRSY<mnemonic#"y", rsyOpcode, operator, cls, bdaddr20pair>;
1065 class RotateSelectRIEf<string mnemonic, bits<16> opcode, RegisterOperand cls1,
1066 RegisterOperand cls2>
1067 : InstRIEf<opcode, (outs cls1:$R1),
1068 (ins cls1:$R1src, cls2:$R2, uimm8:$I3, uimm8:$I4, uimm8zx6:$I5),
1069 mnemonic#"\t$R1, $R2, $I3, $I4, $I5", []> {
1070 let Constraints = "$R1 = $R1src";
1071 let DisableEncoding = "$R1src";
1074 //===----------------------------------------------------------------------===//
1075 // Pseudo instructions
1076 //===----------------------------------------------------------------------===//
1078 // Convenience instructions that get lowered to real instructions
1079 // by either SystemZTargetLowering::EmitInstrWithCustomInserter()
1080 // or SystemZInstrInfo::expandPostRAPseudo().
1082 //===----------------------------------------------------------------------===//
1084 class Pseudo<dag outs, dag ins, list<dag> pattern>
1085 : InstSystemZ<0, outs, ins, "", pattern> {
1087 let isCodeGenOnly = 1;
1090 // Implements "$dst = $cc & (8 >> CC) ? $src1 : $src2", where CC is
1091 // the value of the PSW's 2-bit condition code field.
1092 class SelectWrapper<RegisterOperand cls>
1093 : Pseudo<(outs cls:$dst), (ins cls:$src1, cls:$src2, i8imm:$cc),
1094 [(set cls:$dst, (z_select_ccmask cls:$src1, cls:$src2, imm:$cc))]> {
1095 let usesCustomInserter = 1;
1096 // Although the instructions used by these nodes do not in themselves
1097 // change CC, the insertion requires new blocks, and CC cannot be live
1103 // Stores $new to $addr if $cc is true ("" case) or false (Inv case).
1104 multiclass CondStores<RegisterOperand cls, SDPatternOperator store,
1105 SDPatternOperator load, AddressingMode mode> {
1106 let Defs = [CC], Uses = [CC], usesCustomInserter = 1 in {
1107 def "" : Pseudo<(outs), (ins mode:$addr, cls:$new, i8imm:$cc),
1108 [(store (z_select_ccmask cls:$new, (load mode:$addr),
1109 imm:$cc), mode:$addr)]>;
1110 def Inv : Pseudo<(outs), (ins mode:$addr, cls:$new, i8imm:$cc),
1111 [(store (z_select_ccmask (load mode:$addr), cls:$new,
1112 imm:$cc), mode:$addr)]>;
1116 // OPERATOR is ATOMIC_SWAP or an ATOMIC_LOAD_* operation. PAT and OPERAND
1117 // describe the second (non-memory) operand.
1118 class AtomicLoadBinary<SDPatternOperator operator, RegisterOperand cls,
1119 dag pat, DAGOperand operand>
1120 : Pseudo<(outs cls:$dst), (ins bdaddr20only:$ptr, operand:$src2),
1121 [(set cls:$dst, (operator bdaddr20only:$ptr, pat))]> {
1123 let Has20BitOffset = 1;
1126 let usesCustomInserter = 1;
1129 // Specializations of AtomicLoadWBinary.
1130 class AtomicLoadBinaryReg32<SDPatternOperator operator>
1131 : AtomicLoadBinary<operator, GR32, (i32 GR32:$src2), GR32>;
1132 class AtomicLoadBinaryImm32<SDPatternOperator operator, Immediate imm>
1133 : AtomicLoadBinary<operator, GR32, (i32 imm:$src2), imm>;
1134 class AtomicLoadBinaryReg64<SDPatternOperator operator>
1135 : AtomicLoadBinary<operator, GR64, (i64 GR64:$src2), GR64>;
1136 class AtomicLoadBinaryImm64<SDPatternOperator operator, Immediate imm>
1137 : AtomicLoadBinary<operator, GR64, (i64 imm:$src2), imm>;
1139 // OPERATOR is ATOMIC_SWAPW or an ATOMIC_LOADW_* operation. PAT and OPERAND
1140 // describe the second (non-memory) operand.
1141 class AtomicLoadWBinary<SDPatternOperator operator, dag pat,
1143 : Pseudo<(outs GR32:$dst),
1144 (ins bdaddr20only:$ptr, operand:$src2, ADDR32:$bitshift,
1145 ADDR32:$negbitshift, uimm32:$bitsize),
1146 [(set GR32:$dst, (operator bdaddr20only:$ptr, pat, ADDR32:$bitshift,
1147 ADDR32:$negbitshift, uimm32:$bitsize))]> {
1149 let Has20BitOffset = 1;
1152 let usesCustomInserter = 1;
1155 // Specializations of AtomicLoadWBinary.
1156 class AtomicLoadWBinaryReg<SDPatternOperator operator>
1157 : AtomicLoadWBinary<operator, (i32 GR32:$src2), GR32>;
1158 class AtomicLoadWBinaryImm<SDPatternOperator operator, Immediate imm>
1159 : AtomicLoadWBinary<operator, (i32 imm:$src2), imm>;