1//==- SystemZInstrFormats.td - SystemZ Instruction Formats --*- tablegen -*-==//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10//===----------------------------------------------------------------------===//
11// Basic SystemZ instruction definition
12//===----------------------------------------------------------------------===//
13
14class InstSystemZ<int size, dag outs, dag ins, string asmstr,
15                  list<dag> pattern> : Instruction {
16  let Namespace = "SystemZ";
17
18  dag OutOperandList = outs;
19  dag InOperandList = ins;
20  let Size = size;
21  let Pattern = pattern;
22  let AsmString = asmstr;
23
24  // Used to identify a group of related instructions, such as ST and STY.
25  string Function = "";
26
27  // "12" for an instruction that has a ...Y equivalent, "20" for that
28  // ...Y equivalent.
29  string PairType = "none";
30
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;
34
35  // True if this instruction is a simple D(X,B) store of a register
36  // (with no truncation).
37  bit SimpleBDXStore = 0;
38
39  // True if this instruction has a 20-bit displacement field.
40  bit Has20BitOffset = 0;
41
42  // True if addresses in this instruction have an index register.
43  bit HasIndex = 0;
44
45  // True if this is a 128-bit pseudo instruction that combines two 64-bit
46  // operations.
47  bit Is128Bit = 0;
48
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;
54}
55
56//===----------------------------------------------------------------------===//
57// Mappings between instructions
58//===----------------------------------------------------------------------===//
59
60// Return the version of an instruction that has an unsigned 12-bit
61// displacement.
62def getDisp12Opcode : InstrMapping {
63  let FilterClass = "InstSystemZ";
64  let RowFields = ["Function"];
65  let ColFields = ["PairType"];
66  let KeyCol = ["20"];
67  let ValueCols = [["12"]];
68}
69
70// Return the version of an instruction that has a signed 20-bit displacement.
71def getDisp20Opcode : InstrMapping {
72  let FilterClass = "InstSystemZ";
73  let RowFields = ["Function"];
74  let ColFields = ["PairType"];
75  let KeyCol = ["12"];
76  let ValueCols = [["20"]];
77}
78
79//===----------------------------------------------------------------------===//
80// Instruction formats
81//===----------------------------------------------------------------------===//
82//
83// Formats are specified using operand field declarations of the form:
84//
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
91//
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*
97// orders.
98//
99//===----------------------------------------------------------------------===//
100
101class InstRI<bits<12> op, dag outs, dag ins, string asmstr, list<dag> pattern>
102  : InstSystemZ<4, outs, ins, asmstr, pattern> {
103  field bits<32> Inst;
104
105  bits<4> R1;
106  bits<16> I2;
107
108  let Inst{31-24} = op{11-4};
109  let Inst{23-20} = R1;
110  let Inst{19-16} = op{3-0};
111  let Inst{15-0}  = I2;
112}
113
114class InstRIEf<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
115  : InstSystemZ<6, outs, ins, asmstr, pattern> {
116  field bits<48> Inst;
117
118  bits<4> R1;
119  bits<4> R2;
120  bits<8> I3;
121  bits<8> I4;
122  bits<8> I5;
123
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;
129  let Inst{15-8}  = I5;
130  let Inst{7-0}   = op{7-0};
131}
132
133class InstRIL<bits<12> op, dag outs, dag ins, string asmstr, list<dag> pattern>
134  : InstSystemZ<6, outs, ins, asmstr, pattern> {
135  field bits<48> Inst;
136
137  bits<4> R1;
138  bits<32> I2;
139
140  let Inst{47-40} = op{11-4};
141  let Inst{39-36} = R1;
142  let Inst{35-32} = op{3-0};
143  let Inst{31-0}  = I2;
144}
145
146class InstRR<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
147  : InstSystemZ<2, outs, ins, asmstr, pattern> {
148  field bits<16> Inst;
149
150  bits<4> R1;
151  bits<4> R2;
152
153  let Inst{15-8} = op;
154  let Inst{7-4}  = R1;
155  let Inst{3-0}  = R2;
156}
157
158class InstRRD<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
159  : InstSystemZ<4, outs, ins, asmstr, pattern> {
160  field bits<32> Inst;
161
162  bits<4> R1;
163  bits<4> R3;
164  bits<4> R2;
165
166  let Inst{31-16} = op;
167  let Inst{15-12} = R1;
168  let Inst{11-8}  = 0;
169  let Inst{7-4}   = R3;
170  let Inst{3-0}   = R2;
171}
172
173class InstRRE<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
174  : InstSystemZ<4, outs, ins, asmstr, pattern> {
175  field bits<32> Inst;
176
177  bits<4> R1;
178  bits<4> R2;
179
180  let Inst{31-16} = op;
181  let Inst{15-8}  = 0;
182  let Inst{7-4}   = R1;
183  let Inst{3-0}   = R2;
184}
185
186class InstRRF<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
187  : InstSystemZ<4, outs, ins, asmstr, pattern> {
188  field bits<32> Inst;
189
190  bits<4> R1;
191  bits<4> R2;
192  bits<4> R3;
193
194  let Inst{31-16} = op;
195  let Inst{15-12} = R3;
196  let Inst{11-8}  = 0;
197  let Inst{7-4}   = R1;
198  let Inst{3-0}   = R2;
199}
200
201class InstRX<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
202  : InstSystemZ<4, outs, ins, asmstr, pattern> {
203  field bits<32> Inst;
204
205  bits<4> R1;
206  bits<4> B2;
207  bits<12> D2;
208  bits<4> X2;
209
210  let Inst{31-24} = op;
211  let Inst{23-20} = R1;
212  let Inst{19-16} = X2;
213  let Inst{15-12} = B2;
214  let Inst{11-0}  = D2;
215
216  let HasIndex = 1;
217}
218
219class InstRXE<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
220  : InstSystemZ<6, outs, ins, asmstr, pattern> {
221  field bits<48> Inst;
222
223  bits<4> R1;
224  bits<4> B2;
225  bits<12> D2;
226  bits<4> X2;
227
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;
233  let Inst{15-8}  = 0;
234  let Inst{7-0}   = op{7-0};
235
236  let HasIndex = 1;
237}
238
239class InstRXF<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
240  : InstSystemZ<6, outs, ins, asmstr, pattern> {
241  field bits<48> Inst;
242
243  bits<4> R1;
244  bits<4> R3;
245  bits<4> B2;
246  bits<12> D2;
247  bits<4> X2;
248
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;
255  let Inst{11-8}  = 0;
256  let Inst{7-0}   = op{7-0};
257
258  let HasIndex = 1;
259}
260
261class InstRXY<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
262  : InstSystemZ<6, outs, ins, asmstr, pattern> {
263  field bits<48> Inst;
264
265  bits<4> R1;
266  bits<4> B2;
267  bits<20> D2;
268  bits<4> X2;
269
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};
277
278  let Has20BitOffset = 1;
279  let HasIndex = 1;
280}
281
282class InstRS<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
283  : InstSystemZ<4, outs, ins, asmstr, pattern> {
284  field bits<32> Inst;
285
286  bits<4> R1;
287  bits<4> R3;
288  bits<4> B2;
289  bits<12> D2;
290
291  let Inst{31-24} = op;
292  let Inst{23-20} = R1;
293  let Inst{19-16} = R3;
294  let Inst{15-12} = B2;
295  let Inst{11-0}  = D2;
296}
297
298class InstRSY<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
299  : InstSystemZ<6, outs, ins, asmstr, pattern> {
300  field bits<48> Inst;
301
302  bits<4> R1;
303  bits<4> R3;
304  bits<4> B2;
305  bits<20> D2;
306
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};
314
315  let Has20BitOffset = 1;
316}
317
318class InstSI<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
319  : InstSystemZ<4, outs, ins, asmstr, pattern> {
320  field bits<32> Inst;
321
322  bits<4> B1;
323  bits<12> D1;
324  bits<8> I2;
325
326  let Inst{31-24} = op;
327  let Inst{23-16} = I2;
328  let Inst{15-12} = B1;
329  let Inst{11-0}  = D1;
330}
331
332class InstSIL<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
333  : InstSystemZ<6, outs, ins, asmstr, pattern> {
334  field bits<48> Inst;
335
336  bits<4> B1;
337  bits<12> D1;
338  bits<16> I2;
339
340  let Inst{47-32} = op;
341  let Inst{31-28} = B1;
342  let Inst{27-16} = D1;
343  let Inst{15-0}  = I2;
344}
345
346class InstSIY<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
347  : InstSystemZ<6, outs, ins, asmstr, pattern> {
348  field bits<48> Inst;
349
350  bits<4> B1;
351  bits<20> D1;
352  bits<8> I2;
353
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};
360
361  let Has20BitOffset = 1;
362}
363
364//===----------------------------------------------------------------------===//
365// Instruction definitions with semantics
366//===----------------------------------------------------------------------===//
367//
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:
371//
372//   Inherent:
373//     One register output operand and no input operands.
374//
375//   Store:
376//     One register or immediate input operand and one address input operand.
377//     The instruction stores the first operand to the address.
378//
379//     This category is used for both pure and truncating stores.
380//
381//   LoadMultiple:
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.
386//
387//   StoreMultiple:
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.
392//
393//   Unary:
394//     One register output operand and one input operand.  The input
395//     operand may be a register, immediate or memory.
396//
397//   Binary:
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.
401//
402//   Shift:
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).
406//
407//   Compare:
408//     Two input operands.  The first operand is always a register,
409//     the second may be a register, immediate or memory.
410//
411//   Ternary:
412//     One register output operand and three register input operands.
413//
414//   CmpSwap:
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.
418//
419//   RotateSelect:
420//     One output operand and five input operands.  The first two operands
421//     are registers and the other three are immediates.
422//
423// The format determines which input operands are tied to output operands,
424// and also determines the shape of any address operand.
425//
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
429// an extra "y".
430//
431//===----------------------------------------------------------------------===//
432
433class InherentRRE<string mnemonic, bits<16> opcode, RegisterOperand cls,
434                  dag src>
435  : InstRRE<opcode, (outs cls:$dst), (ins),
436            mnemonic#"\t$dst",
437            [(set cls:$dst, src)]> {
438  let R2 = 0;
439}
440
441class 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", []> {
444  let mayLoad = 1;
445}
446
447class StoreRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator,
448                 RegisterOperand cls>
449  : InstRIL<opcode, (outs), (ins cls:$src, pcrel32:$addr),
450            mnemonic#"\t$src, $addr",
451            [(operator cls:$src, pcrel32:$addr)]> {
452  let mayStore = 1;
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
455  // complex.
456  let AddedComplexity = 7;
457}
458
459class 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)]> {
464  let mayStore = 1;
465}
466
467class 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)]> {
472  let mayStore = 1;
473}
474
475multiclass 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>;
482  }
483}
484
485class 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", []> {
488  let mayStore = 1;
489}
490
491class 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)]> {
496  let mayStore = 1;
497}
498
499class 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)]> {
504  let mayStore = 1;
505}
506
507class StoreSIL<string mnemonic, bits<16> opcode, SDPatternOperator operator,
508               Immediate imm>
509  : InstSIL<opcode, (outs), (ins bdaddr12only:$addr, imm:$src),
510            mnemonic#"\t$addr, $src",
511            [(operator imm:$src, bdaddr12only:$addr)]> {
512  let mayStore = 1;
513}
514
515multiclass 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>;
522  }
523}
524
525class 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))]>;
530
531class 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))]>;
536
537class 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", []>;
541
542class 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))]>;
547
548class 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))]>;
553
554class UnaryRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator,
555                 RegisterOperand cls>
556  : InstRIL<opcode, (outs cls:$dst), (ins pcrel32:$addr),
557            mnemonic#"\t$dst, $addr",
558            [(set cls:$dst, (operator pcrel32:$addr))]> {
559  let mayLoad = 1;
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
562  // complex.
563  let AddedComplexity = 7;
564}
565
566class 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))]> {
571  let mayLoad = 1;
572}
573
574class UnaryRXE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
575               RegisterOperand cls>
576  : InstRXE<opcode, (outs cls:$dst), (ins bdxaddr12only:$addr),
577            mnemonic#"\t$dst, $addr",
578            [(set cls:$dst, (operator bdxaddr12only:$addr))]> {
579  let mayLoad = 1;
580}
581
582class 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))]> {
587  let mayLoad = 1;
588}
589
590multiclass 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>;
597  }
598}
599
600class 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";
607}
608
609class 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";
616}
617
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).
622//
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.
625class 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))]>;
630
631class 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";
638}
639
640class 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";
647}
648
649class 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";
657  let mayLoad = 1;
658}
659
660class 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";
668  let mayLoad = 1;
669}
670
671class 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";
679  let mayLoad = 1;
680}
681
682multiclass 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,
690                         bdxaddr20pair>;
691  }
692}
693
694class 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)]> {
699  let mayLoad = 1;
700  let mayStore = 1;
701}
702
703class 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)]> {
708  let mayLoad = 1;
709  let mayStore = 1;
710}
711
712multiclass BinarySIPair<string mnemonic, bits<8> siOpcode,
713                        bits<16> siyOpcode, SDPatternOperator operator,
714                        Operand imm> {
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>;
720  }
721}
722
723class 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))]> {
728  let R3 = 0;
729  let Constraints = "$src1 = $dst";
730  let DisableEncoding = "$src1";
731}
732
733class 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))]>;
738
739class 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)]>;
744
745class 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)]>;
750
751class 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)]>;
756
757class 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)]>;
762
763class 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))]> {
768  let mayLoad = 1;
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
771  // complex.
772  let AddedComplexity = 7;
773}
774
775class 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))]> {
781  let mayLoad = 1;
782}
783
784class 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))]> {
789  let mayLoad = 1;
790}
791
792class 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))]> {
798  let mayLoad = 1;
799}
800
801multiclass 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>;
811  }
812}
813
814class 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)]> {
820  let mayLoad = 1;
821}
822
823class 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)]> {
828  let mayLoad = 1;
829}
830
831class 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)]> {
837  let mayLoad = 1;
838}
839
840multiclass CompareSIPair<string mnemonic, bits<8> siOpcode, bits<16> siyOpcode,
841                         SDPatternOperator operator, SDPatternOperator load,
842                         Immediate imm> {
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,
848                          bdaddr20pair>;
849  }
850}
851
852class 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";
859}
860
861class 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";
870  let mayLoad = 1;
871}
872
873class 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";
880  let mayLoad = 1;
881  let mayStore = 1;
882}
883
884class 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";
891  let mayLoad = 1;
892  let mayStore = 1;
893}
894
895multiclass 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>;
902  }
903}
904
905class 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";
913}
914
915//===----------------------------------------------------------------------===//
916// Pseudo instructions
917//===----------------------------------------------------------------------===//
918//
919// Convenience instructions that get lowered to real instructions
920// by either SystemZTargetLowering::EmitInstrWithCustomInserter()
921// or SystemZInstrInfo::expandPostRAPseudo().
922//
923//===----------------------------------------------------------------------===//
924
925class Pseudo<dag outs, dag ins, list<dag> pattern>
926  : InstSystemZ<0, outs, ins, "", pattern> {
927  let isPseudo = 1;
928  let isCodeGenOnly = 1;
929}
930
931// Implements "$dst = $cc & (8 >> CC) ? $src1 : $src2", where CC is
932// the value of the PSW's 2-bit condition code field.
933class 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.
940  let Defs = [PSW];
941  let Uses = [PSW];
942}
943
944// OPERATOR is ATOMIC_SWAP or an ATOMIC_LOAD_* operation.  PAT and OPERAND
945// describe the second (non-memory) operand.
946class 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))]> {
950  let Defs = [PSW];
951  let Has20BitOffset = 1;
952  let mayLoad = 1;
953  let mayStore = 1;
954  let usesCustomInserter = 1;
955}
956
957// Specializations of AtomicLoadWBinary.
958class AtomicLoadBinaryReg32<SDPatternOperator operator>
959  : AtomicLoadBinary<operator, GR32, (i32 GR32:$src2), GR32>;
960class AtomicLoadBinaryImm32<SDPatternOperator operator, Immediate imm>
961  : AtomicLoadBinary<operator, GR32, (i32 imm:$src2), imm>;
962class AtomicLoadBinaryReg64<SDPatternOperator operator>
963  : AtomicLoadBinary<operator, GR64, (i64 GR64:$src2), GR64>;
964class AtomicLoadBinaryImm64<SDPatternOperator operator, Immediate imm>
965  : AtomicLoadBinary<operator, GR64, (i64 imm:$src2), imm>;
966
967// OPERATOR is ATOMIC_SWAPW or an ATOMIC_LOADW_* operation.  PAT and OPERAND
968// describe the second (non-memory) operand.
969class AtomicLoadWBinary<SDPatternOperator operator, dag pat,
970                        DAGOperand operand>
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))]> {
976  let Defs = [PSW];
977  let Has20BitOffset = 1;
978  let mayLoad = 1;
979  let mayStore = 1;
980  let usesCustomInserter = 1;
981}
982
983// Specializations of AtomicLoadWBinary.
984class AtomicLoadWBinaryReg<SDPatternOperator operator>
985  : AtomicLoadWBinary<operator, (i32 GR32:$src2), GR32>;
986class AtomicLoadWBinaryImm<SDPatternOperator operator, Immediate imm>
987  : AtomicLoadWBinary<operator, (i32 imm:$src2), imm>;
988