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 // Used to identify a group of related instructions, such as ST and STY.
27 // "12" for an instruction that has a ...Y equivalent, "20" for that
29 string PairType = "none";
31 // True if this instruction is a simple D(X,B) load of a register
32 // (with no sign or zero extension).
33 bit SimpleBDXLoad = 0;
35 // True if this instruction is a simple D(X,B) store of a register
36 // (with no truncation).
37 bit SimpleBDXStore = 0;
39 // True if this instruction has a 20-bit displacement field.
40 bit Has20BitOffset = 0;
42 // True if addresses in this instruction have an index register.
45 // True if this is a 128-bit pseudo instruction that combines two 64-bit
49 let TSFlags{0} = SimpleBDXLoad;
50 let TSFlags{1} = SimpleBDXStore;
51 let TSFlags{2} = Has20BitOffset;
52 let TSFlags{3} = HasIndex;
53 let TSFlags{4} = Is128Bit;
56 //===----------------------------------------------------------------------===//
57 // Mappings between instructions
58 //===----------------------------------------------------------------------===//
60 // Return the version of an instruction that has an unsigned 12-bit
62 def getDisp12Opcode : InstrMapping {
63 let FilterClass = "InstSystemZ";
64 let RowFields = ["Function"];
65 let ColFields = ["PairType"];
67 let ValueCols = [["12"]];
70 // Return the version of an instruction that has a signed 20-bit displacement.
71 def getDisp20Opcode : InstrMapping {
72 let FilterClass = "InstSystemZ";
73 let RowFields = ["Function"];
74 let ColFields = ["PairType"];
76 let ValueCols = [["20"]];
79 //===----------------------------------------------------------------------===//
80 // Instruction formats
81 //===----------------------------------------------------------------------===//
83 // Formats are specified using operand field declarations of the form:
85 // bits<4> Rn : register input or output for operand n
86 // bits<m> In : immediate value of width m for operand n
87 // bits<4> Bn : base register for address operand n
88 // bits<m> Dn : displacement value of width m for address operand n
89 // bits<4> Xn : index register for address operand n
90 // bits<4> Mn : mode value for operand n
92 // The operand numbers ("n" in the list above) follow the architecture manual,
93 // but the fields are always declared in assembly order, so there are some
94 // cases where operand "2" comes after operand "3". For address operands,
95 // the base register field is declared first, followed by the displacement,
96 // followed by the index (if any). This matches the bdaddr* and bdxaddr*
99 //===----------------------------------------------------------------------===//
101 class InstRI<bits<12> op, dag outs, dag ins, string asmstr, list<dag> pattern>
102 : InstSystemZ<4, outs, ins, asmstr, pattern> {
108 let Inst{31-24} = op{11-4};
109 let Inst{23-20} = R1;
110 let Inst{19-16} = op{3-0};
114 class InstRIEf<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
115 : InstSystemZ<6, outs, ins, asmstr, pattern> {
124 let Inst{47-40} = op{15-8};
125 let Inst{39-36} = R1;
126 let Inst{35-32} = R2;
127 let Inst{31-24} = I3;
128 let Inst{23-16} = I4;
130 let Inst{7-0} = op{7-0};
133 class InstRIL<bits<12> op, dag outs, dag ins, string asmstr, list<dag> pattern>
134 : InstSystemZ<6, outs, ins, asmstr, pattern> {
140 let Inst{47-40} = op{11-4};
141 let Inst{39-36} = R1;
142 let Inst{35-32} = op{3-0};
146 class InstRR<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
147 : InstSystemZ<2, outs, ins, asmstr, pattern> {
158 class InstRRD<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
159 : InstSystemZ<4, outs, ins, asmstr, pattern> {
166 let Inst{31-16} = op;
167 let Inst{15-12} = R1;
173 class InstRRE<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
174 : InstSystemZ<4, outs, ins, asmstr, pattern> {
180 let Inst{31-16} = op;
186 class InstRRF<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
187 : InstSystemZ<4, outs, ins, asmstr, pattern> {
194 let Inst{31-16} = op;
195 let Inst{15-12} = R3;
201 class InstRX<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
202 : InstSystemZ<4, outs, ins, asmstr, pattern> {
210 let Inst{31-24} = op;
211 let Inst{23-20} = R1;
212 let Inst{19-16} = X2;
213 let Inst{15-12} = B2;
219 class InstRXE<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
220 : InstSystemZ<6, outs, ins, asmstr, pattern> {
228 let Inst{47-40} = op{15-8};
229 let Inst{39-36} = R1;
230 let Inst{35-32} = X2;
231 let Inst{31-28} = B2;
232 let Inst{27-16} = D2;
234 let Inst{7-0} = op{7-0};
239 class InstRXF<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
240 : InstSystemZ<6, outs, ins, asmstr, pattern> {
249 let Inst{47-40} = op{15-8};
250 let Inst{39-36} = R3;
251 let Inst{35-32} = X2;
252 let Inst{31-28} = B2;
253 let Inst{27-16} = D2;
254 let Inst{15-12} = R1;
256 let Inst{7-0} = op{7-0};
261 class InstRXY<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
262 : InstSystemZ<6, outs, ins, asmstr, pattern> {
270 let Inst{47-40} = op{15-8};
271 let Inst{39-36} = R1;
272 let Inst{35-32} = X2;
273 let Inst{31-28} = B2;
274 let Inst{27-16} = D2{11-0};
275 let Inst{15-8} = D2{19-12};
276 let Inst{7-0} = op{7-0};
278 let Has20BitOffset = 1;
282 class InstRS<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
283 : InstSystemZ<4, outs, ins, asmstr, pattern> {
291 let Inst{31-24} = op;
292 let Inst{23-20} = R1;
293 let Inst{19-16} = R3;
294 let Inst{15-12} = B2;
298 class InstRSY<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
299 : InstSystemZ<6, outs, ins, asmstr, pattern> {
307 let Inst{47-40} = op{15-8};
308 let Inst{39-36} = R1;
309 let Inst{35-32} = R3;
310 let Inst{31-28} = B2;
311 let Inst{27-16} = D2{11-0};
312 let Inst{15-8} = D2{19-12};
313 let Inst{7-0} = op{7-0};
315 let Has20BitOffset = 1;
318 class InstSI<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
319 : InstSystemZ<4, outs, ins, asmstr, pattern> {
326 let Inst{31-24} = op;
327 let Inst{23-16} = I2;
328 let Inst{15-12} = B1;
332 class InstSIL<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
333 : InstSystemZ<6, outs, ins, asmstr, pattern> {
340 let Inst{47-32} = op;
341 let Inst{31-28} = B1;
342 let Inst{27-16} = D1;
346 class InstSIY<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
347 : InstSystemZ<6, outs, ins, asmstr, pattern> {
354 let Inst{47-40} = op{15-8};
355 let Inst{39-32} = I2;
356 let Inst{31-28} = B1;
357 let Inst{27-16} = D1{11-0};
358 let Inst{15-8} = D1{19-12};
359 let Inst{7-0} = op{7-0};
361 let Has20BitOffset = 1;
364 //===----------------------------------------------------------------------===//
365 // Instruction definitions with semantics
366 //===----------------------------------------------------------------------===//
368 // These classes have the form <Category><Format>, where <Format> is one
369 // of the formats defined above and where <Category> describes the inputs
370 // and outputs. <Category> can be one of:
373 // One register output operand and no input operands.
376 // One register or immediate input operand and one address input operand.
377 // The instruction stores the first operand to the address.
379 // This category is used for both pure and truncating stores.
382 // One address input operand and two explicit output operands.
383 // The instruction loads a range of registers from the address,
384 // with the explicit operands giving the first and last register
385 // to load. Other loaded registers are added as implicit definitions.
388 // Two explicit input register operands and an address operand.
389 // The instruction stores a range of registers to the address,
390 // with the explicit operands giving the first and last register
391 // to store. Other stored registers are added as implicit uses.
394 // One register output operand and one input operand. The input
395 // operand may be a register, immediate or memory.
398 // One register output operand and two input operands. The first
399 // input operand is always a register and he second may be a register,
400 // immediate or memory.
403 // One register output operand and two input operands. The first
404 // input operand is a register and the second has the same form as
405 // an address (although it isn't actually used to address memory).
408 // Two input operands. The first operand is always a register,
409 // the second may be a register, immediate or memory.
412 // One register output operand and three register input operands.
415 // One output operand and three input operands. The first two
416 // operands are registers and the third is an address. The instruction
417 // both reads from and writes to the address.
420 // One output operand and five input operands. The first two operands
421 // are registers and the other three are immediates.
423 // The format determines which input operands are tied to output operands,
424 // and also determines the shape of any address operand.
426 // Multiclasses of the form <Category><Format>Pair define two instructions,
427 // one with <Category><Format> and one with <Category><Format>Y. The name
428 // of the first instruction has no suffix, the name of the second has
431 //===----------------------------------------------------------------------===//
433 class InherentRRE<string mnemonic, bits<16> opcode, RegisterOperand cls,
435 : InstRRE<opcode, (outs cls:$dst), (ins),
437 [(set cls:$dst, src)]> {
441 class LoadMultipleRSY<string mnemonic, bits<16> opcode, RegisterOperand cls>
442 : InstRSY<opcode, (outs cls:$dst1, cls:$dst2), (ins bdaddr20only:$addr),
443 mnemonic#"\t$dst1, $dst2, $addr", []> {
447 class StoreRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator,
449 : InstRIL<opcode, (outs), (ins cls:$src, pcrel32:$addr),
450 mnemonic#"\t$src, $addr",
451 [(operator cls:$src, pcrel32:$addr)]> {
453 // We want PC-relative addresses to be tried ahead of BD and BDX addresses.
454 // However, BDXs have two extra operands and are therefore 6 units more
456 let AddedComplexity = 7;
459 class StoreRX<string mnemonic, bits<8> opcode, SDPatternOperator operator,
460 RegisterOperand cls, AddressingMode mode = bdxaddr12only>
461 : InstRX<opcode, (outs), (ins cls:$src, mode:$addr),
462 mnemonic#"\t$src, $addr",
463 [(operator cls:$src, mode:$addr)]> {
467 class StoreRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
468 RegisterOperand cls, AddressingMode mode = bdxaddr20only>
469 : InstRXY<opcode, (outs), (ins cls:$src, mode:$addr),
470 mnemonic#"\t$src, $addr",
471 [(operator cls:$src, mode:$addr)]> {
475 multiclass StoreRXPair<string mnemonic, bits<8> rxOpcode, bits<16> rxyOpcode,
476 SDPatternOperator operator, RegisterOperand cls> {
477 let Function = mnemonic ## #cls in {
478 let PairType = "12" in
479 def "" : StoreRX<mnemonic, rxOpcode, operator, cls, bdxaddr12pair>;
480 let PairType = "20" in
481 def Y : StoreRXY<mnemonic#"y", rxyOpcode, operator, cls, bdxaddr20pair>;
485 class StoreMultipleRSY<string mnemonic, bits<16> opcode, RegisterOperand cls>
486 : InstRSY<opcode, (outs), (ins cls:$from, cls:$to, bdaddr20only:$addr),
487 mnemonic#"\t$from, $to, $addr", []> {
491 class StoreSI<string mnemonic, bits<8> opcode, SDPatternOperator operator,
492 Immediate imm, AddressingMode mode = bdaddr12only>
493 : InstSI<opcode, (outs), (ins mode:$addr, imm:$src),
494 mnemonic#"\t$addr, $src",
495 [(operator imm:$src, mode:$addr)]> {
499 class StoreSIY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
500 Immediate imm, AddressingMode mode = bdaddr20only>
501 : InstSIY<opcode, (outs), (ins mode:$addr, imm:$src),
502 mnemonic#"\t$addr, $src",
503 [(operator imm:$src, mode:$addr)]> {
507 class StoreSIL<string mnemonic, bits<16> opcode, SDPatternOperator operator,
509 : InstSIL<opcode, (outs), (ins bdaddr12only:$addr, imm:$src),
510 mnemonic#"\t$addr, $src",
511 [(operator imm:$src, bdaddr12only:$addr)]> {
515 multiclass StoreSIPair<string mnemonic, bits<8> siOpcode, bits<16> siyOpcode,
516 SDPatternOperator operator, Immediate imm> {
517 let Function = mnemonic in {
518 let PairType = "12" in
519 def "" : StoreSI<mnemonic, siOpcode, operator, imm, bdaddr12pair>;
520 let PairType = "20" in
521 def Y : StoreSIY<mnemonic#"y", siyOpcode, operator, imm, bdaddr20pair>;
525 class UnaryRR<string mnemonic, bits<8> opcode, SDPatternOperator operator,
526 RegisterOperand cls1, RegisterOperand cls2>
527 : InstRR<opcode, (outs cls1:$dst), (ins cls2:$src),
528 mnemonic#"\t$dst, $src",
529 [(set cls1:$dst, (operator cls2:$src))]>;
531 class UnaryRRE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
532 RegisterOperand cls1, RegisterOperand cls2>
533 : InstRRE<opcode, (outs cls1:$dst), (ins cls2:$src),
534 mnemonic#"\t$dst, $src",
535 [(set cls1:$dst, (operator cls2:$src))]>;
537 class UnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1,
538 RegisterOperand cls2>
539 : InstRRF<opcode, (outs cls1:$dst), (ins cls2:$src, uimm8zx4:$mode),
540 mnemonic#"\t$dst, $mode, $src", []>;
542 class UnaryRI<string mnemonic, bits<12> opcode, SDPatternOperator operator,
543 RegisterOperand cls, Immediate imm>
544 : InstRI<opcode, (outs cls:$dst), (ins imm:$src),
545 mnemonic#"\t$dst, $src",
546 [(set cls:$dst, (operator imm:$src))]>;
548 class UnaryRIL<string mnemonic, bits<12> opcode, SDPatternOperator operator,
549 RegisterOperand cls, Immediate imm>
550 : InstRIL<opcode, (outs cls:$dst), (ins imm:$src),
551 mnemonic#"\t$dst, $src",
552 [(set cls:$dst, (operator imm:$src))]>;
554 class UnaryRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator,
556 : InstRIL<opcode, (outs cls:$dst), (ins pcrel32:$addr),
557 mnemonic#"\t$dst, $addr",
558 [(set cls:$dst, (operator pcrel32:$addr))]> {
560 // We want PC-relative addresses to be tried ahead of BD and BDX addresses.
561 // However, BDXs have two extra operands and are therefore 6 units more
563 let AddedComplexity = 7;
566 class UnaryRX<string mnemonic, bits<8> opcode, SDPatternOperator operator,
567 RegisterOperand cls, AddressingMode mode = bdxaddr12only>
568 : InstRX<opcode, (outs cls:$dst), (ins mode:$addr),
569 mnemonic#"\t$dst, $addr",
570 [(set cls:$dst, (operator mode:$addr))]> {
574 class UnaryRXE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
576 : InstRXE<opcode, (outs cls:$dst), (ins bdxaddr12only:$addr),
577 mnemonic#"\t$dst, $addr",
578 [(set cls:$dst, (operator bdxaddr12only:$addr))]> {
582 class UnaryRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
583 RegisterOperand cls, AddressingMode mode = bdxaddr20only>
584 : InstRXY<opcode, (outs cls:$dst), (ins mode:$addr),
585 mnemonic#"\t$dst, $addr",
586 [(set cls:$dst, (operator mode:$addr))]> {
590 multiclass UnaryRXPair<string mnemonic, bits<8> rxOpcode, bits<16> rxyOpcode,
591 SDPatternOperator operator, RegisterOperand cls> {
592 let Function = mnemonic ## #cls in {
593 let PairType = "12" in
594 def "" : UnaryRX<mnemonic, rxOpcode, operator, cls, bdxaddr12pair>;
595 let PairType = "20" in
596 def Y : UnaryRXY<mnemonic#"y", rxyOpcode, operator, cls, bdxaddr20pair>;
600 class BinaryRR<string mnemonic, bits<8> opcode, SDPatternOperator operator,
601 RegisterOperand cls1, RegisterOperand cls2>
602 : InstRR<opcode, (outs cls1:$dst), (ins cls1:$src1, cls2:$src2),
603 mnemonic#"\t$dst, $src2",
604 [(set cls1:$dst, (operator cls1:$src1, cls2:$src2))]> {
605 let Constraints = "$src1 = $dst";
606 let DisableEncoding = "$src1";
609 class BinaryRRE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
610 RegisterOperand cls1, RegisterOperand cls2>
611 : InstRRE<opcode, (outs cls1:$dst), (ins cls1:$src1, cls2:$src2),
612 mnemonic#"\t$dst, $src2",
613 [(set cls1:$dst, (operator cls1:$src1, cls2:$src2))]> {
614 let Constraints = "$src1 = $dst";
615 let DisableEncoding = "$src1";
618 // Here the assembly and dag operands are in natural order,
619 // but the first input operand maps to R3 and the second to R2.
620 // This is used for "CPSDR R1, R3, R2", which is equivalent to
621 // R1 = copysign (R3, R2).
623 // Direct uses of the instruction must pass operands in encoding order --
624 // R1, R2, R3 -- so they must pass the source operands in reverse order.
625 class BinaryRevRRF<string mnemonic, bits<16> opcode, SDPatternOperator operator,
626 RegisterOperand cls1, RegisterOperand cls2>
627 : InstRRF<opcode, (outs cls1:$dst), (ins cls2:$src2, cls1:$src1),
628 mnemonic#"\t$dst, $src1, $src2",
629 [(set cls1:$dst, (operator cls1:$src1, cls2:$src2))]>;
631 class BinaryRI<string mnemonic, bits<12> opcode, SDPatternOperator operator,
632 RegisterOperand cls, Immediate imm>
633 : InstRI<opcode, (outs cls:$dst), (ins cls:$src1, imm:$src2),
634 mnemonic#"\t$dst, $src2",
635 [(set cls:$dst, (operator cls:$src1, imm:$src2))]> {
636 let Constraints = "$src1 = $dst";
637 let DisableEncoding = "$src1";
640 class BinaryRIL<string mnemonic, bits<12> opcode, SDPatternOperator operator,
641 RegisterOperand cls, Immediate imm>
642 : InstRIL<opcode, (outs cls:$dst), (ins cls:$src1, imm:$src2),
643 mnemonic#"\t$dst, $src2",
644 [(set cls:$dst, (operator cls:$src1, imm:$src2))]> {
645 let Constraints = "$src1 = $dst";
646 let DisableEncoding = "$src1";
649 class BinaryRX<string mnemonic, bits<8> opcode, SDPatternOperator operator,
650 RegisterOperand cls, SDPatternOperator load,
651 AddressingMode mode = bdxaddr12only>
652 : InstRX<opcode, (outs cls:$dst), (ins cls:$src1, mode:$src2),
653 mnemonic#"\t$dst, $src2",
654 [(set cls:$dst, (operator cls:$src1, (load mode:$src2)))]> {
655 let Constraints = "$src1 = $dst";
656 let DisableEncoding = "$src1";
660 class BinaryRXE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
661 RegisterOperand cls, SDPatternOperator load>
662 : InstRXE<opcode, (outs cls:$dst), (ins cls:$src1, bdxaddr12only:$src2),
663 mnemonic#"\t$dst, $src2",
664 [(set cls:$dst, (operator cls:$src1,
665 (load bdxaddr12only:$src2)))]> {
666 let Constraints = "$src1 = $dst";
667 let DisableEncoding = "$src1";
671 class BinaryRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
672 RegisterOperand cls, SDPatternOperator load,
673 AddressingMode mode = bdxaddr20only>
674 : InstRXY<opcode, (outs cls:$dst), (ins cls:$src1, mode:$src2),
675 mnemonic#"\t$dst, $src2",
676 [(set cls:$dst, (operator cls:$src1, (load mode:$src2)))]> {
677 let Constraints = "$src1 = $dst";
678 let DisableEncoding = "$src1";
682 multiclass BinaryRXPair<string mnemonic, bits<8> rxOpcode, bits<16> rxyOpcode,
683 SDPatternOperator operator, RegisterOperand cls,
684 SDPatternOperator load> {
685 let Function = mnemonic ## #cls in {
686 let PairType = "12" in
687 def "" : BinaryRX<mnemonic, rxOpcode, operator, cls, load, bdxaddr12pair>;
688 let PairType = "20" in
689 def Y : BinaryRXY<mnemonic#"y", rxyOpcode, operator, cls, load,
694 class BinarySI<string mnemonic, bits<8> opcode, SDPatternOperator operator,
695 Operand imm, AddressingMode mode = bdaddr12only>
696 : InstSI<opcode, (outs), (ins mode:$addr, imm:$src),
697 mnemonic#"\t$addr, $src",
698 [(store (operator (load mode:$addr), imm:$src), mode:$addr)]> {
703 class BinarySIY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
704 Operand imm, AddressingMode mode = bdaddr20only>
705 : InstSIY<opcode, (outs), (ins mode:$addr, imm:$src),
706 mnemonic#"\t$addr, $src",
707 [(store (operator (load mode:$addr), imm:$src), mode:$addr)]> {
712 multiclass BinarySIPair<string mnemonic, bits<8> siOpcode,
713 bits<16> siyOpcode, SDPatternOperator operator,
715 let Function = mnemonic ## #cls in {
716 let PairType = "12" in
717 def "" : BinarySI<mnemonic, siOpcode, operator, imm, bdaddr12pair>;
718 let PairType = "20" in
719 def Y : BinarySIY<mnemonic#"y", siyOpcode, operator, imm, bdaddr20pair>;
723 class ShiftRS<string mnemonic, bits<8> opcode, SDPatternOperator operator,
724 RegisterOperand cls, AddressingMode mode>
725 : InstRS<opcode, (outs cls:$dst), (ins cls:$src1, mode:$src2),
726 mnemonic#"\t$dst, $src2",
727 [(set cls:$dst, (operator cls:$src1, mode:$src2))]> {
729 let Constraints = "$src1 = $dst";
730 let DisableEncoding = "$src1";
733 class ShiftRSY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
734 RegisterOperand cls, AddressingMode mode>
735 : InstRSY<opcode, (outs cls:$dst), (ins cls:$src1, mode:$src2),
736 mnemonic#"\t$dst, $src1, $src2",
737 [(set cls:$dst, (operator cls:$src1, mode:$src2))]>;
739 class CompareRR<string mnemonic, bits<8> opcode, SDPatternOperator operator,
740 RegisterOperand cls1, RegisterOperand cls2>
741 : InstRR<opcode, (outs), (ins cls1:$src1, cls2:$src2),
742 mnemonic#"\t$src1, $src2",
743 [(operator cls1:$src1, cls2:$src2)]>;
745 class CompareRRE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
746 RegisterOperand cls1, RegisterOperand cls2>
747 : InstRRE<opcode, (outs), (ins cls1:$src1, cls2:$src2),
748 mnemonic#"\t$src1, $src2",
749 [(operator cls1:$src1, cls2:$src2)]>;
751 class CompareRI<string mnemonic, bits<12> opcode, SDPatternOperator operator,
752 RegisterOperand cls, Immediate imm>
753 : InstRI<opcode, (outs), (ins cls:$src1, imm:$src2),
754 mnemonic#"\t$src1, $src2",
755 [(operator cls:$src1, imm:$src2)]>;
757 class CompareRIL<string mnemonic, bits<12> opcode, SDPatternOperator operator,
758 RegisterOperand cls, Immediate imm>
759 : InstRIL<opcode, (outs), (ins cls:$src1, imm:$src2),
760 mnemonic#"\t$src1, $src2",
761 [(operator cls:$src1, imm:$src2)]>;
763 class CompareRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator,
764 RegisterOperand cls, SDPatternOperator load>
765 : InstRIL<opcode, (outs), (ins cls:$src1, pcrel32:$src2),
766 mnemonic#"\t$src1, $src2",
767 [(operator cls:$src1, (load pcrel32:$src2))]> {
769 // We want PC-relative addresses to be tried ahead of BD and BDX addresses.
770 // However, BDXs have two extra operands and are therefore 6 units more
772 let AddedComplexity = 7;
775 class CompareRX<string mnemonic, bits<8> opcode, SDPatternOperator operator,
776 RegisterOperand cls, SDPatternOperator load,
777 AddressingMode mode = bdxaddr12only>
778 : InstRX<opcode, (outs), (ins cls:$src1, mode:$src2),
779 mnemonic#"\t$src1, $src2",
780 [(operator cls:$src1, (load mode:$src2))]> {
784 class CompareRXE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
785 RegisterOperand cls, SDPatternOperator load>
786 : InstRXE<opcode, (outs), (ins cls:$src1, bdxaddr12only:$src2),
787 mnemonic#"\t$src1, $src2",
788 [(operator cls:$src1, (load bdxaddr12only:$src2))]> {
792 class CompareRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
793 RegisterOperand cls, SDPatternOperator load,
794 AddressingMode mode = bdxaddr20only>
795 : InstRXY<opcode, (outs), (ins cls:$src1, mode:$src2),
796 mnemonic#"\t$src1, $src2",
797 [(operator cls:$src1, (load mode:$src2))]> {
801 multiclass CompareRXPair<string mnemonic, bits<8> rxOpcode, bits<16> rxyOpcode,
802 SDPatternOperator operator, RegisterOperand cls,
803 SDPatternOperator load> {
804 let Function = mnemonic ## #cls in {
805 let PairType = "12" in
806 def "" : CompareRX<mnemonic, rxOpcode, operator, cls,
807 load, bdxaddr12pair>;
808 let PairType = "20" in
809 def Y : CompareRXY<mnemonic#"y", rxyOpcode, operator, cls,
810 load, bdxaddr20pair>;
814 class CompareSI<string mnemonic, bits<8> opcode, SDPatternOperator operator,
815 SDPatternOperator load, Immediate imm,
816 AddressingMode mode = bdaddr12only>
817 : InstSI<opcode, (outs), (ins mode:$addr, imm:$src),
818 mnemonic#"\t$addr, $src",
819 [(operator (load mode:$addr), imm:$src)]> {
823 class CompareSIL<string mnemonic, bits<16> opcode, SDPatternOperator operator,
824 SDPatternOperator load, Immediate imm>
825 : InstSIL<opcode, (outs), (ins bdaddr12only:$addr, imm:$src),
826 mnemonic#"\t$addr, $src",
827 [(operator (load bdaddr12only:$addr), imm:$src)]> {
831 class CompareSIY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
832 SDPatternOperator load, Immediate imm,
833 AddressingMode mode = bdaddr20only>
834 : InstSIY<opcode, (outs), (ins mode:$addr, imm:$src),
835 mnemonic#"\t$addr, $src",
836 [(operator (load mode:$addr), imm:$src)]> {
840 multiclass CompareSIPair<string mnemonic, bits<8> siOpcode, bits<16> siyOpcode,
841 SDPatternOperator operator, SDPatternOperator load,
843 let Function = mnemonic in {
844 let PairType = "12" in
845 def "" : CompareSI<mnemonic, siOpcode, operator, load, imm, bdaddr12pair>;
846 let PairType = "20" in
847 def Y : CompareSIY<mnemonic#"y", siyOpcode, operator, load, imm,
852 class TernaryRRD<string mnemonic, bits<16> opcode,
853 SDPatternOperator operator, RegisterOperand cls>
854 : InstRRD<opcode, (outs cls:$dst), (ins cls:$src1, cls:$src2, cls:$src3),
855 mnemonic#"\t$dst, $src2, $src3",
856 [(set cls:$dst, (operator cls:$src1, cls:$src2, cls:$src3))]> {
857 let Constraints = "$src1 = $dst";
858 let DisableEncoding = "$src1";
861 class TernaryRXF<string mnemonic, bits<16> opcode, SDPatternOperator operator,
862 RegisterOperand cls, SDPatternOperator load>
863 : InstRXF<opcode, (outs cls:$dst),
864 (ins cls:$src1, cls:$src2, bdxaddr12only:$src3),
865 mnemonic#"\t$dst, $src2, $src3",
866 [(set cls:$dst, (operator cls:$src1, cls:$src2,
867 (load bdxaddr12only:$src3)))]> {
868 let Constraints = "$src1 = $dst";
869 let DisableEncoding = "$src1";
873 class CmpSwapRS<string mnemonic, bits<8> opcode, SDPatternOperator operator,
874 RegisterOperand cls, AddressingMode mode = bdaddr12only>
875 : InstRS<opcode, (outs cls:$dst), (ins cls:$old, cls:$new, mode:$ptr),
876 mnemonic#"\t$dst, $new, $ptr",
877 [(set cls:$dst, (operator mode:$ptr, cls:$old, cls:$new))]> {
878 let Constraints = "$old = $dst";
879 let DisableEncoding = "$old";
884 class CmpSwapRSY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
885 RegisterOperand cls, AddressingMode mode = bdaddr20only>
886 : InstRSY<opcode, (outs cls:$dst), (ins cls:$old, cls:$new, mode:$ptr),
887 mnemonic#"\t$dst, $new, $ptr",
888 [(set cls:$dst, (operator mode:$ptr, cls:$old, cls:$new))]> {
889 let Constraints = "$old = $dst";
890 let DisableEncoding = "$old";
895 multiclass CmpSwapRSPair<string mnemonic, bits<8> rsOpcode, bits<16> rsyOpcode,
896 SDPatternOperator operator, RegisterOperand cls> {
897 let Function = mnemonic ## #cls in {
898 let PairType = "12" in
899 def "" : CmpSwapRS<mnemonic, rsOpcode, operator, cls, bdaddr12pair>;
900 let PairType = "20" in
901 def Y : CmpSwapRSY<mnemonic#"y", rsyOpcode, operator, cls, bdaddr20pair>;
905 class RotateSelectRIEf<string mnemonic, bits<16> opcode, RegisterOperand cls1,
906 RegisterOperand cls2>
907 : InstRIEf<opcode, (outs cls1:$dst),
908 (ins cls1:$src1, cls2:$src2,
909 uimm8zx6:$imm1, uimm8zx6:$imm2, uimm8zx6:$imm3),
910 mnemonic#"\t$dst, $src2, $imm1, $imm2, $imm3", []> {
911 let Constraints = "$src1 = $dst";
912 let DisableEncoding = "$src1";
915 //===----------------------------------------------------------------------===//
916 // Pseudo instructions
917 //===----------------------------------------------------------------------===//
919 // Convenience instructions that get lowered to real instructions
920 // by either SystemZTargetLowering::EmitInstrWithCustomInserter()
921 // or SystemZInstrInfo::expandPostRAPseudo().
923 //===----------------------------------------------------------------------===//
925 class Pseudo<dag outs, dag ins, list<dag> pattern>
926 : InstSystemZ<0, outs, ins, "", pattern> {
928 let isCodeGenOnly = 1;
931 // Implements "$dst = $cc & (8 >> CC) ? $src1 : $src2", where CC is
932 // the value of the PSW's 2-bit condition code field.
933 class SelectWrapper<RegisterOperand cls>
934 : Pseudo<(outs cls:$dst), (ins cls:$src1, cls:$src2, i8imm:$cc),
935 [(set cls:$dst, (z_select_ccmask cls:$src1, cls:$src2, imm:$cc))]> {
936 let usesCustomInserter = 1;
937 // Although the instructions used by these nodes do not in themselves
938 // change the PSW, the insertion requires new blocks, and the PSW cannot
939 // be live across them.
944 // OPERATOR is ATOMIC_SWAP or an ATOMIC_LOAD_* operation. PAT and OPERAND
945 // describe the second (non-memory) operand.
946 class AtomicLoadBinary<SDPatternOperator operator, RegisterOperand cls,
947 dag pat, DAGOperand operand>
948 : Pseudo<(outs cls:$dst), (ins bdaddr20only:$ptr, operand:$src2),
949 [(set cls:$dst, (operator bdaddr20only:$ptr, pat))]> {
951 let Has20BitOffset = 1;
954 let usesCustomInserter = 1;
957 // Specializations of AtomicLoadWBinary.
958 class AtomicLoadBinaryReg32<SDPatternOperator operator>
959 : AtomicLoadBinary<operator, GR32, (i32 GR32:$src2), GR32>;
960 class AtomicLoadBinaryImm32<SDPatternOperator operator, Immediate imm>
961 : AtomicLoadBinary<operator, GR32, (i32 imm:$src2), imm>;
962 class AtomicLoadBinaryReg64<SDPatternOperator operator>
963 : AtomicLoadBinary<operator, GR64, (i64 GR64:$src2), GR64>;
964 class AtomicLoadBinaryImm64<SDPatternOperator operator, Immediate imm>
965 : AtomicLoadBinary<operator, GR64, (i64 imm:$src2), imm>;
967 // OPERATOR is ATOMIC_SWAPW or an ATOMIC_LOADW_* operation. PAT and OPERAND
968 // describe the second (non-memory) operand.
969 class AtomicLoadWBinary<SDPatternOperator operator, dag pat,
971 : Pseudo<(outs GR32:$dst),
972 (ins bdaddr20only:$ptr, operand:$src2, ADDR32:$bitshift,
973 ADDR32:$negbitshift, uimm32:$bitsize),
974 [(set GR32:$dst, (operator bdaddr20only:$ptr, pat, ADDR32:$bitshift,
975 ADDR32:$negbitshift, uimm32:$bitsize))]> {
977 let Has20BitOffset = 1;
980 let usesCustomInserter = 1;
983 // Specializations of AtomicLoadWBinary.
984 class AtomicLoadWBinaryReg<SDPatternOperator operator>
985 : AtomicLoadWBinary<operator, (i32 GR32:$src2), GR32>;
986 class AtomicLoadWBinaryImm<SDPatternOperator operator, Immediate imm>
987 : AtomicLoadWBinary<operator, (i32 imm:$src2), imm>;