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  // 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"
27  // respectively.
28  string DispKey = "";
29  string DispSize = "none";
30
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>.
34  string OpKey = "";
35  string OpType = "none";
36
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";
42
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;
46
47  // True if this instruction is a simple D(X,B) store of a register
48  // (with no truncation).
49  bit SimpleBDXStore = 0;
50
51  // True if this instruction has a 20-bit displacement field.
52  bit Has20BitOffset = 0;
53
54  // True if addresses in this instruction have an index register.
55  bit HasIndex = 0;
56
57  // True if this is a 128-bit pseudo instruction that combines two 64-bit
58  // operations.
59  bit Is128Bit = 0;
60
61  // The access size of all memory operands in bytes, or 0 if not known.
62  bits<5> AccessBytes = 0;
63
64  // If the instruction sets CC to a useful value, this gives the mask
65  // of all possible CC results.  The mask has the same form as
66  // SystemZ::CCMASK_*.
67  bits<4> CCValues = 0;
68
69  // The subset of CCValues that have the same meaning as they would after
70  // a comparison of the first operand against zero.
71  bits<4> CompareZeroCCMask = 0;
72
73  // True if the instruction is conditional and if the CC mask operand
74  // comes first (as for BRC, etc.).
75  bit CCMaskFirst = 0;
76
77  // Similar, but true if the CC mask operand comes last (as for LOC, etc.).
78  bit CCMaskLast = 0;
79
80  // True if the instruction is the "logical" rather than "arithmetic" form,
81  // in cases where a distinction exists.
82  bit IsLogical = 0;
83
84  let TSFlags{0}     = SimpleBDXLoad;
85  let TSFlags{1}     = SimpleBDXStore;
86  let TSFlags{2}     = Has20BitOffset;
87  let TSFlags{3}     = HasIndex;
88  let TSFlags{4}     = Is128Bit;
89  let TSFlags{9-5}   = AccessBytes;
90  let TSFlags{13-10} = CCValues;
91  let TSFlags{17-14} = CompareZeroCCMask;
92  let TSFlags{18}    = CCMaskFirst;
93  let TSFlags{19}    = CCMaskLast;
94  let TSFlags{20}    = IsLogical;
95}
96
97//===----------------------------------------------------------------------===//
98// Mappings between instructions
99//===----------------------------------------------------------------------===//
100
101// Return the version of an instruction that has an unsigned 12-bit
102// displacement.
103def getDisp12Opcode : InstrMapping {
104  let FilterClass = "InstSystemZ";
105  let RowFields = ["DispKey"];
106  let ColFields = ["DispSize"];
107  let KeyCol = ["20"];
108  let ValueCols = [["12"]];
109}
110
111// Return the version of an instruction that has a signed 20-bit displacement.
112def getDisp20Opcode : InstrMapping {
113  let FilterClass = "InstSystemZ";
114  let RowFields = ["DispKey"];
115  let ColFields = ["DispSize"];
116  let KeyCol = ["12"];
117  let ValueCols = [["20"]];
118}
119
120// Return the memory form of a register instruction.
121def getMemOpcode : InstrMapping {
122  let FilterClass = "InstSystemZ";
123  let RowFields = ["OpKey"];
124  let ColFields = ["OpType"];
125  let KeyCol = ["reg"];
126  let ValueCols = [["mem"]];
127}
128
129// Return the 3-operand form of a 2-operand instruction.
130def getThreeOperandOpcode : InstrMapping {
131  let FilterClass = "InstSystemZ";
132  let RowFields = ["NumOpsKey"];
133  let ColFields = ["NumOpsValue"];
134  let KeyCol = ["2"];
135  let ValueCols = [["3"]];
136}
137
138//===----------------------------------------------------------------------===//
139// Instruction formats
140//===----------------------------------------------------------------------===//
141//
142// Formats are specified using operand field declarations of the form:
143//
144//   bits<4> Rn   : register input or output for operand n
145//   bits<m> In   : immediate value of width m for operand n
146//   bits<4> BDn  : address operand n, which has a base and a displacement
147//   bits<m> XBDn : address operand n, which has an index, a base and a
148//                  displacement
149//   bits<4> Xn   : index register for address operand n
150//   bits<4> Mn   : mode value for operand n
151//
152// The operand numbers ("n" in the list above) follow the architecture manual.
153// Assembly operands sometimes have a different order; in particular, R3 often
154// is often written between operands 1 and 2.
155//
156//===----------------------------------------------------------------------===//
157
158class InstRI<bits<12> op, dag outs, dag ins, string asmstr, list<dag> pattern>
159  : InstSystemZ<4, outs, ins, asmstr, pattern> {
160  field bits<32> Inst;
161  field bits<32> SoftFail = 0;
162
163  bits<4> R1;
164  bits<16> I2;
165
166  let Inst{31-24} = op{11-4};
167  let Inst{23-20} = R1;
168  let Inst{19-16} = op{3-0};
169  let Inst{15-0}  = I2;
170}
171
172class InstRIEb<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
173  : InstSystemZ<6, outs, ins, asmstr, pattern> {
174  field bits<48> Inst;
175  field bits<48> SoftFail = 0;
176
177  bits<4> R1;
178  bits<4> R2;
179  bits<4> M3;
180  bits<16> RI4;
181
182  let Inst{47-40} = op{15-8};
183  let Inst{39-36} = R1;
184  let Inst{35-32} = R2;
185  let Inst{31-16} = RI4;
186  let Inst{15-12} = M3;
187  let Inst{11-8}  = 0;
188  let Inst{7-0}   = op{7-0};
189}
190
191class InstRIEc<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
192  : InstSystemZ<6, outs, ins, asmstr, pattern> {
193  field bits<48> Inst;
194  field bits<48> SoftFail = 0;
195
196  bits<4> R1;
197  bits<8> I2;
198  bits<4> M3;
199  bits<16> RI4;
200
201  let Inst{47-40} = op{15-8};
202  let Inst{39-36} = R1;
203  let Inst{35-32} = M3;
204  let Inst{31-16} = RI4;
205  let Inst{15-8}  = I2;
206  let Inst{7-0}   = op{7-0};
207}
208
209class InstRIEd<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
210  : InstSystemZ<6, outs, ins, asmstr, pattern> {
211  field bits<48> Inst;
212  field bits<48> SoftFail = 0;
213
214  bits<4> R1;
215  bits<4> R3;
216  bits<16> I2;
217
218  let Inst{47-40} = op{15-8};
219  let Inst{39-36} = R1;
220  let Inst{35-32} = R3;
221  let Inst{31-16} = I2;
222  let Inst{15-8}  = 0;
223  let Inst{7-0}   = op{7-0};
224}
225
226class InstRIEf<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
227  : InstSystemZ<6, outs, ins, asmstr, pattern> {
228  field bits<48> Inst;
229  field bits<48> SoftFail = 0;
230
231  bits<4> R1;
232  bits<4> R2;
233  bits<8> I3;
234  bits<8> I4;
235  bits<8> I5;
236
237  let Inst{47-40} = op{15-8};
238  let Inst{39-36} = R1;
239  let Inst{35-32} = R2;
240  let Inst{31-24} = I3;
241  let Inst{23-16} = I4;
242  let Inst{15-8}  = I5;
243  let Inst{7-0}   = op{7-0};
244}
245
246class InstRIL<bits<12> op, dag outs, dag ins, string asmstr, list<dag> pattern>
247  : InstSystemZ<6, outs, ins, asmstr, pattern> {
248  field bits<48> Inst;
249  field bits<48> SoftFail = 0;
250
251  bits<4> R1;
252  bits<32> I2;
253
254  let Inst{47-40} = op{11-4};
255  let Inst{39-36} = R1;
256  let Inst{35-32} = op{3-0};
257  let Inst{31-0}  = I2;
258}
259
260class InstRR<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
261  : InstSystemZ<2, outs, ins, asmstr, pattern> {
262  field bits<16> Inst;
263  field bits<16> SoftFail = 0;
264
265  bits<4> R1;
266  bits<4> R2;
267
268  let Inst{15-8} = op;
269  let Inst{7-4}  = R1;
270  let Inst{3-0}  = R2;
271}
272
273class InstRRD<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
274  : InstSystemZ<4, outs, ins, asmstr, pattern> {
275  field bits<32> Inst;
276  field bits<32> SoftFail = 0;
277
278  bits<4> R1;
279  bits<4> R3;
280  bits<4> R2;
281
282  let Inst{31-16} = op;
283  let Inst{15-12} = R1;
284  let Inst{11-8}  = 0;
285  let Inst{7-4}   = R3;
286  let Inst{3-0}   = R2;
287}
288
289class InstRRE<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
290  : InstSystemZ<4, outs, ins, asmstr, pattern> {
291  field bits<32> Inst;
292  field bits<32> SoftFail = 0;
293
294  bits<4> R1;
295  bits<4> R2;
296
297  let Inst{31-16} = op;
298  let Inst{15-8}  = 0;
299  let Inst{7-4}   = R1;
300  let Inst{3-0}   = R2;
301}
302
303class InstRRF<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
304  : InstSystemZ<4, outs, ins, asmstr, pattern> {
305  field bits<32> Inst;
306  field bits<32> SoftFail = 0;
307
308  bits<4> R1;
309  bits<4> R2;
310  bits<4> R3;
311  bits<4> R4;
312
313  let Inst{31-16} = op;
314  let Inst{15-12} = R3;
315  let Inst{11-8}  = R4;
316  let Inst{7-4}   = R1;
317  let Inst{3-0}   = R2;
318}
319
320class InstRX<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
321  : InstSystemZ<4, outs, ins, asmstr, pattern> {
322  field bits<32> Inst;
323  field bits<32> SoftFail = 0;
324
325  bits<4> R1;
326  bits<20> XBD2;
327
328  let Inst{31-24} = op;
329  let Inst{23-20} = R1;
330  let Inst{19-0}  = XBD2;
331
332  let HasIndex = 1;
333}
334
335class InstRXE<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
336  : InstSystemZ<6, outs, ins, asmstr, pattern> {
337  field bits<48> Inst;
338  field bits<48> SoftFail = 0;
339
340  bits<4> R1;
341  bits<20> XBD2;
342
343  let Inst{47-40} = op{15-8};
344  let Inst{39-36} = R1;
345  let Inst{35-16} = XBD2;
346  let Inst{15-8}  = 0;
347  let Inst{7-0}   = op{7-0};
348
349  let HasIndex = 1;
350}
351
352class InstRXF<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
353  : InstSystemZ<6, outs, ins, asmstr, pattern> {
354  field bits<48> Inst;
355  field bits<48> SoftFail = 0;
356
357  bits<4> R1;
358  bits<4> R3;
359  bits<20> XBD2;
360
361  let Inst{47-40} = op{15-8};
362  let Inst{39-36} = R3;
363  let Inst{35-16} = XBD2;
364  let Inst{15-12} = R1;
365  let Inst{11-8}  = 0;
366  let Inst{7-0}   = op{7-0};
367
368  let HasIndex = 1;
369}
370
371class InstRXY<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
372  : InstSystemZ<6, outs, ins, asmstr, pattern> {
373  field bits<48> Inst;
374  field bits<48> SoftFail = 0;
375
376  bits<4> R1;
377  bits<28> XBD2;
378
379  let Inst{47-40} = op{15-8};
380  let Inst{39-36} = R1;
381  let Inst{35-8}  = XBD2;
382  let Inst{7-0}   = op{7-0};
383
384  let Has20BitOffset = 1;
385  let HasIndex = 1;
386}
387
388class InstRS<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
389  : InstSystemZ<4, outs, ins, asmstr, pattern> {
390  field bits<32> Inst;
391  field bits<32> SoftFail = 0;
392
393  bits<4> R1;
394  bits<4> R3;
395  bits<16> BD2;
396
397  let Inst{31-24} = op;
398  let Inst{23-20} = R1;
399  let Inst{19-16} = R3;
400  let Inst{15-0}  = BD2;
401}
402
403class InstRSY<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
404  : InstSystemZ<6, outs, ins, asmstr, pattern> {
405  field bits<48> Inst;
406  field bits<48> SoftFail = 0;
407
408  bits<4> R1;
409  bits<4> R3;
410  bits<24> BD2;
411
412  let Inst{47-40} = op{15-8};
413  let Inst{39-36} = R1;
414  let Inst{35-32} = R3;
415  let Inst{31-8}  = BD2;
416  let Inst{7-0}   = op{7-0};
417
418  let Has20BitOffset = 1;
419}
420
421class InstSI<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
422  : InstSystemZ<4, outs, ins, asmstr, pattern> {
423  field bits<32> Inst;
424  field bits<32> SoftFail = 0;
425
426  bits<16> BD1;
427  bits<8> I2;
428
429  let Inst{31-24} = op;
430  let Inst{23-16} = I2;
431  let Inst{15-0}  = BD1;
432}
433
434class InstSIL<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
435  : InstSystemZ<6, outs, ins, asmstr, pattern> {
436  field bits<48> Inst;
437  field bits<48> SoftFail = 0;
438
439  bits<16> BD1;
440  bits<16> I2;
441
442  let Inst{47-32} = op;
443  let Inst{31-16} = BD1;
444  let Inst{15-0}  = I2;
445}
446
447class InstSIY<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
448  : InstSystemZ<6, outs, ins, asmstr, pattern> {
449  field bits<48> Inst;
450  field bits<48> SoftFail = 0;
451
452  bits<24> BD1;
453  bits<8> I2;
454
455  let Inst{47-40} = op{15-8};
456  let Inst{39-32} = I2;
457  let Inst{31-8}  = BD1;
458  let Inst{7-0}   = op{7-0};
459
460  let Has20BitOffset = 1;
461}
462
463class InstSS<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
464  : InstSystemZ<6, outs, ins, asmstr, pattern> {
465  field bits<48> Inst;
466  field bits<48> SoftFail = 0;
467
468  bits<24> BDL1;
469  bits<16> BD2;
470
471  let Inst{47-40} = op;
472  let Inst{39-16} = BDL1;
473  let Inst{15-0}  = BD2;
474}
475
476//===----------------------------------------------------------------------===//
477// Instruction definitions with semantics
478//===----------------------------------------------------------------------===//
479//
480// These classes have the form [Cond]<Category><Format>, where <Format> is one
481// of the formats defined above and where <Category> describes the inputs
482// and outputs.  "Cond" is used if the instruction is conditional,
483// in which case the 4-bit condition-code mask is added as a final operand.
484// <Category> can be one of:
485//
486//   Inherent:
487//     One register output operand and no input operands.
488//
489//   BranchUnary:
490//     One register output operand, one register input operand and
491//     one branch displacement.  The instructions stores a modified
492//     form of the source register in the destination register and
493//     branches on the result.
494//
495//   Store:
496//     One register or immediate input operand and one address input operand.
497//     The instruction stores the first operand to the address.
498//
499//     This category is used for both pure and truncating stores.
500//
501//   LoadMultiple:
502//     One address input operand and two explicit output operands.
503//     The instruction loads a range of registers from the address,
504//     with the explicit operands giving the first and last register
505//     to load.  Other loaded registers are added as implicit definitions.
506//
507//   StoreMultiple:
508//     Two explicit input register operands and an address operand.
509//     The instruction stores a range of registers to the address,
510//     with the explicit operands giving the first and last register
511//     to store.  Other stored registers are added as implicit uses.
512//
513//   Unary:
514//     One register output operand and one input operand.  The input
515//     operand may be a register, immediate or memory.
516//
517//   Binary:
518//     One register output operand and two input operands.  The first
519//     input operand is always a register and he second may be a register,
520//     immediate or memory.
521//
522//   Shift:
523//     One register output operand and two input operands.  The first
524//     input operand is a register and the second has the same form as
525//     an address (although it isn't actually used to address memory).
526//
527//   Compare:
528//     Two input operands.  The first operand is always a register,
529//     the second may be a register, immediate or memory.
530//
531//   Ternary:
532//     One register output operand and three register input operands.
533//
534//   CmpSwap:
535//     One output operand and three input operands.  The first two
536//     operands are registers and the third is an address.  The instruction
537//     both reads from and writes to the address.
538//
539//   RotateSelect:
540//     One output operand and five input operands.  The first two operands
541//     are registers and the other three are immediates.
542//
543//   Prefetch:
544//     One 4-bit immediate operand and one address operand.  The immediate
545//     operand is 1 for a load prefetch and 2 for a store prefetch.
546//
547// The format determines which input operands are tied to output operands,
548// and also determines the shape of any address operand.
549//
550// Multiclasses of the form <Category><Format>Pair define two instructions,
551// one with <Category><Format> and one with <Category><Format>Y.  The name
552// of the first instruction has no suffix, the name of the second has
553// an extra "y".
554//
555//===----------------------------------------------------------------------===//
556
557class InherentRRE<string mnemonic, bits<16> opcode, RegisterOperand cls,
558                  dag src>
559  : InstRRE<opcode, (outs cls:$R1), (ins),
560            mnemonic#"\t$R1",
561            [(set cls:$R1, src)]> {
562  let R2 = 0;
563}
564
565class BranchUnaryRI<string mnemonic, bits<12> opcode, RegisterOperand cls>
566  : InstRI<opcode, (outs cls:$R1), (ins cls:$R1src, brtarget16:$I2),
567           mnemonic##"\t$R1, $I2", []> {
568  let isBranch = 1;
569  let isTerminator = 1;
570  let Constraints = "$R1 = $R1src";
571  let DisableEncoding = "$R1src";
572}
573
574class LoadMultipleRSY<string mnemonic, bits<16> opcode, RegisterOperand cls>
575  : InstRSY<opcode, (outs cls:$R1, cls:$R3), (ins bdaddr20only:$BD2),
576            mnemonic#"\t$R1, $R3, $BD2", []> {
577  let mayLoad = 1;
578}
579
580class StoreRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator,
581                 RegisterOperand cls>
582  : InstRIL<opcode, (outs), (ins cls:$R1, pcrel32:$I2),
583            mnemonic#"\t$R1, $I2",
584            [(operator cls:$R1, pcrel32:$I2)]> {
585  let mayStore = 1;
586  // We want PC-relative addresses to be tried ahead of BD and BDX addresses.
587  // However, BDXs have two extra operands and are therefore 6 units more
588  // complex.
589  let AddedComplexity = 7;
590}
591
592class StoreRX<string mnemonic, bits<8> opcode, SDPatternOperator operator,
593              RegisterOperand cls, bits<5> bytes,
594              AddressingMode mode = bdxaddr12only>
595  : InstRX<opcode, (outs), (ins cls:$R1, mode:$XBD2),
596           mnemonic#"\t$R1, $XBD2",
597           [(operator cls:$R1, mode:$XBD2)]> {
598  let OpKey = mnemonic ## cls;
599  let OpType = "mem";
600  let mayStore = 1;
601  let AccessBytes = bytes;
602}
603
604class StoreRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
605               RegisterOperand cls, bits<5> bytes,
606               AddressingMode mode = bdxaddr20only>
607  : InstRXY<opcode, (outs), (ins cls:$R1, mode:$XBD2),
608            mnemonic#"\t$R1, $XBD2",
609            [(operator cls:$R1, mode:$XBD2)]> {
610  let OpKey = mnemonic ## cls;
611  let OpType = "mem";
612  let mayStore = 1;
613  let AccessBytes = bytes;
614}
615
616multiclass StoreRXPair<string mnemonic, bits<8> rxOpcode, bits<16> rxyOpcode,
617                       SDPatternOperator operator, RegisterOperand cls,
618                       bits<5> bytes> {
619  let DispKey = mnemonic ## #cls in {
620    let DispSize = "12" in
621      def "" : StoreRX<mnemonic, rxOpcode, operator, cls, bytes, bdxaddr12pair>;
622    let DispSize = "20" in
623      def Y  : StoreRXY<mnemonic#"y", rxyOpcode, operator, cls, bytes,
624                        bdxaddr20pair>;
625  }
626}
627
628class StoreMultipleRSY<string mnemonic, bits<16> opcode, RegisterOperand cls>
629  : InstRSY<opcode, (outs), (ins cls:$R1, cls:$R3, bdaddr20only:$BD2),
630            mnemonic#"\t$R1, $R3, $BD2", []> {
631  let mayStore = 1;
632}
633
634// StoreSI* instructions are used to store an integer to memory, but the
635// addresses are more restricted than for normal stores.  If we are in the
636// situation of having to force either the address into a register or the
637// constant into a register, it's usually better to do the latter.
638// We therefore match the address in the same way as a normal store and
639// only use the StoreSI* instruction if the matched address is suitable.
640class StoreSI<string mnemonic, bits<8> opcode, SDPatternOperator operator,
641              Immediate imm>
642  : InstSI<opcode, (outs), (ins mviaddr12pair:$BD1, imm:$I2),
643           mnemonic#"\t$BD1, $I2",
644           [(operator imm:$I2, mviaddr12pair:$BD1)]> {
645  let mayStore = 1;
646}
647
648class StoreSIY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
649               Immediate imm>
650  : InstSIY<opcode, (outs), (ins mviaddr20pair:$BD1, imm:$I2),
651            mnemonic#"\t$BD1, $I2",
652            [(operator imm:$I2, mviaddr20pair:$BD1)]> {
653  let mayStore = 1;
654}
655
656class StoreSIL<string mnemonic, bits<16> opcode, SDPatternOperator operator,
657               Immediate imm>
658  : InstSIL<opcode, (outs), (ins mviaddr12pair:$BD1, imm:$I2),
659            mnemonic#"\t$BD1, $I2",
660            [(operator imm:$I2, mviaddr12pair:$BD1)]> {
661  let mayStore = 1;
662}
663
664multiclass StoreSIPair<string mnemonic, bits<8> siOpcode, bits<16> siyOpcode,
665                       SDPatternOperator operator, Immediate imm> {
666  let DispKey = mnemonic in {
667    let DispSize = "12" in
668      def "" : StoreSI<mnemonic, siOpcode, operator, imm>;
669    let DispSize = "20" in
670      def Y  : StoreSIY<mnemonic#"y", siyOpcode, operator, imm>;
671  }
672}
673
674class CondStoreRSY<string mnemonic, bits<16> opcode,
675                   RegisterOperand cls, bits<5> bytes,
676                   AddressingMode mode = bdaddr20only>
677  : InstRSY<opcode, (outs), (ins cls:$R1, mode:$BD2, cond4:$valid, cond4:$R3),
678            mnemonic#"$R3\t$R1, $BD2", []>,
679    Requires<[FeatureLoadStoreOnCond]> {
680  let mayStore = 1;
681  let AccessBytes = bytes;
682  let CCMaskLast = 1;
683}
684
685// Like CondStoreRSY, but used for the raw assembly form.  The condition-code
686// mask is the third operand rather than being part of the mnemonic.
687class AsmCondStoreRSY<string mnemonic, bits<16> opcode,
688                      RegisterOperand cls, bits<5> bytes,
689                      AddressingMode mode = bdaddr20only>
690  : InstRSY<opcode, (outs), (ins cls:$R1, mode:$BD2, uimm8zx4:$R3),
691            mnemonic#"\t$R1, $BD2, $R3", []>,
692    Requires<[FeatureLoadStoreOnCond]> {
693  let mayStore = 1;
694  let AccessBytes = bytes;
695}
696
697// Like CondStoreRSY, but with a fixed CC mask.
698class FixedCondStoreRSY<string mnemonic, bits<16> opcode,
699                        RegisterOperand cls, bits<4> ccmask, bits<5> bytes,
700                        AddressingMode mode = bdaddr20only>
701  : InstRSY<opcode, (outs), (ins cls:$R1, mode:$BD2),
702            mnemonic#"\t$R1, $BD2", []>,
703    Requires<[FeatureLoadStoreOnCond]> {
704  let mayStore = 1;
705  let AccessBytes = bytes;
706  let R3 = ccmask;
707}
708
709class UnaryRR<string mnemonic, bits<8> opcode, SDPatternOperator operator,
710              RegisterOperand cls1, RegisterOperand cls2>
711  : InstRR<opcode, (outs cls1:$R1), (ins cls2:$R2),
712           mnemonic#"r\t$R1, $R2",
713           [(set cls1:$R1, (operator cls2:$R2))]> {
714  let OpKey = mnemonic ## cls1;
715  let OpType = "reg";
716}
717
718class UnaryRRE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
719               RegisterOperand cls1, RegisterOperand cls2>
720  : InstRRE<opcode, (outs cls1:$R1), (ins cls2:$R2),
721            mnemonic#"r\t$R1, $R2",
722            [(set cls1:$R1, (operator cls2:$R2))]> {
723  let OpKey = mnemonic ## cls1;
724  let OpType = "reg";
725}
726
727class UnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1,
728               RegisterOperand cls2>
729  : InstRRF<opcode, (outs cls1:$R1), (ins uimm8zx4:$R3, cls2:$R2),
730            mnemonic#"r\t$R1, $R3, $R2", []> {
731  let OpKey = mnemonic ## cls1;
732  let OpType = "reg";
733  let R4 = 0;
734}
735
736class UnaryRRF4<string mnemonic, bits<16> opcode, RegisterOperand cls1,
737                RegisterOperand cls2>
738  : InstRRF<opcode, (outs cls1:$R1), (ins uimm8zx4:$R3, cls2:$R2, uimm8zx4:$R4),
739            mnemonic#"\t$R1, $R3, $R2, $R4", []>;
740
741// These instructions are generated by if conversion.  The old value of R1
742// is added as an implicit use.
743class CondUnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1,
744                   RegisterOperand cls2>
745  : InstRRF<opcode, (outs cls1:$R1), (ins cls2:$R2, cond4:$valid, cond4:$R3),
746            mnemonic#"r$R3\t$R1, $R2", []>,
747    Requires<[FeatureLoadStoreOnCond]> {
748  let CCMaskLast = 1;
749  let R4 = 0;
750}
751
752// Like CondUnaryRRF, but used for the raw assembly form.  The condition-code
753// mask is the third operand rather than being part of the mnemonic.
754class AsmCondUnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1,
755                      RegisterOperand cls2>
756  : InstRRF<opcode, (outs cls1:$R1), (ins cls1:$R1src, cls2:$R2, uimm8zx4:$R3),
757            mnemonic#"r\t$R1, $R2, $R3", []>,
758    Requires<[FeatureLoadStoreOnCond]> {
759  let Constraints = "$R1 = $R1src";
760  let DisableEncoding = "$R1src";
761  let R4 = 0;
762}
763
764// Like CondUnaryRRF, but with a fixed CC mask.
765class FixedCondUnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1,
766                        RegisterOperand cls2, bits<4> ccmask>
767  : InstRRF<opcode, (outs cls1:$R1), (ins cls1:$R1src, cls2:$R2),
768            mnemonic#"\t$R1, $R2", []>,
769    Requires<[FeatureLoadStoreOnCond]> {
770  let Constraints = "$R1 = $R1src";
771  let DisableEncoding = "$R1src";
772  let R3 = ccmask;
773  let R4 = 0;
774}
775
776class UnaryRI<string mnemonic, bits<12> opcode, SDPatternOperator operator,
777              RegisterOperand cls, Immediate imm>
778  : InstRI<opcode, (outs cls:$R1), (ins imm:$I2),
779           mnemonic#"\t$R1, $I2",
780           [(set cls:$R1, (operator imm:$I2))]>;
781
782class UnaryRIL<string mnemonic, bits<12> opcode, SDPatternOperator operator,
783               RegisterOperand cls, Immediate imm>
784  : InstRIL<opcode, (outs cls:$R1), (ins imm:$I2),
785            mnemonic#"\t$R1, $I2",
786            [(set cls:$R1, (operator imm:$I2))]>;
787
788class UnaryRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator,
789                 RegisterOperand cls>
790  : InstRIL<opcode, (outs cls:$R1), (ins pcrel32:$I2),
791            mnemonic#"\t$R1, $I2",
792            [(set cls:$R1, (operator pcrel32:$I2))]> {
793  let mayLoad = 1;
794  // We want PC-relative addresses to be tried ahead of BD and BDX addresses.
795  // However, BDXs have two extra operands and are therefore 6 units more
796  // complex.
797  let AddedComplexity = 7;
798}
799
800class CondUnaryRSY<string mnemonic, bits<16> opcode,
801                   SDPatternOperator operator, RegisterOperand cls,
802                   bits<5> bytes, AddressingMode mode = bdaddr20only>
803  : InstRSY<opcode, (outs cls:$R1),
804            (ins cls:$R1src, mode:$BD2, cond4:$valid, cond4:$R3),
805            mnemonic#"$R3\t$R1, $BD2",
806            [(set cls:$R1,
807                  (z_select_ccmask (load bdaddr20only:$BD2), cls:$R1src,
808                                   cond4:$valid, cond4:$R3))]>,
809    Requires<[FeatureLoadStoreOnCond]> {
810  let Constraints = "$R1 = $R1src";
811  let DisableEncoding = "$R1src";
812  let mayLoad = 1;
813  let AccessBytes = bytes;
814  let CCMaskLast = 1;
815}
816
817// Like CondUnaryRSY, but used for the raw assembly form.  The condition-code
818// mask is the third operand rather than being part of the mnemonic.
819class AsmCondUnaryRSY<string mnemonic, bits<16> opcode,
820                      RegisterOperand cls, bits<5> bytes,
821                      AddressingMode mode = bdaddr20only>
822  : InstRSY<opcode, (outs cls:$R1), (ins cls:$R1src, mode:$BD2, uimm8zx4:$R3),
823            mnemonic#"\t$R1, $BD2, $R3", []>,
824    Requires<[FeatureLoadStoreOnCond]> {
825  let mayLoad = 1;
826  let AccessBytes = bytes;
827  let Constraints = "$R1 = $R1src";
828  let DisableEncoding = "$R1src";
829}
830
831// Like CondUnaryRSY, but with a fixed CC mask.
832class FixedCondUnaryRSY<string mnemonic, bits<16> opcode,
833                        RegisterOperand cls, bits<4> ccmask, bits<5> bytes,
834                        AddressingMode mode = bdaddr20only>
835  : InstRSY<opcode, (outs cls:$R1), (ins cls:$R1src, mode:$BD2),
836            mnemonic#"\t$R1, $BD2", []>,
837    Requires<[FeatureLoadStoreOnCond]> {
838  let Constraints = "$R1 = $R1src";
839  let DisableEncoding = "$R1src";
840  let R3 = ccmask;
841  let mayLoad = 1;
842  let AccessBytes = bytes;
843}
844
845class UnaryRX<string mnemonic, bits<8> opcode, SDPatternOperator operator,
846              RegisterOperand cls, bits<5> bytes,
847              AddressingMode mode = bdxaddr12only>
848  : InstRX<opcode, (outs cls:$R1), (ins mode:$XBD2),
849           mnemonic#"\t$R1, $XBD2",
850           [(set cls:$R1, (operator mode:$XBD2))]> {
851  let OpKey = mnemonic ## cls;
852  let OpType = "mem";
853  let mayLoad = 1;
854  let AccessBytes = bytes;
855}
856
857class UnaryRXE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
858               RegisterOperand cls, bits<5> bytes>
859  : InstRXE<opcode, (outs cls:$R1), (ins bdxaddr12only:$XBD2),
860            mnemonic#"\t$R1, $XBD2",
861            [(set cls:$R1, (operator bdxaddr12only:$XBD2))]> {
862  let OpKey = mnemonic ## cls;
863  let OpType = "mem";
864  let mayLoad = 1;
865  let AccessBytes = bytes;
866}
867
868class UnaryRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
869               RegisterOperand cls, bits<5> bytes,
870               AddressingMode mode = bdxaddr20only>
871  : InstRXY<opcode, (outs cls:$R1), (ins mode:$XBD2),
872            mnemonic#"\t$R1, $XBD2",
873            [(set cls:$R1, (operator mode:$XBD2))]> {
874  let OpKey = mnemonic ## cls;
875  let OpType = "mem";
876  let mayLoad = 1;
877  let AccessBytes = bytes;
878}
879
880multiclass UnaryRXPair<string mnemonic, bits<8> rxOpcode, bits<16> rxyOpcode,
881                       SDPatternOperator operator, RegisterOperand cls,
882                       bits<5> bytes> {
883  let DispKey = mnemonic ## #cls in {
884    let DispSize = "12" in
885      def "" : UnaryRX<mnemonic, rxOpcode, operator, cls, bytes, bdxaddr12pair>;
886    let DispSize = "20" in
887      def Y  : UnaryRXY<mnemonic#"y", rxyOpcode, operator, cls, bytes,
888                        bdxaddr20pair>;
889  }
890}
891
892class BinaryRR<string mnemonic, bits<8> opcode, SDPatternOperator operator,
893               RegisterOperand cls1, RegisterOperand cls2>
894  : InstRR<opcode, (outs cls1:$R1), (ins cls1:$R1src, cls2:$R2),
895           mnemonic#"r\t$R1, $R2",
896           [(set cls1:$R1, (operator cls1:$R1src, cls2:$R2))]> {
897  let OpKey = mnemonic ## cls1;
898  let OpType = "reg";
899  let Constraints = "$R1 = $R1src";
900  let DisableEncoding = "$R1src";
901}
902
903class BinaryRRE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
904                RegisterOperand cls1, RegisterOperand cls2>
905  : InstRRE<opcode, (outs cls1:$R1), (ins cls1:$R1src, cls2:$R2),
906            mnemonic#"r\t$R1, $R2",
907            [(set cls1:$R1, (operator cls1:$R1src, cls2:$R2))]> {
908  let OpKey = mnemonic ## cls1;
909  let OpType = "reg";
910  let Constraints = "$R1 = $R1src";
911  let DisableEncoding = "$R1src";
912}
913
914class BinaryRRF<string mnemonic, bits<16> opcode, SDPatternOperator operator,
915                RegisterOperand cls1, RegisterOperand cls2>
916  : InstRRF<opcode, (outs cls1:$R1), (ins cls1:$R3, cls2:$R2),
917            mnemonic#"r\t$R1, $R3, $R2",
918            [(set cls1:$R1, (operator cls1:$R3, cls2:$R2))]> {
919  let OpKey = mnemonic ## cls1;
920  let OpType = "reg";
921  let R4 = 0;
922}
923
924class BinaryRRFK<string mnemonic, bits<16> opcode, SDPatternOperator operator,
925                 RegisterOperand cls1, RegisterOperand cls2>
926  : InstRRF<opcode, (outs cls1:$R1), (ins cls1:$R2, cls2:$R3),
927            mnemonic#"rk\t$R1, $R2, $R3",
928            [(set cls1:$R1, (operator cls1:$R2, cls2:$R3))]> {
929  let R4 = 0;
930}
931
932multiclass BinaryRRAndK<string mnemonic, bits<8> opcode1, bits<16> opcode2,
933                        SDPatternOperator operator, RegisterOperand cls1,
934                        RegisterOperand cls2> {
935  let NumOpsKey = mnemonic in {
936    let NumOpsValue = "3" in
937      def K : BinaryRRFK<mnemonic, opcode2, null_frag, cls1, cls2>,
938              Requires<[FeatureDistinctOps]>;
939    let NumOpsValue = "2", isConvertibleToThreeAddress = 1 in
940      def "" : BinaryRR<mnemonic, opcode1, operator, cls1, cls2>;
941  }
942}
943
944multiclass BinaryRREAndK<string mnemonic, bits<16> opcode1, bits<16> opcode2,
945                         SDPatternOperator operator, RegisterOperand cls1,
946                         RegisterOperand cls2> {
947  let NumOpsKey = mnemonic in {
948    let NumOpsValue = "3" in
949      def K : BinaryRRFK<mnemonic, opcode2, null_frag, cls1, cls2>,
950              Requires<[FeatureDistinctOps]>;
951    let NumOpsValue = "2", isConvertibleToThreeAddress = 1 in
952      def "" : BinaryRRE<mnemonic, opcode1, operator, cls1, cls2>;
953  }
954}
955
956class BinaryRI<string mnemonic, bits<12> opcode, SDPatternOperator operator,
957               RegisterOperand cls, Immediate imm>
958  : InstRI<opcode, (outs cls:$R1), (ins cls:$R1src, imm:$I2),
959           mnemonic#"\t$R1, $I2",
960           [(set cls:$R1, (operator cls:$R1src, imm:$I2))]> {
961  let Constraints = "$R1 = $R1src";
962  let DisableEncoding = "$R1src";
963}
964
965class BinaryRIE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
966                RegisterOperand cls, Immediate imm>
967  : InstRIEd<opcode, (outs cls:$R1), (ins cls:$R3, imm:$I2),
968             mnemonic#"\t$R1, $R3, $I2",
969             [(set cls:$R1, (operator cls:$R3, imm:$I2))]>;
970
971multiclass BinaryRIAndK<string mnemonic, bits<12> opcode1, bits<16> opcode2,
972                        SDPatternOperator operator, RegisterOperand cls,
973                        Immediate imm> {
974  let NumOpsKey = mnemonic in {
975    let NumOpsValue = "3" in
976      def K : BinaryRIE<mnemonic##"k", opcode2, null_frag, cls, imm>,
977              Requires<[FeatureDistinctOps]>;
978    let NumOpsValue = "2", isConvertibleToThreeAddress = 1 in
979      def "" : BinaryRI<mnemonic, opcode1, operator, cls, imm>;
980  }
981}
982
983class BinaryRIL<string mnemonic, bits<12> opcode, SDPatternOperator operator,
984                RegisterOperand cls, Immediate imm>
985  : InstRIL<opcode, (outs cls:$R1), (ins cls:$R1src, imm:$I2),
986            mnemonic#"\t$R1, $I2",
987            [(set cls:$R1, (operator cls:$R1src, imm:$I2))]> {
988  let Constraints = "$R1 = $R1src";
989  let DisableEncoding = "$R1src";
990}
991
992class BinaryRX<string mnemonic, bits<8> opcode, SDPatternOperator operator,
993               RegisterOperand cls, SDPatternOperator load, bits<5> bytes,
994               AddressingMode mode = bdxaddr12only>
995  : InstRX<opcode, (outs cls:$R1), (ins cls:$R1src, mode:$XBD2),
996           mnemonic#"\t$R1, $XBD2",
997           [(set cls:$R1, (operator cls:$R1src, (load mode:$XBD2)))]> {
998  let OpKey = mnemonic ## cls;
999  let OpType = "mem";
1000  let Constraints = "$R1 = $R1src";
1001  let DisableEncoding = "$R1src";
1002  let mayLoad = 1;
1003  let AccessBytes = bytes;
1004}
1005
1006class BinaryRXE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1007                  RegisterOperand cls, SDPatternOperator load, bits<5> bytes>
1008  : InstRXE<opcode, (outs cls:$R1), (ins cls:$R1src, bdxaddr12only:$XBD2),
1009            mnemonic#"\t$R1, $XBD2",
1010            [(set cls:$R1, (operator cls:$R1src,
1011                                     (load bdxaddr12only:$XBD2)))]> {
1012  let OpKey = mnemonic ## cls;
1013  let OpType = "mem";
1014  let Constraints = "$R1 = $R1src";
1015  let DisableEncoding = "$R1src";
1016  let mayLoad = 1;
1017  let AccessBytes = bytes;
1018}
1019
1020class BinaryRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1021                RegisterOperand cls, SDPatternOperator load, bits<5> bytes,
1022                AddressingMode mode = bdxaddr20only>
1023  : InstRXY<opcode, (outs cls:$R1), (ins cls:$R1src, mode:$XBD2),
1024            mnemonic#"\t$R1, $XBD2",
1025            [(set cls:$R1, (operator cls:$R1src, (load mode:$XBD2)))]> {
1026  let OpKey = mnemonic ## cls;
1027  let OpType = "mem";
1028  let Constraints = "$R1 = $R1src";
1029  let DisableEncoding = "$R1src";
1030  let mayLoad = 1;
1031  let AccessBytes = bytes;
1032}
1033
1034multiclass BinaryRXPair<string mnemonic, bits<8> rxOpcode, bits<16> rxyOpcode,
1035                        SDPatternOperator operator, RegisterOperand cls,
1036                        SDPatternOperator load, bits<5> bytes> {
1037  let DispKey = mnemonic ## #cls in {
1038    let DispSize = "12" in
1039      def "" : BinaryRX<mnemonic, rxOpcode, operator, cls, load, bytes,
1040                        bdxaddr12pair>;
1041    let DispSize = "20" in
1042      def Y  : BinaryRXY<mnemonic#"y", rxyOpcode, operator, cls, load, bytes,
1043                         bdxaddr20pair>;
1044  }
1045}
1046
1047class BinarySI<string mnemonic, bits<8> opcode, SDPatternOperator operator,
1048               Operand imm, AddressingMode mode = bdaddr12only>
1049  : InstSI<opcode, (outs), (ins mode:$BD1, imm:$I2),
1050           mnemonic#"\t$BD1, $I2",
1051           [(store (operator (load mode:$BD1), imm:$I2), mode:$BD1)]> {
1052  let mayLoad = 1;
1053  let mayStore = 1;
1054}
1055
1056class BinarySIY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1057                Operand imm, AddressingMode mode = bdaddr20only>
1058  : InstSIY<opcode, (outs), (ins mode:$BD1, imm:$I2),
1059            mnemonic#"\t$BD1, $I2",
1060            [(store (operator (load mode:$BD1), imm:$I2), mode:$BD1)]> {
1061  let mayLoad = 1;
1062  let mayStore = 1;
1063}
1064
1065multiclass BinarySIPair<string mnemonic, bits<8> siOpcode,
1066                        bits<16> siyOpcode, SDPatternOperator operator,
1067                        Operand imm> {
1068  let DispKey = mnemonic ## #cls in {
1069    let DispSize = "12" in
1070      def "" : BinarySI<mnemonic, siOpcode, operator, imm, bdaddr12pair>;
1071    let DispSize = "20" in
1072      def Y  : BinarySIY<mnemonic#"y", siyOpcode, operator, imm, bdaddr20pair>;
1073  }
1074}
1075
1076class ShiftRS<string mnemonic, bits<8> opcode, SDPatternOperator operator,
1077              RegisterOperand cls>
1078  : InstRS<opcode, (outs cls:$R1), (ins cls:$R1src, shift12only:$BD2),
1079           mnemonic#"\t$R1, $BD2",
1080           [(set cls:$R1, (operator cls:$R1src, shift12only:$BD2))]> {
1081  let R3 = 0;
1082  let Constraints = "$R1 = $R1src";
1083  let DisableEncoding = "$R1src";
1084}
1085
1086class ShiftRSY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1087               RegisterOperand cls>
1088  : InstRSY<opcode, (outs cls:$R1), (ins cls:$R3, shift20only:$BD2),
1089            mnemonic#"\t$R1, $R3, $BD2",
1090            [(set cls:$R1, (operator cls:$R3, shift20only:$BD2))]>;
1091
1092multiclass ShiftRSAndK<string mnemonic, bits<8> opcode1, bits<16> opcode2,
1093                       SDPatternOperator operator, RegisterOperand cls> {
1094  let NumOpsKey = mnemonic in {
1095    let NumOpsValue = "3" in
1096      def K  : ShiftRSY<mnemonic##"k", opcode2, null_frag, cls>,
1097               Requires<[FeatureDistinctOps]>;
1098    let NumOpsValue = "2", isConvertibleToThreeAddress = 1 in
1099      def "" : ShiftRS<mnemonic, opcode1, operator, cls>;
1100  }
1101}
1102
1103class CompareRR<string mnemonic, bits<8> opcode, SDPatternOperator operator,
1104                RegisterOperand cls1, RegisterOperand cls2>
1105  : InstRR<opcode, (outs), (ins cls1:$R1, cls2:$R2),
1106           mnemonic#"r\t$R1, $R2",
1107           [(operator cls1:$R1, cls2:$R2)]> {
1108  let OpKey = mnemonic ## cls1;
1109  let OpType = "reg";
1110  let isCompare = 1;
1111}
1112
1113class CompareRRE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1114                 RegisterOperand cls1, RegisterOperand cls2>
1115  : InstRRE<opcode, (outs), (ins cls1:$R1, cls2:$R2),
1116            mnemonic#"r\t$R1, $R2",
1117            [(operator cls1:$R1, cls2:$R2)]> {
1118  let OpKey = mnemonic ## cls1;
1119  let OpType = "reg";
1120  let isCompare = 1;
1121}
1122
1123class CompareRI<string mnemonic, bits<12> opcode, SDPatternOperator operator,
1124                RegisterOperand cls, Immediate imm>
1125  : InstRI<opcode, (outs), (ins cls:$R1, imm:$I2),
1126           mnemonic#"\t$R1, $I2",
1127           [(operator cls:$R1, imm:$I2)]> {
1128  let isCompare = 1;
1129}
1130
1131class CompareRIL<string mnemonic, bits<12> opcode, SDPatternOperator operator,
1132                 RegisterOperand cls, Immediate imm>
1133  : InstRIL<opcode, (outs), (ins cls:$R1, imm:$I2),
1134            mnemonic#"\t$R1, $I2",
1135            [(operator cls:$R1, imm:$I2)]> {
1136  let isCompare = 1;
1137}
1138
1139class CompareRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator,
1140                   RegisterOperand cls, SDPatternOperator load>
1141  : InstRIL<opcode, (outs), (ins cls:$R1, pcrel32:$I2),
1142            mnemonic#"\t$R1, $I2",
1143            [(operator cls:$R1, (load pcrel32:$I2))]> {
1144  let isCompare = 1;
1145  let mayLoad = 1;
1146  // We want PC-relative addresses to be tried ahead of BD and BDX addresses.
1147  // However, BDXs have two extra operands and are therefore 6 units more
1148  // complex.
1149  let AddedComplexity = 7;
1150}
1151
1152class CompareRX<string mnemonic, bits<8> opcode, SDPatternOperator operator,
1153                RegisterOperand cls, SDPatternOperator load, bits<5> bytes,
1154                AddressingMode mode = bdxaddr12only>
1155  : InstRX<opcode, (outs), (ins cls:$R1, mode:$XBD2),
1156           mnemonic#"\t$R1, $XBD2",
1157           [(operator cls:$R1, (load mode:$XBD2))]> {
1158  let OpKey = mnemonic ## cls;
1159  let OpType = "mem";
1160  let isCompare = 1;
1161  let mayLoad = 1;
1162  let AccessBytes = bytes;
1163}
1164
1165class CompareRXE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1166                 RegisterOperand cls, SDPatternOperator load, bits<5> bytes>
1167  : InstRXE<opcode, (outs), (ins cls:$R1, bdxaddr12only:$XBD2),
1168            mnemonic#"\t$R1, $XBD2",
1169            [(operator cls:$R1, (load bdxaddr12only:$XBD2))]> {
1170  let OpKey = mnemonic ## cls;
1171  let OpType = "mem";
1172  let isCompare = 1;
1173  let mayLoad = 1;
1174  let AccessBytes = bytes;
1175}
1176
1177class CompareRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1178                 RegisterOperand cls, SDPatternOperator load, bits<5> bytes,
1179                 AddressingMode mode = bdxaddr20only>
1180  : InstRXY<opcode, (outs), (ins cls:$R1, mode:$XBD2),
1181            mnemonic#"\t$R1, $XBD2",
1182            [(operator cls:$R1, (load mode:$XBD2))]> {
1183  let OpKey = mnemonic ## cls;
1184  let OpType = "mem";
1185  let isCompare = 1;
1186  let mayLoad = 1;
1187  let AccessBytes = bytes;
1188}
1189
1190multiclass CompareRXPair<string mnemonic, bits<8> rxOpcode, bits<16> rxyOpcode,
1191                         SDPatternOperator operator, RegisterOperand cls,
1192                         SDPatternOperator load, bits<5> bytes> {
1193  let DispKey = mnemonic ## #cls in {
1194    let DispSize = "12" in
1195      def "" : CompareRX<mnemonic, rxOpcode, operator, cls,
1196                         load, bytes, bdxaddr12pair>;
1197    let DispSize = "20" in
1198      def Y  : CompareRXY<mnemonic#"y", rxyOpcode, operator, cls,
1199                          load, bytes, bdxaddr20pair>;
1200  }
1201}
1202
1203class CompareSI<string mnemonic, bits<8> opcode, SDPatternOperator operator,
1204                SDPatternOperator load, Immediate imm,
1205                AddressingMode mode = bdaddr12only>
1206  : InstSI<opcode, (outs), (ins mode:$BD1, imm:$I2),
1207           mnemonic#"\t$BD1, $I2",
1208           [(operator (load mode:$BD1), imm:$I2)]> {
1209  let isCompare = 1;
1210  let mayLoad = 1;
1211}
1212
1213class CompareSIL<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1214                 SDPatternOperator load, Immediate imm>
1215  : InstSIL<opcode, (outs), (ins bdaddr12only:$BD1, imm:$I2),
1216            mnemonic#"\t$BD1, $I2",
1217            [(operator (load bdaddr12only:$BD1), imm:$I2)]> {
1218  let isCompare = 1;
1219  let mayLoad = 1;
1220}
1221
1222class CompareSIY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1223                 SDPatternOperator load, Immediate imm,
1224                 AddressingMode mode = bdaddr20only>
1225  : InstSIY<opcode, (outs), (ins mode:$BD1, imm:$I2),
1226            mnemonic#"\t$BD1, $I2",
1227            [(operator (load mode:$BD1), imm:$I2)]> {
1228  let isCompare = 1;
1229  let mayLoad = 1;
1230}
1231
1232multiclass CompareSIPair<string mnemonic, bits<8> siOpcode, bits<16> siyOpcode,
1233                         SDPatternOperator operator, SDPatternOperator load,
1234                         Immediate imm> {
1235  let DispKey = mnemonic in {
1236    let DispSize = "12" in
1237      def "" : CompareSI<mnemonic, siOpcode, operator, load, imm, bdaddr12pair>;
1238    let DispSize = "20" in
1239      def Y  : CompareSIY<mnemonic#"y", siyOpcode, operator, load, imm,
1240                          bdaddr20pair>;
1241  }
1242}
1243
1244class TernaryRRD<string mnemonic, bits<16> opcode,
1245                 SDPatternOperator operator, RegisterOperand cls>
1246  : InstRRD<opcode, (outs cls:$R1), (ins cls:$R1src, cls:$R3, cls:$R2),
1247            mnemonic#"r\t$R1, $R3, $R2",
1248            [(set cls:$R1, (operator cls:$R1src, cls:$R3, cls:$R2))]> {
1249  let OpKey = mnemonic ## cls;
1250  let OpType = "reg";
1251  let Constraints = "$R1 = $R1src";
1252  let DisableEncoding = "$R1src";
1253}
1254
1255class TernaryRXF<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1256                 RegisterOperand cls, SDPatternOperator load, bits<5> bytes>
1257  : InstRXF<opcode, (outs cls:$R1),
1258            (ins cls:$R1src, cls:$R3, bdxaddr12only:$XBD2),
1259            mnemonic#"\t$R1, $R3, $XBD2",
1260            [(set cls:$R1, (operator cls:$R1src, cls:$R3,
1261                                     (load bdxaddr12only:$XBD2)))]> {
1262  let OpKey = mnemonic ## cls;
1263  let OpType = "mem";
1264  let Constraints = "$R1 = $R1src";
1265  let DisableEncoding = "$R1src";
1266  let mayLoad = 1;
1267  let AccessBytes = bytes;
1268}
1269
1270class CmpSwapRS<string mnemonic, bits<8> opcode, SDPatternOperator operator,
1271                RegisterOperand cls, AddressingMode mode = bdaddr12only>
1272  : InstRS<opcode, (outs cls:$R1), (ins cls:$R1src, cls:$R3, mode:$BD2),
1273           mnemonic#"\t$R1, $R3, $BD2",
1274           [(set cls:$R1, (operator mode:$BD2, cls:$R1src, cls:$R3))]> {
1275  let Constraints = "$R1 = $R1src";
1276  let DisableEncoding = "$R1src";
1277  let mayLoad = 1;
1278  let mayStore = 1;
1279}
1280
1281class CmpSwapRSY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1282                 RegisterOperand cls, AddressingMode mode = bdaddr20only>
1283  : InstRSY<opcode, (outs cls:$R1), (ins cls:$R1src, cls:$R3, mode:$BD2),
1284            mnemonic#"\t$R1, $R3, $BD2",
1285            [(set cls:$R1, (operator mode:$BD2, cls:$R1src, cls:$R3))]> {
1286  let Constraints = "$R1 = $R1src";
1287  let DisableEncoding = "$R1src";
1288  let mayLoad = 1;
1289  let mayStore = 1;
1290}
1291
1292multiclass CmpSwapRSPair<string mnemonic, bits<8> rsOpcode, bits<16> rsyOpcode,
1293                         SDPatternOperator operator, RegisterOperand cls> {
1294  let DispKey = mnemonic ## #cls in {
1295    let DispSize = "12" in
1296      def "" : CmpSwapRS<mnemonic, rsOpcode, operator, cls, bdaddr12pair>;
1297    let DispSize = "20" in
1298      def Y  : CmpSwapRSY<mnemonic#"y", rsyOpcode, operator, cls, bdaddr20pair>;
1299  }
1300}
1301
1302class RotateSelectRIEf<string mnemonic, bits<16> opcode, RegisterOperand cls1,
1303                       RegisterOperand cls2>
1304  : InstRIEf<opcode, (outs cls1:$R1),
1305             (ins cls1:$R1src, cls2:$R2, uimm8:$I3, uimm8:$I4, uimm8zx6:$I5),
1306             mnemonic#"\t$R1, $R2, $I3, $I4, $I5", []> {
1307  let Constraints = "$R1 = $R1src";
1308  let DisableEncoding = "$R1src";
1309}
1310
1311class PrefetchRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator>
1312  : InstRXY<opcode, (outs), (ins uimm8zx4:$R1, bdxaddr20only:$XBD2),
1313            mnemonic##"\t$R1, $XBD2",
1314            [(operator uimm8zx4:$R1, bdxaddr20only:$XBD2)]>;
1315
1316class PrefetchRILPC<string mnemonic, bits<12> opcode,
1317                    SDPatternOperator operator>
1318  : InstRIL<opcode, (outs), (ins uimm8zx4:$R1, pcrel32:$I2),
1319            mnemonic##"\t$R1, $I2",
1320            [(operator uimm8zx4:$R1, pcrel32:$I2)]> {
1321  // We want PC-relative addresses to be tried ahead of BD and BDX addresses.
1322  // However, BDXs have two extra operands and are therefore 6 units more
1323  // complex.
1324  let AddedComplexity = 7;
1325}
1326
1327// A floating-point load-and test operation.  Create both a normal unary
1328// operation and one that acts as a comparison against zero.
1329multiclass LoadAndTestRRE<string mnemonic, bits<16> opcode,
1330                          RegisterOperand cls> {
1331  def "" : UnaryRRE<mnemonic, opcode, null_frag, cls, cls>;
1332  let isCodeGenOnly = 1 in
1333    def Compare : CompareRRE<mnemonic, opcode, null_frag, cls, cls>;
1334}
1335
1336//===----------------------------------------------------------------------===//
1337// Pseudo instructions
1338//===----------------------------------------------------------------------===//
1339//
1340// Convenience instructions that get lowered to real instructions
1341// by either SystemZTargetLowering::EmitInstrWithCustomInserter()
1342// or SystemZInstrInfo::expandPostRAPseudo().
1343//
1344//===----------------------------------------------------------------------===//
1345
1346class Pseudo<dag outs, dag ins, list<dag> pattern>
1347  : InstSystemZ<0, outs, ins, "", pattern> {
1348  let isPseudo = 1;
1349  let isCodeGenOnly = 1;
1350}
1351
1352// Like UnaryRI, but expanded after RA depending on the choice of register.
1353class UnaryRIPseudo<SDPatternOperator operator, RegisterOperand cls,
1354                    Immediate imm>
1355  : Pseudo<(outs cls:$R1), (ins imm:$I2),
1356           [(set cls:$R1, (operator imm:$I2))]>;
1357
1358// Like UnaryRXY, but expanded after RA depending on the choice of register.
1359class UnaryRXYPseudo<string key, SDPatternOperator operator,
1360                     RegisterOperand cls, bits<5> bytes,
1361                     AddressingMode mode = bdxaddr20only>
1362  : Pseudo<(outs cls:$R1), (ins mode:$XBD2),
1363           [(set cls:$R1, (operator mode:$XBD2))]> {
1364  let OpKey = key ## cls;
1365  let OpType = "mem";
1366  let mayLoad = 1;
1367  let Has20BitOffset = 1;
1368  let HasIndex = 1;
1369  let AccessBytes = bytes;
1370}
1371
1372// Like UnaryRR, but expanded after RA depending on the choice of registers.
1373class UnaryRRPseudo<string key, SDPatternOperator operator,
1374                    RegisterOperand cls1, RegisterOperand cls2>
1375  : Pseudo<(outs cls1:$R1), (ins cls2:$R2),
1376           [(set cls1:$R1, (operator cls2:$R2))]> {
1377  let OpKey = key ## cls1;
1378  let OpType = "reg";
1379}
1380
1381// Like BinaryRI, but expanded after RA depending on the choice of register.
1382class BinaryRIPseudo<SDPatternOperator operator, RegisterOperand cls,
1383                     Immediate imm>
1384  : Pseudo<(outs cls:$R1), (ins cls:$R1src, imm:$I2),
1385           [(set cls:$R1, (operator cls:$R1src, imm:$I2))]> {
1386  let Constraints = "$R1 = $R1src";
1387}
1388
1389// Like BinaryRIE, but expanded after RA depending on the choice of register.
1390class BinaryRIEPseudo<SDPatternOperator operator, RegisterOperand cls,
1391                      Immediate imm>
1392  : Pseudo<(outs cls:$R1), (ins cls:$R3, imm:$I2),
1393           [(set cls:$R1, (operator cls:$R3, imm:$I2))]>;
1394
1395// Like BinaryRIAndK, but expanded after RA depending on the choice of register.
1396multiclass BinaryRIAndKPseudo<string key, SDPatternOperator operator,
1397                              RegisterOperand cls, Immediate imm> {
1398  let NumOpsKey = key in {
1399    let NumOpsValue = "3" in
1400      def K : BinaryRIEPseudo<null_frag, cls, imm>,
1401              Requires<[FeatureHighWord, FeatureDistinctOps]>;
1402    let NumOpsValue = "2", isConvertibleToThreeAddress = 1 in
1403      def "" : BinaryRIPseudo<operator, cls, imm>,
1404               Requires<[FeatureHighWord]>;
1405  }
1406}
1407
1408// Like CompareRI, but expanded after RA depending on the choice of register.
1409class CompareRIPseudo<SDPatternOperator operator, RegisterOperand cls,
1410                      Immediate imm>
1411  : Pseudo<(outs), (ins cls:$R1, imm:$I2), [(operator cls:$R1, imm:$I2)]>;
1412
1413// Like CompareRXY, but expanded after RA depending on the choice of register.
1414class CompareRXYPseudo<SDPatternOperator operator, RegisterOperand cls,
1415                       SDPatternOperator load, bits<5> bytes,
1416                       AddressingMode mode = bdxaddr20only>
1417  : Pseudo<(outs), (ins cls:$R1, mode:$XBD2),
1418           [(operator cls:$R1, (load mode:$XBD2))]> {
1419  let mayLoad = 1;
1420  let Has20BitOffset = 1;
1421  let HasIndex = 1;
1422  let AccessBytes = bytes;
1423}
1424
1425// Like StoreRXY, but expanded after RA depending on the choice of register.
1426class StoreRXYPseudo<SDPatternOperator operator, RegisterOperand cls,
1427                     bits<5> bytes, AddressingMode mode = bdxaddr20only>
1428  : Pseudo<(outs), (ins cls:$R1, mode:$XBD2),
1429           [(operator cls:$R1, mode:$XBD2)]> {
1430  let mayStore = 1;
1431  let Has20BitOffset = 1;
1432  let HasIndex = 1;
1433  let AccessBytes = bytes;
1434}
1435
1436// Like RotateSelectRIEf, but expanded after RA depending on the choice
1437// of registers.
1438class RotateSelectRIEfPseudo<RegisterOperand cls1, RegisterOperand cls2>
1439  : Pseudo<(outs cls1:$R1),
1440           (ins cls1:$R1src, cls2:$R2, uimm8:$I3, uimm8:$I4, uimm8zx6:$I5),
1441           []> {
1442  let Constraints = "$R1 = $R1src";
1443  let DisableEncoding = "$R1src";
1444}
1445
1446// Implements "$dst = $cc & (8 >> CC) ? $src1 : $src2", where CC is
1447// the value of the PSW's 2-bit condition code field.
1448class SelectWrapper<RegisterOperand cls>
1449  : Pseudo<(outs cls:$dst),
1450           (ins cls:$src1, cls:$src2, uimm8zx4:$valid, uimm8zx4:$cc),
1451           [(set cls:$dst, (z_select_ccmask cls:$src1, cls:$src2,
1452                                            uimm8zx4:$valid, uimm8zx4:$cc))]> {
1453  let usesCustomInserter = 1;
1454  // Although the instructions used by these nodes do not in themselves
1455  // change CC, the insertion requires new blocks, and CC cannot be live
1456  // across them.
1457  let Defs = [CC];
1458  let Uses = [CC];
1459}
1460
1461// Stores $new to $addr if $cc is true ("" case) or false (Inv case).
1462multiclass CondStores<RegisterOperand cls, SDPatternOperator store,
1463                      SDPatternOperator load, AddressingMode mode> {
1464  let Defs = [CC], Uses = [CC], usesCustomInserter = 1 in {
1465    def "" : Pseudo<(outs),
1466                    (ins cls:$new, mode:$addr, uimm8zx4:$valid, uimm8zx4:$cc),
1467                    [(store (z_select_ccmask cls:$new, (load mode:$addr),
1468                                             uimm8zx4:$valid, uimm8zx4:$cc),
1469                            mode:$addr)]>;
1470    def Inv : Pseudo<(outs),
1471                     (ins cls:$new, mode:$addr, uimm8zx4:$valid, uimm8zx4:$cc),
1472                     [(store (z_select_ccmask (load mode:$addr), cls:$new,
1473                                              uimm8zx4:$valid, uimm8zx4:$cc),
1474                              mode:$addr)]>;
1475  }
1476}
1477
1478// OPERATOR is ATOMIC_SWAP or an ATOMIC_LOAD_* operation.  PAT and OPERAND
1479// describe the second (non-memory) operand.
1480class AtomicLoadBinary<SDPatternOperator operator, RegisterOperand cls,
1481                       dag pat, DAGOperand operand>
1482  : Pseudo<(outs cls:$dst), (ins bdaddr20only:$ptr, operand:$src2),
1483           [(set cls:$dst, (operator bdaddr20only:$ptr, pat))]> {
1484  let Defs = [CC];
1485  let Has20BitOffset = 1;
1486  let mayLoad = 1;
1487  let mayStore = 1;
1488  let usesCustomInserter = 1;
1489}
1490
1491// Specializations of AtomicLoadWBinary.
1492class AtomicLoadBinaryReg32<SDPatternOperator operator>
1493  : AtomicLoadBinary<operator, GR32, (i32 GR32:$src2), GR32>;
1494class AtomicLoadBinaryImm32<SDPatternOperator operator, Immediate imm>
1495  : AtomicLoadBinary<operator, GR32, (i32 imm:$src2), imm>;
1496class AtomicLoadBinaryReg64<SDPatternOperator operator>
1497  : AtomicLoadBinary<operator, GR64, (i64 GR64:$src2), GR64>;
1498class AtomicLoadBinaryImm64<SDPatternOperator operator, Immediate imm>
1499  : AtomicLoadBinary<operator, GR64, (i64 imm:$src2), imm>;
1500
1501// OPERATOR is ATOMIC_SWAPW or an ATOMIC_LOADW_* operation.  PAT and OPERAND
1502// describe the second (non-memory) operand.
1503class AtomicLoadWBinary<SDPatternOperator operator, dag pat,
1504                        DAGOperand operand>
1505  : Pseudo<(outs GR32:$dst),
1506           (ins bdaddr20only:$ptr, operand:$src2, ADDR32:$bitshift,
1507                ADDR32:$negbitshift, uimm32:$bitsize),
1508           [(set GR32:$dst, (operator bdaddr20only:$ptr, pat, ADDR32:$bitshift,
1509                                      ADDR32:$negbitshift, uimm32:$bitsize))]> {
1510  let Defs = [CC];
1511  let Has20BitOffset = 1;
1512  let mayLoad = 1;
1513  let mayStore = 1;
1514  let usesCustomInserter = 1;
1515}
1516
1517// Specializations of AtomicLoadWBinary.
1518class AtomicLoadWBinaryReg<SDPatternOperator operator>
1519  : AtomicLoadWBinary<operator, (i32 GR32:$src2), GR32>;
1520class AtomicLoadWBinaryImm<SDPatternOperator operator, Immediate imm>
1521  : AtomicLoadWBinary<operator, (i32 imm:$src2), imm>;
1522
1523// Define an instruction that operates on two fixed-length blocks of memory,
1524// and associated pseudo instructions for operating on blocks of any size.
1525// The Sequence form uses a straight-line sequence of instructions and
1526// the Loop form uses a loop of length-256 instructions followed by
1527// another instruction to handle the excess.
1528multiclass MemorySS<string mnemonic, bits<8> opcode,
1529                    SDPatternOperator sequence, SDPatternOperator loop> {
1530  def "" : InstSS<opcode, (outs), (ins bdladdr12onlylen8:$BDL1,
1531                                       bdaddr12only:$BD2),
1532                  mnemonic##"\t$BDL1, $BD2", []>;
1533  let usesCustomInserter = 1 in {
1534    def Sequence : Pseudo<(outs), (ins bdaddr12only:$dest, bdaddr12only:$src,
1535                                       imm64:$length),
1536                           [(sequence bdaddr12only:$dest, bdaddr12only:$src,
1537                                      imm64:$length)]>;
1538    def Loop : Pseudo<(outs), (ins bdaddr12only:$dest, bdaddr12only:$src,
1539                                   imm64:$length, GR64:$count256),
1540                      [(loop bdaddr12only:$dest, bdaddr12only:$src,
1541                             imm64:$length, GR64:$count256)]>;
1542  }
1543}
1544
1545// Define an instruction that operates on two strings, both terminated
1546// by the character in R0.  The instruction processes a CPU-determinated
1547// number of bytes at a time and sets CC to 3 if the instruction needs
1548// to be repeated.  Also define a pseudo instruction that represents
1549// the full loop (the main instruction plus the branch on CC==3).
1550multiclass StringRRE<string mnemonic, bits<16> opcode,
1551                     SDPatternOperator operator> {
1552  def "" : InstRRE<opcode, (outs GR64:$R1, GR64:$R2),
1553                   (ins GR64:$R1src, GR64:$R2src),
1554                   mnemonic#"\t$R1, $R2", []> {
1555    let Constraints = "$R1 = $R1src, $R2 = $R2src";
1556    let DisableEncoding = "$R1src, $R2src";
1557  }
1558  let usesCustomInserter = 1 in
1559    def Loop : Pseudo<(outs GR64:$end),
1560                      (ins GR64:$start1, GR64:$start2, GR32:$char),
1561                      [(set GR64:$end, (operator GR64:$start1, GR64:$start2,
1562                                                 GR32:$char))]>;
1563}
1564
1565// A pseudo instruction that is a direct alias of a real instruction.
1566// These aliases are used in cases where a particular register operand is
1567// fixed or where the same instruction is used with different register sizes.
1568// The size parameter is the size in bytes of the associated real instruction.
1569class Alias<int size, dag outs, dag ins, list<dag> pattern>
1570  : InstSystemZ<size, outs, ins, "", pattern> {
1571  let isPseudo = 1;
1572  let isCodeGenOnly = 1;
1573}
1574
1575// An alias of a BinaryRI, but with different register sizes.
1576class BinaryAliasRI<SDPatternOperator operator, RegisterOperand cls,
1577                    Immediate imm>
1578  : Alias<4, (outs cls:$R1), (ins cls:$R1src, imm:$I2),
1579          [(set cls:$R1, (operator cls:$R1src, imm:$I2))]> {
1580  let Constraints = "$R1 = $R1src";
1581}
1582
1583// An alias of a BinaryRIL, but with different register sizes.
1584class BinaryAliasRIL<SDPatternOperator operator, RegisterOperand cls,
1585                     Immediate imm>
1586  : Alias<6, (outs cls:$R1), (ins cls:$R1src, imm:$I2),
1587          [(set cls:$R1, (operator cls:$R1src, imm:$I2))]> {
1588  let Constraints = "$R1 = $R1src";
1589}
1590
1591// An alias of a CompareRI, but with different register sizes.
1592class CompareAliasRI<SDPatternOperator operator, RegisterOperand cls,
1593                     Immediate imm>
1594  : Alias<4, (outs), (ins cls:$R1, imm:$I2), [(operator cls:$R1, imm:$I2)]> {
1595  let isCompare = 1;
1596}
1597
1598// An alias of a RotateSelectRIEf, but with different register sizes.
1599class RotateSelectAliasRIEf<RegisterOperand cls1, RegisterOperand cls2>
1600  : Alias<6, (outs cls1:$R1),
1601          (ins cls1:$R1src, cls2:$R2, uimm8:$I3, uimm8:$I4, uimm8zx6:$I5), []> {
1602  let Constraints = "$R1 = $R1src";
1603}
1604