1251607Sdim//==- SystemZInstrFormats.td - SystemZ Instruction Formats --*- tablegen -*-==//
2251607Sdim//
3251607Sdim//                     The LLVM Compiler Infrastructure
4251607Sdim//
5251607Sdim// This file is distributed under the University of Illinois Open Source
6251607Sdim// License. See LICENSE.TXT for details.
7251607Sdim//
8251607Sdim//===----------------------------------------------------------------------===//
9251607Sdim
10251607Sdim//===----------------------------------------------------------------------===//
11251607Sdim// Basic SystemZ instruction definition
12251607Sdim//===----------------------------------------------------------------------===//
13251607Sdim
14251607Sdimclass InstSystemZ<int size, dag outs, dag ins, string asmstr,
15251607Sdim                  list<dag> pattern> : Instruction {
16251607Sdim  let Namespace = "SystemZ";
17251607Sdim
18251607Sdim  dag OutOperandList = outs;
19251607Sdim  dag InOperandList = ins;
20251607Sdim  let Size = size;
21251607Sdim  let Pattern = pattern;
22251607Sdim  let AsmString = asmstr;
23251607Sdim
24263509Sdim  // Some instructions come in pairs, one having a 12-bit displacement
25263509Sdim  // and the other having a 20-bit displacement.  Both instructions in
26263509Sdim  // the pair have the same DispKey and their DispSizes are "12" and "20"
27263509Sdim  // respectively.
28263509Sdim  string DispKey = "";
29263509Sdim  string DispSize = "none";
30251607Sdim
31263509Sdim  // Many register-based <INSN>R instructions have a memory-based <INSN>
32263509Sdim  // counterpart.  OpKey uniquely identifies <INSN>, while OpType is
33263509Sdim  // "reg" for <INSN>R and "mem" for <INSN>.
34263509Sdim  string OpKey = "";
35263509Sdim  string OpType = "none";
36251607Sdim
37263509Sdim  // Many distinct-operands instructions have older 2-operand equivalents.
38263509Sdim  // NumOpsKey uniquely identifies one of these 2-operand and 3-operand pairs,
39263509Sdim  // with NumOpsValue being "2" or "3" as appropriate.
40263509Sdim  string NumOpsKey = "";
41263509Sdim  string NumOpsValue = "none";
42263509Sdim
43251607Sdim  // True if this instruction is a simple D(X,B) load of a register
44251607Sdim  // (with no sign or zero extension).
45251607Sdim  bit SimpleBDXLoad = 0;
46251607Sdim
47251607Sdim  // True if this instruction is a simple D(X,B) store of a register
48251607Sdim  // (with no truncation).
49251607Sdim  bit SimpleBDXStore = 0;
50251607Sdim
51251607Sdim  // True if this instruction has a 20-bit displacement field.
52251607Sdim  bit Has20BitOffset = 0;
53251607Sdim
54251607Sdim  // True if addresses in this instruction have an index register.
55251607Sdim  bit HasIndex = 0;
56251607Sdim
57251607Sdim  // True if this is a 128-bit pseudo instruction that combines two 64-bit
58251607Sdim  // operations.
59251607Sdim  bit Is128Bit = 0;
60251607Sdim
61263509Sdim  // The access size of all memory operands in bytes, or 0 if not known.
62263509Sdim  bits<5> AccessBytes = 0;
63263509Sdim
64263509Sdim  // If the instruction sets CC to a useful value, this gives the mask
65263509Sdim  // of all possible CC results.  The mask has the same form as
66263509Sdim  // SystemZ::CCMASK_*.
67263509Sdim  bits<4> CCValues = 0;
68263509Sdim
69263509Sdim  // The subset of CCValues that have the same meaning as they would after
70263509Sdim  // a comparison of the first operand against zero.
71263509Sdim  bits<4> CompareZeroCCMask = 0;
72263509Sdim
73263509Sdim  // True if the instruction is conditional and if the CC mask operand
74263509Sdim  // comes first (as for BRC, etc.).
75263509Sdim  bit CCMaskFirst = 0;
76263509Sdim
77263509Sdim  // Similar, but true if the CC mask operand comes last (as for LOC, etc.).
78263509Sdim  bit CCMaskLast = 0;
79263509Sdim
80263509Sdim  // True if the instruction is the "logical" rather than "arithmetic" form,
81263509Sdim  // in cases where a distinction exists.
82263509Sdim  bit IsLogical = 0;
83263509Sdim
84263509Sdim  let TSFlags{0}     = SimpleBDXLoad;
85263509Sdim  let TSFlags{1}     = SimpleBDXStore;
86263509Sdim  let TSFlags{2}     = Has20BitOffset;
87263509Sdim  let TSFlags{3}     = HasIndex;
88263509Sdim  let TSFlags{4}     = Is128Bit;
89263509Sdim  let TSFlags{9-5}   = AccessBytes;
90263509Sdim  let TSFlags{13-10} = CCValues;
91263509Sdim  let TSFlags{17-14} = CompareZeroCCMask;
92263509Sdim  let TSFlags{18}    = CCMaskFirst;
93263509Sdim  let TSFlags{19}    = CCMaskLast;
94263509Sdim  let TSFlags{20}    = IsLogical;
95251607Sdim}
96251607Sdim
97251607Sdim//===----------------------------------------------------------------------===//
98251607Sdim// Mappings between instructions
99251607Sdim//===----------------------------------------------------------------------===//
100251607Sdim
101251607Sdim// Return the version of an instruction that has an unsigned 12-bit
102251607Sdim// displacement.
103251607Sdimdef getDisp12Opcode : InstrMapping {
104251607Sdim  let FilterClass = "InstSystemZ";
105263509Sdim  let RowFields = ["DispKey"];
106263509Sdim  let ColFields = ["DispSize"];
107251607Sdim  let KeyCol = ["20"];
108251607Sdim  let ValueCols = [["12"]];
109251607Sdim}
110251607Sdim
111251607Sdim// Return the version of an instruction that has a signed 20-bit displacement.
112251607Sdimdef getDisp20Opcode : InstrMapping {
113251607Sdim  let FilterClass = "InstSystemZ";
114263509Sdim  let RowFields = ["DispKey"];
115263509Sdim  let ColFields = ["DispSize"];
116251607Sdim  let KeyCol = ["12"];
117251607Sdim  let ValueCols = [["20"]];
118251607Sdim}
119251607Sdim
120263509Sdim// Return the memory form of a register instruction.
121263509Sdimdef getMemOpcode : InstrMapping {
122263509Sdim  let FilterClass = "InstSystemZ";
123263509Sdim  let RowFields = ["OpKey"];
124263509Sdim  let ColFields = ["OpType"];
125263509Sdim  let KeyCol = ["reg"];
126263509Sdim  let ValueCols = [["mem"]];
127263509Sdim}
128263509Sdim
129263509Sdim// Return the 3-operand form of a 2-operand instruction.
130263509Sdimdef getThreeOperandOpcode : InstrMapping {
131263509Sdim  let FilterClass = "InstSystemZ";
132263509Sdim  let RowFields = ["NumOpsKey"];
133263509Sdim  let ColFields = ["NumOpsValue"];
134263509Sdim  let KeyCol = ["2"];
135263509Sdim  let ValueCols = [["3"]];
136263509Sdim}
137263509Sdim
138251607Sdim//===----------------------------------------------------------------------===//
139251607Sdim// Instruction formats
140251607Sdim//===----------------------------------------------------------------------===//
141251607Sdim//
142251607Sdim// Formats are specified using operand field declarations of the form:
143251607Sdim//
144263509Sdim//   bits<4> Rn   : register input or output for operand n
145263509Sdim//   bits<m> In   : immediate value of width m for operand n
146263509Sdim//   bits<4> BDn  : address operand n, which has a base and a displacement
147263509Sdim//   bits<m> XBDn : address operand n, which has an index, a base and a
148263509Sdim//                  displacement
149263509Sdim//   bits<4> Xn   : index register for address operand n
150263509Sdim//   bits<4> Mn   : mode value for operand n
151251607Sdim//
152263509Sdim// The operand numbers ("n" in the list above) follow the architecture manual.
153263509Sdim// Assembly operands sometimes have a different order; in particular, R3 often
154263509Sdim// is often written between operands 1 and 2.
155251607Sdim//
156251607Sdim//===----------------------------------------------------------------------===//
157251607Sdim
158251607Sdimclass InstRI<bits<12> op, dag outs, dag ins, string asmstr, list<dag> pattern>
159251607Sdim  : InstSystemZ<4, outs, ins, asmstr, pattern> {
160251607Sdim  field bits<32> Inst;
161263509Sdim  field bits<32> SoftFail = 0;
162251607Sdim
163251607Sdim  bits<4> R1;
164251607Sdim  bits<16> I2;
165251607Sdim
166251607Sdim  let Inst{31-24} = op{11-4};
167251607Sdim  let Inst{23-20} = R1;
168251607Sdim  let Inst{19-16} = op{3-0};
169251607Sdim  let Inst{15-0}  = I2;
170251607Sdim}
171251607Sdim
172263509Sdimclass InstRIEb<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
173263509Sdim  : InstSystemZ<6, outs, ins, asmstr, pattern> {
174263509Sdim  field bits<48> Inst;
175263509Sdim  field bits<48> SoftFail = 0;
176263509Sdim
177263509Sdim  bits<4> R1;
178263509Sdim  bits<4> R2;
179263509Sdim  bits<4> M3;
180263509Sdim  bits<16> RI4;
181263509Sdim
182263509Sdim  let Inst{47-40} = op{15-8};
183263509Sdim  let Inst{39-36} = R1;
184263509Sdim  let Inst{35-32} = R2;
185263509Sdim  let Inst{31-16} = RI4;
186263509Sdim  let Inst{15-12} = M3;
187263509Sdim  let Inst{11-8}  = 0;
188263509Sdim  let Inst{7-0}   = op{7-0};
189263509Sdim}
190263509Sdim
191263509Sdimclass InstRIEc<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
192263509Sdim  : InstSystemZ<6, outs, ins, asmstr, pattern> {
193263509Sdim  field bits<48> Inst;
194263509Sdim  field bits<48> SoftFail = 0;
195263509Sdim
196263509Sdim  bits<4> R1;
197263509Sdim  bits<8> I2;
198263509Sdim  bits<4> M3;
199263509Sdim  bits<16> RI4;
200263509Sdim
201263509Sdim  let Inst{47-40} = op{15-8};
202263509Sdim  let Inst{39-36} = R1;
203263509Sdim  let Inst{35-32} = M3;
204263509Sdim  let Inst{31-16} = RI4;
205263509Sdim  let Inst{15-8}  = I2;
206263509Sdim  let Inst{7-0}   = op{7-0};
207263509Sdim}
208263509Sdim
209263509Sdimclass InstRIEd<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
210263509Sdim  : InstSystemZ<6, outs, ins, asmstr, pattern> {
211263509Sdim  field bits<48> Inst;
212263509Sdim  field bits<48> SoftFail = 0;
213263509Sdim
214263509Sdim  bits<4> R1;
215263509Sdim  bits<4> R3;
216263509Sdim  bits<16> I2;
217263509Sdim
218263509Sdim  let Inst{47-40} = op{15-8};
219263509Sdim  let Inst{39-36} = R1;
220263509Sdim  let Inst{35-32} = R3;
221263509Sdim  let Inst{31-16} = I2;
222263509Sdim  let Inst{15-8}  = 0;
223263509Sdim  let Inst{7-0}   = op{7-0};
224263509Sdim}
225263509Sdim
226251607Sdimclass InstRIEf<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
227251607Sdim  : InstSystemZ<6, outs, ins, asmstr, pattern> {
228251607Sdim  field bits<48> Inst;
229263509Sdim  field bits<48> SoftFail = 0;
230251607Sdim
231251607Sdim  bits<4> R1;
232251607Sdim  bits<4> R2;
233251607Sdim  bits<8> I3;
234251607Sdim  bits<8> I4;
235251607Sdim  bits<8> I5;
236251607Sdim
237251607Sdim  let Inst{47-40} = op{15-8};
238251607Sdim  let Inst{39-36} = R1;
239251607Sdim  let Inst{35-32} = R2;
240251607Sdim  let Inst{31-24} = I3;
241251607Sdim  let Inst{23-16} = I4;
242251607Sdim  let Inst{15-8}  = I5;
243251607Sdim  let Inst{7-0}   = op{7-0};
244251607Sdim}
245251607Sdim
246251607Sdimclass InstRIL<bits<12> op, dag outs, dag ins, string asmstr, list<dag> pattern>
247251607Sdim  : InstSystemZ<6, outs, ins, asmstr, pattern> {
248251607Sdim  field bits<48> Inst;
249263509Sdim  field bits<48> SoftFail = 0;
250251607Sdim
251251607Sdim  bits<4> R1;
252251607Sdim  bits<32> I2;
253251607Sdim
254251607Sdim  let Inst{47-40} = op{11-4};
255251607Sdim  let Inst{39-36} = R1;
256251607Sdim  let Inst{35-32} = op{3-0};
257251607Sdim  let Inst{31-0}  = I2;
258251607Sdim}
259251607Sdim
260251607Sdimclass InstRR<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
261251607Sdim  : InstSystemZ<2, outs, ins, asmstr, pattern> {
262251607Sdim  field bits<16> Inst;
263263509Sdim  field bits<16> SoftFail = 0;
264251607Sdim
265251607Sdim  bits<4> R1;
266251607Sdim  bits<4> R2;
267251607Sdim
268251607Sdim  let Inst{15-8} = op;
269251607Sdim  let Inst{7-4}  = R1;
270251607Sdim  let Inst{3-0}  = R2;
271251607Sdim}
272251607Sdim
273251607Sdimclass InstRRD<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
274251607Sdim  : InstSystemZ<4, outs, ins, asmstr, pattern> {
275251607Sdim  field bits<32> Inst;
276263509Sdim  field bits<32> SoftFail = 0;
277251607Sdim
278251607Sdim  bits<4> R1;
279251607Sdim  bits<4> R3;
280251607Sdim  bits<4> R2;
281251607Sdim
282251607Sdim  let Inst{31-16} = op;
283251607Sdim  let Inst{15-12} = R1;
284251607Sdim  let Inst{11-8}  = 0;
285251607Sdim  let Inst{7-4}   = R3;
286251607Sdim  let Inst{3-0}   = R2;
287251607Sdim}
288251607Sdim
289251607Sdimclass InstRRE<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
290251607Sdim  : InstSystemZ<4, outs, ins, asmstr, pattern> {
291251607Sdim  field bits<32> Inst;
292263509Sdim  field bits<32> SoftFail = 0;
293251607Sdim
294251607Sdim  bits<4> R1;
295251607Sdim  bits<4> R2;
296251607Sdim
297251607Sdim  let Inst{31-16} = op;
298251607Sdim  let Inst{15-8}  = 0;
299251607Sdim  let Inst{7-4}   = R1;
300251607Sdim  let Inst{3-0}   = R2;
301251607Sdim}
302251607Sdim
303251607Sdimclass InstRRF<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
304251607Sdim  : InstSystemZ<4, outs, ins, asmstr, pattern> {
305251607Sdim  field bits<32> Inst;
306263509Sdim  field bits<32> SoftFail = 0;
307251607Sdim
308251607Sdim  bits<4> R1;
309251607Sdim  bits<4> R2;
310251607Sdim  bits<4> R3;
311263509Sdim  bits<4> R4;
312251607Sdim
313251607Sdim  let Inst{31-16} = op;
314251607Sdim  let Inst{15-12} = R3;
315263509Sdim  let Inst{11-8}  = R4;
316251607Sdim  let Inst{7-4}   = R1;
317251607Sdim  let Inst{3-0}   = R2;
318251607Sdim}
319251607Sdim
320251607Sdimclass InstRX<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
321251607Sdim  : InstSystemZ<4, outs, ins, asmstr, pattern> {
322251607Sdim  field bits<32> Inst;
323263509Sdim  field bits<32> SoftFail = 0;
324251607Sdim
325251607Sdim  bits<4> R1;
326263509Sdim  bits<20> XBD2;
327251607Sdim
328251607Sdim  let Inst{31-24} = op;
329251607Sdim  let Inst{23-20} = R1;
330263509Sdim  let Inst{19-0}  = XBD2;
331251607Sdim
332251607Sdim  let HasIndex = 1;
333251607Sdim}
334251607Sdim
335251607Sdimclass InstRXE<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
336251607Sdim  : InstSystemZ<6, outs, ins, asmstr, pattern> {
337251607Sdim  field bits<48> Inst;
338263509Sdim  field bits<48> SoftFail = 0;
339251607Sdim
340251607Sdim  bits<4> R1;
341263509Sdim  bits<20> XBD2;
342251607Sdim
343251607Sdim  let Inst{47-40} = op{15-8};
344251607Sdim  let Inst{39-36} = R1;
345263509Sdim  let Inst{35-16} = XBD2;
346251607Sdim  let Inst{15-8}  = 0;
347251607Sdim  let Inst{7-0}   = op{7-0};
348251607Sdim
349251607Sdim  let HasIndex = 1;
350251607Sdim}
351251607Sdim
352251607Sdimclass InstRXF<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
353251607Sdim  : InstSystemZ<6, outs, ins, asmstr, pattern> {
354251607Sdim  field bits<48> Inst;
355263509Sdim  field bits<48> SoftFail = 0;
356251607Sdim
357251607Sdim  bits<4> R1;
358251607Sdim  bits<4> R3;
359263509Sdim  bits<20> XBD2;
360251607Sdim
361251607Sdim  let Inst{47-40} = op{15-8};
362251607Sdim  let Inst{39-36} = R3;
363263509Sdim  let Inst{35-16} = XBD2;
364251607Sdim  let Inst{15-12} = R1;
365251607Sdim  let Inst{11-8}  = 0;
366251607Sdim  let Inst{7-0}   = op{7-0};
367251607Sdim
368251607Sdim  let HasIndex = 1;
369251607Sdim}
370251607Sdim
371251607Sdimclass InstRXY<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
372251607Sdim  : InstSystemZ<6, outs, ins, asmstr, pattern> {
373251607Sdim  field bits<48> Inst;
374263509Sdim  field bits<48> SoftFail = 0;
375251607Sdim
376251607Sdim  bits<4> R1;
377263509Sdim  bits<28> XBD2;
378251607Sdim
379251607Sdim  let Inst{47-40} = op{15-8};
380251607Sdim  let Inst{39-36} = R1;
381263509Sdim  let Inst{35-8}  = XBD2;
382251607Sdim  let Inst{7-0}   = op{7-0};
383251607Sdim
384251607Sdim  let Has20BitOffset = 1;
385251607Sdim  let HasIndex = 1;
386251607Sdim}
387251607Sdim
388251607Sdimclass InstRS<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
389251607Sdim  : InstSystemZ<4, outs, ins, asmstr, pattern> {
390251607Sdim  field bits<32> Inst;
391263509Sdim  field bits<32> SoftFail = 0;
392251607Sdim
393251607Sdim  bits<4> R1;
394251607Sdim  bits<4> R3;
395263509Sdim  bits<16> BD2;
396251607Sdim
397251607Sdim  let Inst{31-24} = op;
398251607Sdim  let Inst{23-20} = R1;
399251607Sdim  let Inst{19-16} = R3;
400263509Sdim  let Inst{15-0}  = BD2;
401251607Sdim}
402251607Sdim
403251607Sdimclass InstRSY<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
404251607Sdim  : InstSystemZ<6, outs, ins, asmstr, pattern> {
405251607Sdim  field bits<48> Inst;
406263509Sdim  field bits<48> SoftFail = 0;
407251607Sdim
408251607Sdim  bits<4> R1;
409251607Sdim  bits<4> R3;
410263509Sdim  bits<24> BD2;
411251607Sdim
412251607Sdim  let Inst{47-40} = op{15-8};
413251607Sdim  let Inst{39-36} = R1;
414251607Sdim  let Inst{35-32} = R3;
415263509Sdim  let Inst{31-8}  = BD2;
416251607Sdim  let Inst{7-0}   = op{7-0};
417251607Sdim
418251607Sdim  let Has20BitOffset = 1;
419251607Sdim}
420251607Sdim
421251607Sdimclass InstSI<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
422251607Sdim  : InstSystemZ<4, outs, ins, asmstr, pattern> {
423251607Sdim  field bits<32> Inst;
424263509Sdim  field bits<32> SoftFail = 0;
425251607Sdim
426263509Sdim  bits<16> BD1;
427251607Sdim  bits<8> I2;
428251607Sdim
429251607Sdim  let Inst{31-24} = op;
430251607Sdim  let Inst{23-16} = I2;
431263509Sdim  let Inst{15-0}  = BD1;
432251607Sdim}
433251607Sdim
434251607Sdimclass InstSIL<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
435251607Sdim  : InstSystemZ<6, outs, ins, asmstr, pattern> {
436251607Sdim  field bits<48> Inst;
437263509Sdim  field bits<48> SoftFail = 0;
438251607Sdim
439263509Sdim  bits<16> BD1;
440251607Sdim  bits<16> I2;
441251607Sdim
442251607Sdim  let Inst{47-32} = op;
443263509Sdim  let Inst{31-16} = BD1;
444251607Sdim  let Inst{15-0}  = I2;
445251607Sdim}
446251607Sdim
447251607Sdimclass InstSIY<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
448251607Sdim  : InstSystemZ<6, outs, ins, asmstr, pattern> {
449251607Sdim  field bits<48> Inst;
450263509Sdim  field bits<48> SoftFail = 0;
451251607Sdim
452263509Sdim  bits<24> BD1;
453251607Sdim  bits<8> I2;
454251607Sdim
455251607Sdim  let Inst{47-40} = op{15-8};
456251607Sdim  let Inst{39-32} = I2;
457263509Sdim  let Inst{31-8}  = BD1;
458251607Sdim  let Inst{7-0}   = op{7-0};
459251607Sdim
460251607Sdim  let Has20BitOffset = 1;
461251607Sdim}
462251607Sdim
463263509Sdimclass InstSS<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
464263509Sdim  : InstSystemZ<6, outs, ins, asmstr, pattern> {
465263509Sdim  field bits<48> Inst;
466263509Sdim  field bits<48> SoftFail = 0;
467263509Sdim
468263509Sdim  bits<24> BDL1;
469263509Sdim  bits<16> BD2;
470263509Sdim
471263509Sdim  let Inst{47-40} = op;
472263509Sdim  let Inst{39-16} = BDL1;
473263509Sdim  let Inst{15-0}  = BD2;
474263509Sdim}
475263509Sdim
476251607Sdim//===----------------------------------------------------------------------===//
477251607Sdim// Instruction definitions with semantics
478251607Sdim//===----------------------------------------------------------------------===//
479251607Sdim//
480263509Sdim// These classes have the form [Cond]<Category><Format>, where <Format> is one
481251607Sdim// of the formats defined above and where <Category> describes the inputs
482263509Sdim// and outputs.  "Cond" is used if the instruction is conditional,
483263509Sdim// in which case the 4-bit condition-code mask is added as a final operand.
484263509Sdim// <Category> can be one of:
485251607Sdim//
486251607Sdim//   Inherent:
487251607Sdim//     One register output operand and no input operands.
488251607Sdim//
489263509Sdim//   BranchUnary:
490263509Sdim//     One register output operand, one register input operand and
491263509Sdim//     one branch displacement.  The instructions stores a modified
492263509Sdim//     form of the source register in the destination register and
493263509Sdim//     branches on the result.
494263509Sdim//
495251607Sdim//   Store:
496251607Sdim//     One register or immediate input operand and one address input operand.
497251607Sdim//     The instruction stores the first operand to the address.
498251607Sdim//
499251607Sdim//     This category is used for both pure and truncating stores.
500251607Sdim//
501251607Sdim//   LoadMultiple:
502251607Sdim//     One address input operand and two explicit output operands.
503251607Sdim//     The instruction loads a range of registers from the address,
504251607Sdim//     with the explicit operands giving the first and last register
505251607Sdim//     to load.  Other loaded registers are added as implicit definitions.
506251607Sdim//
507251607Sdim//   StoreMultiple:
508251607Sdim//     Two explicit input register operands and an address operand.
509251607Sdim//     The instruction stores a range of registers to the address,
510251607Sdim//     with the explicit operands giving the first and last register
511251607Sdim//     to store.  Other stored registers are added as implicit uses.
512251607Sdim//
513251607Sdim//   Unary:
514251607Sdim//     One register output operand and one input operand.  The input
515251607Sdim//     operand may be a register, immediate or memory.
516251607Sdim//
517251607Sdim//   Binary:
518251607Sdim//     One register output operand and two input operands.  The first
519251607Sdim//     input operand is always a register and he second may be a register,
520251607Sdim//     immediate or memory.
521251607Sdim//
522251607Sdim//   Shift:
523251607Sdim//     One register output operand and two input operands.  The first
524251607Sdim//     input operand is a register and the second has the same form as
525251607Sdim//     an address (although it isn't actually used to address memory).
526251607Sdim//
527251607Sdim//   Compare:
528251607Sdim//     Two input operands.  The first operand is always a register,
529251607Sdim//     the second may be a register, immediate or memory.
530251607Sdim//
531251607Sdim//   Ternary:
532251607Sdim//     One register output operand and three register input operands.
533251607Sdim//
534251607Sdim//   CmpSwap:
535251607Sdim//     One output operand and three input operands.  The first two
536251607Sdim//     operands are registers and the third is an address.  The instruction
537251607Sdim//     both reads from and writes to the address.
538251607Sdim//
539251607Sdim//   RotateSelect:
540251607Sdim//     One output operand and five input operands.  The first two operands
541251607Sdim//     are registers and the other three are immediates.
542251607Sdim//
543263509Sdim//   Prefetch:
544263509Sdim//     One 4-bit immediate operand and one address operand.  The immediate
545263509Sdim//     operand is 1 for a load prefetch and 2 for a store prefetch.
546263509Sdim//
547251607Sdim// The format determines which input operands are tied to output operands,
548251607Sdim// and also determines the shape of any address operand.
549251607Sdim//
550251607Sdim// Multiclasses of the form <Category><Format>Pair define two instructions,
551251607Sdim// one with <Category><Format> and one with <Category><Format>Y.  The name
552251607Sdim// of the first instruction has no suffix, the name of the second has
553251607Sdim// an extra "y".
554251607Sdim//
555251607Sdim//===----------------------------------------------------------------------===//
556251607Sdim
557251607Sdimclass InherentRRE<string mnemonic, bits<16> opcode, RegisterOperand cls,
558251607Sdim                  dag src>
559263509Sdim  : InstRRE<opcode, (outs cls:$R1), (ins),
560263509Sdim            mnemonic#"\t$R1",
561263509Sdim            [(set cls:$R1, src)]> {
562251607Sdim  let R2 = 0;
563251607Sdim}
564251607Sdim
565263509Sdimclass BranchUnaryRI<string mnemonic, bits<12> opcode, RegisterOperand cls>
566263509Sdim  : InstRI<opcode, (outs cls:$R1), (ins cls:$R1src, brtarget16:$I2),
567263509Sdim           mnemonic##"\t$R1, $I2", []> {
568263509Sdim  let isBranch = 1;
569263509Sdim  let isTerminator = 1;
570263509Sdim  let Constraints = "$R1 = $R1src";
571263509Sdim  let DisableEncoding = "$R1src";
572263509Sdim}
573263509Sdim
574251607Sdimclass LoadMultipleRSY<string mnemonic, bits<16> opcode, RegisterOperand cls>
575263509Sdim  : InstRSY<opcode, (outs cls:$R1, cls:$R3), (ins bdaddr20only:$BD2),
576263509Sdim            mnemonic#"\t$R1, $R3, $BD2", []> {
577251607Sdim  let mayLoad = 1;
578251607Sdim}
579251607Sdim
580251607Sdimclass StoreRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator,
581251607Sdim                 RegisterOperand cls>
582263509Sdim  : InstRIL<opcode, (outs), (ins cls:$R1, pcrel32:$I2),
583263509Sdim            mnemonic#"\t$R1, $I2",
584263509Sdim            [(operator cls:$R1, pcrel32:$I2)]> {
585251607Sdim  let mayStore = 1;
586251607Sdim  // We want PC-relative addresses to be tried ahead of BD and BDX addresses.
587251607Sdim  // However, BDXs have two extra operands and are therefore 6 units more
588251607Sdim  // complex.
589251607Sdim  let AddedComplexity = 7;
590251607Sdim}
591251607Sdim
592251607Sdimclass StoreRX<string mnemonic, bits<8> opcode, SDPatternOperator operator,
593263509Sdim              RegisterOperand cls, bits<5> bytes,
594263509Sdim              AddressingMode mode = bdxaddr12only>
595263509Sdim  : InstRX<opcode, (outs), (ins cls:$R1, mode:$XBD2),
596263509Sdim           mnemonic#"\t$R1, $XBD2",
597263509Sdim           [(operator cls:$R1, mode:$XBD2)]> {
598263509Sdim  let OpKey = mnemonic ## cls;
599263509Sdim  let OpType = "mem";
600251607Sdim  let mayStore = 1;
601263509Sdim  let AccessBytes = bytes;
602251607Sdim}
603251607Sdim
604251607Sdimclass StoreRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
605263509Sdim               RegisterOperand cls, bits<5> bytes,
606263509Sdim               AddressingMode mode = bdxaddr20only>
607263509Sdim  : InstRXY<opcode, (outs), (ins cls:$R1, mode:$XBD2),
608263509Sdim            mnemonic#"\t$R1, $XBD2",
609263509Sdim            [(operator cls:$R1, mode:$XBD2)]> {
610263509Sdim  let OpKey = mnemonic ## cls;
611263509Sdim  let OpType = "mem";
612251607Sdim  let mayStore = 1;
613263509Sdim  let AccessBytes = bytes;
614251607Sdim}
615251607Sdim
616251607Sdimmulticlass StoreRXPair<string mnemonic, bits<8> rxOpcode, bits<16> rxyOpcode,
617263509Sdim                       SDPatternOperator operator, RegisterOperand cls,
618263509Sdim                       bits<5> bytes> {
619263509Sdim  let DispKey = mnemonic ## #cls in {
620263509Sdim    let DispSize = "12" in
621263509Sdim      def "" : StoreRX<mnemonic, rxOpcode, operator, cls, bytes, bdxaddr12pair>;
622263509Sdim    let DispSize = "20" in
623263509Sdim      def Y  : StoreRXY<mnemonic#"y", rxyOpcode, operator, cls, bytes,
624263509Sdim                        bdxaddr20pair>;
625251607Sdim  }
626251607Sdim}
627251607Sdim
628251607Sdimclass StoreMultipleRSY<string mnemonic, bits<16> opcode, RegisterOperand cls>
629263509Sdim  : InstRSY<opcode, (outs), (ins cls:$R1, cls:$R3, bdaddr20only:$BD2),
630263509Sdim            mnemonic#"\t$R1, $R3, $BD2", []> {
631251607Sdim  let mayStore = 1;
632251607Sdim}
633251607Sdim
634263509Sdim// StoreSI* instructions are used to store an integer to memory, but the
635263509Sdim// addresses are more restricted than for normal stores.  If we are in the
636263509Sdim// situation of having to force either the address into a register or the
637263509Sdim// constant into a register, it's usually better to do the latter.
638263509Sdim// We therefore match the address in the same way as a normal store and
639263509Sdim// only use the StoreSI* instruction if the matched address is suitable.
640251607Sdimclass StoreSI<string mnemonic, bits<8> opcode, SDPatternOperator operator,
641263509Sdim              Immediate imm>
642263509Sdim  : InstSI<opcode, (outs), (ins mviaddr12pair:$BD1, imm:$I2),
643263509Sdim           mnemonic#"\t$BD1, $I2",
644263509Sdim           [(operator imm:$I2, mviaddr12pair:$BD1)]> {
645251607Sdim  let mayStore = 1;
646251607Sdim}
647251607Sdim
648251607Sdimclass StoreSIY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
649263509Sdim               Immediate imm>
650263509Sdim  : InstSIY<opcode, (outs), (ins mviaddr20pair:$BD1, imm:$I2),
651263509Sdim            mnemonic#"\t$BD1, $I2",
652263509Sdim            [(operator imm:$I2, mviaddr20pair:$BD1)]> {
653251607Sdim  let mayStore = 1;
654251607Sdim}
655251607Sdim
656251607Sdimclass StoreSIL<string mnemonic, bits<16> opcode, SDPatternOperator operator,
657251607Sdim               Immediate imm>
658263509Sdim  : InstSIL<opcode, (outs), (ins mviaddr12pair:$BD1, imm:$I2),
659263509Sdim            mnemonic#"\t$BD1, $I2",
660263509Sdim            [(operator imm:$I2, mviaddr12pair:$BD1)]> {
661251607Sdim  let mayStore = 1;
662251607Sdim}
663251607Sdim
664251607Sdimmulticlass StoreSIPair<string mnemonic, bits<8> siOpcode, bits<16> siyOpcode,
665251607Sdim                       SDPatternOperator operator, Immediate imm> {
666263509Sdim  let DispKey = mnemonic in {
667263509Sdim    let DispSize = "12" in
668263509Sdim      def "" : StoreSI<mnemonic, siOpcode, operator, imm>;
669263509Sdim    let DispSize = "20" in
670263509Sdim      def Y  : StoreSIY<mnemonic#"y", siyOpcode, operator, imm>;
671251607Sdim  }
672251607Sdim}
673251607Sdim
674263509Sdimclass CondStoreRSY<string mnemonic, bits<16> opcode,
675263509Sdim                   RegisterOperand cls, bits<5> bytes,
676263509Sdim                   AddressingMode mode = bdaddr20only>
677263509Sdim  : InstRSY<opcode, (outs), (ins cls:$R1, mode:$BD2, cond4:$valid, cond4:$R3),
678263509Sdim            mnemonic#"$R3\t$R1, $BD2", []>,
679263509Sdim    Requires<[FeatureLoadStoreOnCond]> {
680263509Sdim  let mayStore = 1;
681263509Sdim  let AccessBytes = bytes;
682263509Sdim  let CCMaskLast = 1;
683263509Sdim}
684263509Sdim
685263509Sdim// Like CondStoreRSY, but used for the raw assembly form.  The condition-code
686263509Sdim// mask is the third operand rather than being part of the mnemonic.
687263509Sdimclass AsmCondStoreRSY<string mnemonic, bits<16> opcode,
688263509Sdim                      RegisterOperand cls, bits<5> bytes,
689263509Sdim                      AddressingMode mode = bdaddr20only>
690263509Sdim  : InstRSY<opcode, (outs), (ins cls:$R1, mode:$BD2, uimm8zx4:$R3),
691263509Sdim            mnemonic#"\t$R1, $BD2, $R3", []>,
692263509Sdim    Requires<[FeatureLoadStoreOnCond]> {
693263509Sdim  let mayStore = 1;
694263509Sdim  let AccessBytes = bytes;
695263509Sdim}
696263509Sdim
697263509Sdim// Like CondStoreRSY, but with a fixed CC mask.
698263509Sdimclass FixedCondStoreRSY<string mnemonic, bits<16> opcode,
699263509Sdim                        RegisterOperand cls, bits<4> ccmask, bits<5> bytes,
700263509Sdim                        AddressingMode mode = bdaddr20only>
701263509Sdim  : InstRSY<opcode, (outs), (ins cls:$R1, mode:$BD2),
702263509Sdim            mnemonic#"\t$R1, $BD2", []>,
703263509Sdim    Requires<[FeatureLoadStoreOnCond]> {
704263509Sdim  let mayStore = 1;
705263509Sdim  let AccessBytes = bytes;
706263509Sdim  let R3 = ccmask;
707263509Sdim}
708263509Sdim
709251607Sdimclass UnaryRR<string mnemonic, bits<8> opcode, SDPatternOperator operator,
710251607Sdim              RegisterOperand cls1, RegisterOperand cls2>
711263509Sdim  : InstRR<opcode, (outs cls1:$R1), (ins cls2:$R2),
712263509Sdim           mnemonic#"r\t$R1, $R2",
713263509Sdim           [(set cls1:$R1, (operator cls2:$R2))]> {
714263509Sdim  let OpKey = mnemonic ## cls1;
715263509Sdim  let OpType = "reg";
716263509Sdim}
717251607Sdim
718251607Sdimclass UnaryRRE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
719251607Sdim               RegisterOperand cls1, RegisterOperand cls2>
720263509Sdim  : InstRRE<opcode, (outs cls1:$R1), (ins cls2:$R2),
721263509Sdim            mnemonic#"r\t$R1, $R2",
722263509Sdim            [(set cls1:$R1, (operator cls2:$R2))]> {
723263509Sdim  let OpKey = mnemonic ## cls1;
724263509Sdim  let OpType = "reg";
725263509Sdim}
726251607Sdim
727251607Sdimclass UnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1,
728251607Sdim               RegisterOperand cls2>
729263509Sdim  : InstRRF<opcode, (outs cls1:$R1), (ins uimm8zx4:$R3, cls2:$R2),
730263509Sdim            mnemonic#"r\t$R1, $R3, $R2", []> {
731263509Sdim  let OpKey = mnemonic ## cls1;
732263509Sdim  let OpType = "reg";
733263509Sdim  let R4 = 0;
734263509Sdim}
735251607Sdim
736263509Sdimclass UnaryRRF4<string mnemonic, bits<16> opcode, RegisterOperand cls1,
737263509Sdim                RegisterOperand cls2>
738263509Sdim  : InstRRF<opcode, (outs cls1:$R1), (ins uimm8zx4:$R3, cls2:$R2, uimm8zx4:$R4),
739263509Sdim            mnemonic#"\t$R1, $R3, $R2, $R4", []>;
740263509Sdim
741263509Sdim// These instructions are generated by if conversion.  The old value of R1
742263509Sdim// is added as an implicit use.
743263509Sdimclass CondUnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1,
744263509Sdim                   RegisterOperand cls2>
745263509Sdim  : InstRRF<opcode, (outs cls1:$R1), (ins cls2:$R2, cond4:$valid, cond4:$R3),
746263509Sdim            mnemonic#"r$R3\t$R1, $R2", []>,
747263509Sdim    Requires<[FeatureLoadStoreOnCond]> {
748263509Sdim  let CCMaskLast = 1;
749263509Sdim  let R4 = 0;
750263509Sdim}
751263509Sdim
752263509Sdim// Like CondUnaryRRF, but used for the raw assembly form.  The condition-code
753263509Sdim// mask is the third operand rather than being part of the mnemonic.
754263509Sdimclass AsmCondUnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1,
755263509Sdim                      RegisterOperand cls2>
756263509Sdim  : InstRRF<opcode, (outs cls1:$R1), (ins cls1:$R1src, cls2:$R2, uimm8zx4:$R3),
757263509Sdim            mnemonic#"r\t$R1, $R2, $R3", []>,
758263509Sdim    Requires<[FeatureLoadStoreOnCond]> {
759263509Sdim  let Constraints = "$R1 = $R1src";
760263509Sdim  let DisableEncoding = "$R1src";
761263509Sdim  let R4 = 0;
762263509Sdim}
763263509Sdim
764263509Sdim// Like CondUnaryRRF, but with a fixed CC mask.
765263509Sdimclass FixedCondUnaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1,
766263509Sdim                        RegisterOperand cls2, bits<4> ccmask>
767263509Sdim  : InstRRF<opcode, (outs cls1:$R1), (ins cls1:$R1src, cls2:$R2),
768263509Sdim            mnemonic#"\t$R1, $R2", []>,
769263509Sdim    Requires<[FeatureLoadStoreOnCond]> {
770263509Sdim  let Constraints = "$R1 = $R1src";
771263509Sdim  let DisableEncoding = "$R1src";
772263509Sdim  let R3 = ccmask;
773263509Sdim  let R4 = 0;
774263509Sdim}
775263509Sdim
776251607Sdimclass UnaryRI<string mnemonic, bits<12> opcode, SDPatternOperator operator,
777251607Sdim              RegisterOperand cls, Immediate imm>
778263509Sdim  : InstRI<opcode, (outs cls:$R1), (ins imm:$I2),
779263509Sdim           mnemonic#"\t$R1, $I2",
780263509Sdim           [(set cls:$R1, (operator imm:$I2))]>;
781251607Sdim
782251607Sdimclass UnaryRIL<string mnemonic, bits<12> opcode, SDPatternOperator operator,
783251607Sdim               RegisterOperand cls, Immediate imm>
784263509Sdim  : InstRIL<opcode, (outs cls:$R1), (ins imm:$I2),
785263509Sdim            mnemonic#"\t$R1, $I2",
786263509Sdim            [(set cls:$R1, (operator imm:$I2))]>;
787251607Sdim
788251607Sdimclass UnaryRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator,
789251607Sdim                 RegisterOperand cls>
790263509Sdim  : InstRIL<opcode, (outs cls:$R1), (ins pcrel32:$I2),
791263509Sdim            mnemonic#"\t$R1, $I2",
792263509Sdim            [(set cls:$R1, (operator pcrel32:$I2))]> {
793251607Sdim  let mayLoad = 1;
794251607Sdim  // We want PC-relative addresses to be tried ahead of BD and BDX addresses.
795251607Sdim  // However, BDXs have two extra operands and are therefore 6 units more
796251607Sdim  // complex.
797251607Sdim  let AddedComplexity = 7;
798251607Sdim}
799251607Sdim
800263509Sdimclass CondUnaryRSY<string mnemonic, bits<16> opcode,
801263509Sdim                   SDPatternOperator operator, RegisterOperand cls,
802263509Sdim                   bits<5> bytes, AddressingMode mode = bdaddr20only>
803263509Sdim  : InstRSY<opcode, (outs cls:$R1),
804263509Sdim            (ins cls:$R1src, mode:$BD2, cond4:$valid, cond4:$R3),
805263509Sdim            mnemonic#"$R3\t$R1, $BD2",
806263509Sdim            [(set cls:$R1,
807263509Sdim                  (z_select_ccmask (load bdaddr20only:$BD2), cls:$R1src,
808263509Sdim                                   cond4:$valid, cond4:$R3))]>,
809263509Sdim    Requires<[FeatureLoadStoreOnCond]> {
810263509Sdim  let Constraints = "$R1 = $R1src";
811263509Sdim  let DisableEncoding = "$R1src";
812263509Sdim  let mayLoad = 1;
813263509Sdim  let AccessBytes = bytes;
814263509Sdim  let CCMaskLast = 1;
815263509Sdim}
816263509Sdim
817263509Sdim// Like CondUnaryRSY, but used for the raw assembly form.  The condition-code
818263509Sdim// mask is the third operand rather than being part of the mnemonic.
819263509Sdimclass AsmCondUnaryRSY<string mnemonic, bits<16> opcode,
820263509Sdim                      RegisterOperand cls, bits<5> bytes,
821263509Sdim                      AddressingMode mode = bdaddr20only>
822263509Sdim  : InstRSY<opcode, (outs cls:$R1), (ins cls:$R1src, mode:$BD2, uimm8zx4:$R3),
823263509Sdim            mnemonic#"\t$R1, $BD2, $R3", []>,
824263509Sdim    Requires<[FeatureLoadStoreOnCond]> {
825263509Sdim  let mayLoad = 1;
826263509Sdim  let AccessBytes = bytes;
827263509Sdim  let Constraints = "$R1 = $R1src";
828263509Sdim  let DisableEncoding = "$R1src";
829263509Sdim}
830263509Sdim
831263509Sdim// Like CondUnaryRSY, but with a fixed CC mask.
832263509Sdimclass FixedCondUnaryRSY<string mnemonic, bits<16> opcode,
833263509Sdim                        RegisterOperand cls, bits<4> ccmask, bits<5> bytes,
834263509Sdim                        AddressingMode mode = bdaddr20only>
835263509Sdim  : InstRSY<opcode, (outs cls:$R1), (ins cls:$R1src, mode:$BD2),
836263509Sdim            mnemonic#"\t$R1, $BD2", []>,
837263509Sdim    Requires<[FeatureLoadStoreOnCond]> {
838263509Sdim  let Constraints = "$R1 = $R1src";
839263509Sdim  let DisableEncoding = "$R1src";
840263509Sdim  let R3 = ccmask;
841263509Sdim  let mayLoad = 1;
842263509Sdim  let AccessBytes = bytes;
843263509Sdim}
844263509Sdim
845251607Sdimclass UnaryRX<string mnemonic, bits<8> opcode, SDPatternOperator operator,
846263509Sdim              RegisterOperand cls, bits<5> bytes,
847263509Sdim              AddressingMode mode = bdxaddr12only>
848263509Sdim  : InstRX<opcode, (outs cls:$R1), (ins mode:$XBD2),
849263509Sdim           mnemonic#"\t$R1, $XBD2",
850263509Sdim           [(set cls:$R1, (operator mode:$XBD2))]> {
851263509Sdim  let OpKey = mnemonic ## cls;
852263509Sdim  let OpType = "mem";
853251607Sdim  let mayLoad = 1;
854263509Sdim  let AccessBytes = bytes;
855251607Sdim}
856251607Sdim
857251607Sdimclass UnaryRXE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
858263509Sdim               RegisterOperand cls, bits<5> bytes>
859263509Sdim  : InstRXE<opcode, (outs cls:$R1), (ins bdxaddr12only:$XBD2),
860263509Sdim            mnemonic#"\t$R1, $XBD2",
861263509Sdim            [(set cls:$R1, (operator bdxaddr12only:$XBD2))]> {
862263509Sdim  let OpKey = mnemonic ## cls;
863263509Sdim  let OpType = "mem";
864251607Sdim  let mayLoad = 1;
865263509Sdim  let AccessBytes = bytes;
866251607Sdim}
867251607Sdim
868251607Sdimclass UnaryRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
869263509Sdim               RegisterOperand cls, bits<5> bytes,
870263509Sdim               AddressingMode mode = bdxaddr20only>
871263509Sdim  : InstRXY<opcode, (outs cls:$R1), (ins mode:$XBD2),
872263509Sdim            mnemonic#"\t$R1, $XBD2",
873263509Sdim            [(set cls:$R1, (operator mode:$XBD2))]> {
874263509Sdim  let OpKey = mnemonic ## cls;
875263509Sdim  let OpType = "mem";
876251607Sdim  let mayLoad = 1;
877263509Sdim  let AccessBytes = bytes;
878251607Sdim}
879251607Sdim
880251607Sdimmulticlass UnaryRXPair<string mnemonic, bits<8> rxOpcode, bits<16> rxyOpcode,
881263509Sdim                       SDPatternOperator operator, RegisterOperand cls,
882263509Sdim                       bits<5> bytes> {
883263509Sdim  let DispKey = mnemonic ## #cls in {
884263509Sdim    let DispSize = "12" in
885263509Sdim      def "" : UnaryRX<mnemonic, rxOpcode, operator, cls, bytes, bdxaddr12pair>;
886263509Sdim    let DispSize = "20" in
887263509Sdim      def Y  : UnaryRXY<mnemonic#"y", rxyOpcode, operator, cls, bytes,
888263509Sdim                        bdxaddr20pair>;
889251607Sdim  }
890251607Sdim}
891251607Sdim
892251607Sdimclass BinaryRR<string mnemonic, bits<8> opcode, SDPatternOperator operator,
893251607Sdim               RegisterOperand cls1, RegisterOperand cls2>
894263509Sdim  : InstRR<opcode, (outs cls1:$R1), (ins cls1:$R1src, cls2:$R2),
895263509Sdim           mnemonic#"r\t$R1, $R2",
896263509Sdim           [(set cls1:$R1, (operator cls1:$R1src, cls2:$R2))]> {
897263509Sdim  let OpKey = mnemonic ## cls1;
898263509Sdim  let OpType = "reg";
899263509Sdim  let Constraints = "$R1 = $R1src";
900263509Sdim  let DisableEncoding = "$R1src";
901251607Sdim}
902251607Sdim
903251607Sdimclass BinaryRRE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
904251607Sdim                RegisterOperand cls1, RegisterOperand cls2>
905263509Sdim  : InstRRE<opcode, (outs cls1:$R1), (ins cls1:$R1src, cls2:$R2),
906263509Sdim            mnemonic#"r\t$R1, $R2",
907263509Sdim            [(set cls1:$R1, (operator cls1:$R1src, cls2:$R2))]> {
908263509Sdim  let OpKey = mnemonic ## cls1;
909263509Sdim  let OpType = "reg";
910263509Sdim  let Constraints = "$R1 = $R1src";
911263509Sdim  let DisableEncoding = "$R1src";
912251607Sdim}
913251607Sdim
914263509Sdimclass BinaryRRF<string mnemonic, bits<16> opcode, SDPatternOperator operator,
915263509Sdim                RegisterOperand cls1, RegisterOperand cls2>
916263509Sdim  : InstRRF<opcode, (outs cls1:$R1), (ins cls1:$R3, cls2:$R2),
917263509Sdim            mnemonic#"r\t$R1, $R3, $R2",
918263509Sdim            [(set cls1:$R1, (operator cls1:$R3, cls2:$R2))]> {
919263509Sdim  let OpKey = mnemonic ## cls1;
920263509Sdim  let OpType = "reg";
921263509Sdim  let R4 = 0;
922263509Sdim}
923251607Sdim
924263509Sdimclass BinaryRRFK<string mnemonic, bits<16> opcode, SDPatternOperator operator,
925263509Sdim                 RegisterOperand cls1, RegisterOperand cls2>
926263509Sdim  : InstRRF<opcode, (outs cls1:$R1), (ins cls1:$R2, cls2:$R3),
927263509Sdim            mnemonic#"rk\t$R1, $R2, $R3",
928263509Sdim            [(set cls1:$R1, (operator cls1:$R2, cls2:$R3))]> {
929263509Sdim  let R4 = 0;
930263509Sdim}
931263509Sdim
932263509Sdimmulticlass BinaryRRAndK<string mnemonic, bits<8> opcode1, bits<16> opcode2,
933263509Sdim                        SDPatternOperator operator, RegisterOperand cls1,
934263509Sdim                        RegisterOperand cls2> {
935263509Sdim  let NumOpsKey = mnemonic in {
936263509Sdim    let NumOpsValue = "3" in
937263509Sdim      def K : BinaryRRFK<mnemonic, opcode2, null_frag, cls1, cls2>,
938263509Sdim              Requires<[FeatureDistinctOps]>;
939263509Sdim    let NumOpsValue = "2", isConvertibleToThreeAddress = 1 in
940263509Sdim      def "" : BinaryRR<mnemonic, opcode1, operator, cls1, cls2>;
941263509Sdim  }
942263509Sdim}
943263509Sdim
944263509Sdimmulticlass BinaryRREAndK<string mnemonic, bits<16> opcode1, bits<16> opcode2,
945263509Sdim                         SDPatternOperator operator, RegisterOperand cls1,
946263509Sdim                         RegisterOperand cls2> {
947263509Sdim  let NumOpsKey = mnemonic in {
948263509Sdim    let NumOpsValue = "3" in
949263509Sdim      def K : BinaryRRFK<mnemonic, opcode2, null_frag, cls1, cls2>,
950263509Sdim              Requires<[FeatureDistinctOps]>;
951263509Sdim    let NumOpsValue = "2", isConvertibleToThreeAddress = 1 in
952263509Sdim      def "" : BinaryRRE<mnemonic, opcode1, operator, cls1, cls2>;
953263509Sdim  }
954263509Sdim}
955263509Sdim
956251607Sdimclass BinaryRI<string mnemonic, bits<12> opcode, SDPatternOperator operator,
957251607Sdim               RegisterOperand cls, Immediate imm>
958263509Sdim  : InstRI<opcode, (outs cls:$R1), (ins cls:$R1src, imm:$I2),
959263509Sdim           mnemonic#"\t$R1, $I2",
960263509Sdim           [(set cls:$R1, (operator cls:$R1src, imm:$I2))]> {
961263509Sdim  let Constraints = "$R1 = $R1src";
962263509Sdim  let DisableEncoding = "$R1src";
963251607Sdim}
964251607Sdim
965263509Sdimclass BinaryRIE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
966263509Sdim                RegisterOperand cls, Immediate imm>
967263509Sdim  : InstRIEd<opcode, (outs cls:$R1), (ins cls:$R3, imm:$I2),
968263509Sdim             mnemonic#"\t$R1, $R3, $I2",
969263509Sdim             [(set cls:$R1, (operator cls:$R3, imm:$I2))]>;
970263509Sdim
971263509Sdimmulticlass BinaryRIAndK<string mnemonic, bits<12> opcode1, bits<16> opcode2,
972263509Sdim                        SDPatternOperator operator, RegisterOperand cls,
973263509Sdim                        Immediate imm> {
974263509Sdim  let NumOpsKey = mnemonic in {
975263509Sdim    let NumOpsValue = "3" in
976263509Sdim      def K : BinaryRIE<mnemonic##"k", opcode2, null_frag, cls, imm>,
977263509Sdim              Requires<[FeatureDistinctOps]>;
978263509Sdim    let NumOpsValue = "2", isConvertibleToThreeAddress = 1 in
979263509Sdim      def "" : BinaryRI<mnemonic, opcode1, operator, cls, imm>;
980263509Sdim  }
981263509Sdim}
982263509Sdim
983251607Sdimclass BinaryRIL<string mnemonic, bits<12> opcode, SDPatternOperator operator,
984251607Sdim                RegisterOperand cls, Immediate imm>
985263509Sdim  : InstRIL<opcode, (outs cls:$R1), (ins cls:$R1src, imm:$I2),
986263509Sdim            mnemonic#"\t$R1, $I2",
987263509Sdim            [(set cls:$R1, (operator cls:$R1src, imm:$I2))]> {
988263509Sdim  let Constraints = "$R1 = $R1src";
989263509Sdim  let DisableEncoding = "$R1src";
990251607Sdim}
991251607Sdim
992251607Sdimclass BinaryRX<string mnemonic, bits<8> opcode, SDPatternOperator operator,
993263509Sdim               RegisterOperand cls, SDPatternOperator load, bits<5> bytes,
994251607Sdim               AddressingMode mode = bdxaddr12only>
995263509Sdim  : InstRX<opcode, (outs cls:$R1), (ins cls:$R1src, mode:$XBD2),
996263509Sdim           mnemonic#"\t$R1, $XBD2",
997263509Sdim           [(set cls:$R1, (operator cls:$R1src, (load mode:$XBD2)))]> {
998263509Sdim  let OpKey = mnemonic ## cls;
999263509Sdim  let OpType = "mem";
1000263509Sdim  let Constraints = "$R1 = $R1src";
1001263509Sdim  let DisableEncoding = "$R1src";
1002251607Sdim  let mayLoad = 1;
1003263509Sdim  let AccessBytes = bytes;
1004251607Sdim}
1005251607Sdim
1006251607Sdimclass BinaryRXE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1007263509Sdim                  RegisterOperand cls, SDPatternOperator load, bits<5> bytes>
1008263509Sdim  : InstRXE<opcode, (outs cls:$R1), (ins cls:$R1src, bdxaddr12only:$XBD2),
1009263509Sdim            mnemonic#"\t$R1, $XBD2",
1010263509Sdim            [(set cls:$R1, (operator cls:$R1src,
1011263509Sdim                                     (load bdxaddr12only:$XBD2)))]> {
1012263509Sdim  let OpKey = mnemonic ## cls;
1013263509Sdim  let OpType = "mem";
1014263509Sdim  let Constraints = "$R1 = $R1src";
1015263509Sdim  let DisableEncoding = "$R1src";
1016251607Sdim  let mayLoad = 1;
1017263509Sdim  let AccessBytes = bytes;
1018251607Sdim}
1019251607Sdim
1020251607Sdimclass BinaryRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1021263509Sdim                RegisterOperand cls, SDPatternOperator load, bits<5> bytes,
1022251607Sdim                AddressingMode mode = bdxaddr20only>
1023263509Sdim  : InstRXY<opcode, (outs cls:$R1), (ins cls:$R1src, mode:$XBD2),
1024263509Sdim            mnemonic#"\t$R1, $XBD2",
1025263509Sdim            [(set cls:$R1, (operator cls:$R1src, (load mode:$XBD2)))]> {
1026263509Sdim  let OpKey = mnemonic ## cls;
1027263509Sdim  let OpType = "mem";
1028263509Sdim  let Constraints = "$R1 = $R1src";
1029263509Sdim  let DisableEncoding = "$R1src";
1030251607Sdim  let mayLoad = 1;
1031263509Sdim  let AccessBytes = bytes;
1032251607Sdim}
1033251607Sdim
1034251607Sdimmulticlass BinaryRXPair<string mnemonic, bits<8> rxOpcode, bits<16> rxyOpcode,
1035251607Sdim                        SDPatternOperator operator, RegisterOperand cls,
1036263509Sdim                        SDPatternOperator load, bits<5> bytes> {
1037263509Sdim  let DispKey = mnemonic ## #cls in {
1038263509Sdim    let DispSize = "12" in
1039263509Sdim      def "" : BinaryRX<mnemonic, rxOpcode, operator, cls, load, bytes,
1040263509Sdim                        bdxaddr12pair>;
1041263509Sdim    let DispSize = "20" in
1042263509Sdim      def Y  : BinaryRXY<mnemonic#"y", rxyOpcode, operator, cls, load, bytes,
1043251607Sdim                         bdxaddr20pair>;
1044251607Sdim  }
1045251607Sdim}
1046251607Sdim
1047251607Sdimclass BinarySI<string mnemonic, bits<8> opcode, SDPatternOperator operator,
1048251607Sdim               Operand imm, AddressingMode mode = bdaddr12only>
1049263509Sdim  : InstSI<opcode, (outs), (ins mode:$BD1, imm:$I2),
1050263509Sdim           mnemonic#"\t$BD1, $I2",
1051263509Sdim           [(store (operator (load mode:$BD1), imm:$I2), mode:$BD1)]> {
1052251607Sdim  let mayLoad = 1;
1053251607Sdim  let mayStore = 1;
1054251607Sdim}
1055251607Sdim
1056251607Sdimclass BinarySIY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1057251607Sdim                Operand imm, AddressingMode mode = bdaddr20only>
1058263509Sdim  : InstSIY<opcode, (outs), (ins mode:$BD1, imm:$I2),
1059263509Sdim            mnemonic#"\t$BD1, $I2",
1060263509Sdim            [(store (operator (load mode:$BD1), imm:$I2), mode:$BD1)]> {
1061251607Sdim  let mayLoad = 1;
1062251607Sdim  let mayStore = 1;
1063251607Sdim}
1064251607Sdim
1065251607Sdimmulticlass BinarySIPair<string mnemonic, bits<8> siOpcode,
1066251607Sdim                        bits<16> siyOpcode, SDPatternOperator operator,
1067251607Sdim                        Operand imm> {
1068263509Sdim  let DispKey = mnemonic ## #cls in {
1069263509Sdim    let DispSize = "12" in
1070251607Sdim      def "" : BinarySI<mnemonic, siOpcode, operator, imm, bdaddr12pair>;
1071263509Sdim    let DispSize = "20" in
1072251607Sdim      def Y  : BinarySIY<mnemonic#"y", siyOpcode, operator, imm, bdaddr20pair>;
1073251607Sdim  }
1074251607Sdim}
1075251607Sdim
1076251607Sdimclass ShiftRS<string mnemonic, bits<8> opcode, SDPatternOperator operator,
1077263509Sdim              RegisterOperand cls>
1078263509Sdim  : InstRS<opcode, (outs cls:$R1), (ins cls:$R1src, shift12only:$BD2),
1079263509Sdim           mnemonic#"\t$R1, $BD2",
1080263509Sdim           [(set cls:$R1, (operator cls:$R1src, shift12only:$BD2))]> {
1081251607Sdim  let R3 = 0;
1082263509Sdim  let Constraints = "$R1 = $R1src";
1083263509Sdim  let DisableEncoding = "$R1src";
1084251607Sdim}
1085251607Sdim
1086251607Sdimclass ShiftRSY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1087263509Sdim               RegisterOperand cls>
1088263509Sdim  : InstRSY<opcode, (outs cls:$R1), (ins cls:$R3, shift20only:$BD2),
1089263509Sdim            mnemonic#"\t$R1, $R3, $BD2",
1090263509Sdim            [(set cls:$R1, (operator cls:$R3, shift20only:$BD2))]>;
1091251607Sdim
1092263509Sdimmulticlass ShiftRSAndK<string mnemonic, bits<8> opcode1, bits<16> opcode2,
1093263509Sdim                       SDPatternOperator operator, RegisterOperand cls> {
1094263509Sdim  let NumOpsKey = mnemonic in {
1095263509Sdim    let NumOpsValue = "3" in
1096263509Sdim      def K  : ShiftRSY<mnemonic##"k", opcode2, null_frag, cls>,
1097263509Sdim               Requires<[FeatureDistinctOps]>;
1098263509Sdim    let NumOpsValue = "2", isConvertibleToThreeAddress = 1 in
1099263509Sdim      def "" : ShiftRS<mnemonic, opcode1, operator, cls>;
1100263509Sdim  }
1101263509Sdim}
1102263509Sdim
1103251607Sdimclass CompareRR<string mnemonic, bits<8> opcode, SDPatternOperator operator,
1104251607Sdim                RegisterOperand cls1, RegisterOperand cls2>
1105263509Sdim  : InstRR<opcode, (outs), (ins cls1:$R1, cls2:$R2),
1106263509Sdim           mnemonic#"r\t$R1, $R2",
1107263509Sdim           [(operator cls1:$R1, cls2:$R2)]> {
1108263509Sdim  let OpKey = mnemonic ## cls1;
1109263509Sdim  let OpType = "reg";
1110263509Sdim  let isCompare = 1;
1111263509Sdim}
1112251607Sdim
1113251607Sdimclass CompareRRE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1114251607Sdim                 RegisterOperand cls1, RegisterOperand cls2>
1115263509Sdim  : InstRRE<opcode, (outs), (ins cls1:$R1, cls2:$R2),
1116263509Sdim            mnemonic#"r\t$R1, $R2",
1117263509Sdim            [(operator cls1:$R1, cls2:$R2)]> {
1118263509Sdim  let OpKey = mnemonic ## cls1;
1119263509Sdim  let OpType = "reg";
1120263509Sdim  let isCompare = 1;
1121263509Sdim}
1122251607Sdim
1123251607Sdimclass CompareRI<string mnemonic, bits<12> opcode, SDPatternOperator operator,
1124251607Sdim                RegisterOperand cls, Immediate imm>
1125263509Sdim  : InstRI<opcode, (outs), (ins cls:$R1, imm:$I2),
1126263509Sdim           mnemonic#"\t$R1, $I2",
1127263509Sdim           [(operator cls:$R1, imm:$I2)]> {
1128263509Sdim  let isCompare = 1;
1129263509Sdim}
1130251607Sdim
1131251607Sdimclass CompareRIL<string mnemonic, bits<12> opcode, SDPatternOperator operator,
1132251607Sdim                 RegisterOperand cls, Immediate imm>
1133263509Sdim  : InstRIL<opcode, (outs), (ins cls:$R1, imm:$I2),
1134263509Sdim            mnemonic#"\t$R1, $I2",
1135263509Sdim            [(operator cls:$R1, imm:$I2)]> {
1136263509Sdim  let isCompare = 1;
1137263509Sdim}
1138251607Sdim
1139251607Sdimclass CompareRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator,
1140251607Sdim                   RegisterOperand cls, SDPatternOperator load>
1141263509Sdim  : InstRIL<opcode, (outs), (ins cls:$R1, pcrel32:$I2),
1142263509Sdim            mnemonic#"\t$R1, $I2",
1143263509Sdim            [(operator cls:$R1, (load pcrel32:$I2))]> {
1144263509Sdim  let isCompare = 1;
1145251607Sdim  let mayLoad = 1;
1146251607Sdim  // We want PC-relative addresses to be tried ahead of BD and BDX addresses.
1147251607Sdim  // However, BDXs have two extra operands and are therefore 6 units more
1148251607Sdim  // complex.
1149251607Sdim  let AddedComplexity = 7;
1150251607Sdim}
1151251607Sdim
1152251607Sdimclass CompareRX<string mnemonic, bits<8> opcode, SDPatternOperator operator,
1153263509Sdim                RegisterOperand cls, SDPatternOperator load, bits<5> bytes,
1154251607Sdim                AddressingMode mode = bdxaddr12only>
1155263509Sdim  : InstRX<opcode, (outs), (ins cls:$R1, mode:$XBD2),
1156263509Sdim           mnemonic#"\t$R1, $XBD2",
1157263509Sdim           [(operator cls:$R1, (load mode:$XBD2))]> {
1158263509Sdim  let OpKey = mnemonic ## cls;
1159263509Sdim  let OpType = "mem";
1160263509Sdim  let isCompare = 1;
1161251607Sdim  let mayLoad = 1;
1162263509Sdim  let AccessBytes = bytes;
1163251607Sdim}
1164251607Sdim
1165251607Sdimclass CompareRXE<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1166263509Sdim                 RegisterOperand cls, SDPatternOperator load, bits<5> bytes>
1167263509Sdim  : InstRXE<opcode, (outs), (ins cls:$R1, bdxaddr12only:$XBD2),
1168263509Sdim            mnemonic#"\t$R1, $XBD2",
1169263509Sdim            [(operator cls:$R1, (load bdxaddr12only:$XBD2))]> {
1170263509Sdim  let OpKey = mnemonic ## cls;
1171263509Sdim  let OpType = "mem";
1172263509Sdim  let isCompare = 1;
1173251607Sdim  let mayLoad = 1;
1174263509Sdim  let AccessBytes = bytes;
1175251607Sdim}
1176251607Sdim
1177251607Sdimclass CompareRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1178263509Sdim                 RegisterOperand cls, SDPatternOperator load, bits<5> bytes,
1179251607Sdim                 AddressingMode mode = bdxaddr20only>
1180263509Sdim  : InstRXY<opcode, (outs), (ins cls:$R1, mode:$XBD2),
1181263509Sdim            mnemonic#"\t$R1, $XBD2",
1182263509Sdim            [(operator cls:$R1, (load mode:$XBD2))]> {
1183263509Sdim  let OpKey = mnemonic ## cls;
1184263509Sdim  let OpType = "mem";
1185263509Sdim  let isCompare = 1;
1186251607Sdim  let mayLoad = 1;
1187263509Sdim  let AccessBytes = bytes;
1188251607Sdim}
1189251607Sdim
1190251607Sdimmulticlass CompareRXPair<string mnemonic, bits<8> rxOpcode, bits<16> rxyOpcode,
1191251607Sdim                         SDPatternOperator operator, RegisterOperand cls,
1192263509Sdim                         SDPatternOperator load, bits<5> bytes> {
1193263509Sdim  let DispKey = mnemonic ## #cls in {
1194263509Sdim    let DispSize = "12" in
1195251607Sdim      def "" : CompareRX<mnemonic, rxOpcode, operator, cls,
1196263509Sdim                         load, bytes, bdxaddr12pair>;
1197263509Sdim    let DispSize = "20" in
1198251607Sdim      def Y  : CompareRXY<mnemonic#"y", rxyOpcode, operator, cls,
1199263509Sdim                          load, bytes, bdxaddr20pair>;
1200251607Sdim  }
1201251607Sdim}
1202251607Sdim
1203251607Sdimclass CompareSI<string mnemonic, bits<8> opcode, SDPatternOperator operator,
1204251607Sdim                SDPatternOperator load, Immediate imm,
1205251607Sdim                AddressingMode mode = bdaddr12only>
1206263509Sdim  : InstSI<opcode, (outs), (ins mode:$BD1, imm:$I2),
1207263509Sdim           mnemonic#"\t$BD1, $I2",
1208263509Sdim           [(operator (load mode:$BD1), imm:$I2)]> {
1209263509Sdim  let isCompare = 1;
1210251607Sdim  let mayLoad = 1;
1211251607Sdim}
1212251607Sdim
1213251607Sdimclass CompareSIL<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1214251607Sdim                 SDPatternOperator load, Immediate imm>
1215263509Sdim  : InstSIL<opcode, (outs), (ins bdaddr12only:$BD1, imm:$I2),
1216263509Sdim            mnemonic#"\t$BD1, $I2",
1217263509Sdim            [(operator (load bdaddr12only:$BD1), imm:$I2)]> {
1218263509Sdim  let isCompare = 1;
1219251607Sdim  let mayLoad = 1;
1220251607Sdim}
1221251607Sdim
1222251607Sdimclass CompareSIY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1223251607Sdim                 SDPatternOperator load, Immediate imm,
1224251607Sdim                 AddressingMode mode = bdaddr20only>
1225263509Sdim  : InstSIY<opcode, (outs), (ins mode:$BD1, imm:$I2),
1226263509Sdim            mnemonic#"\t$BD1, $I2",
1227263509Sdim            [(operator (load mode:$BD1), imm:$I2)]> {
1228263509Sdim  let isCompare = 1;
1229251607Sdim  let mayLoad = 1;
1230251607Sdim}
1231251607Sdim
1232251607Sdimmulticlass CompareSIPair<string mnemonic, bits<8> siOpcode, bits<16> siyOpcode,
1233251607Sdim                         SDPatternOperator operator, SDPatternOperator load,
1234251607Sdim                         Immediate imm> {
1235263509Sdim  let DispKey = mnemonic in {
1236263509Sdim    let DispSize = "12" in
1237251607Sdim      def "" : CompareSI<mnemonic, siOpcode, operator, load, imm, bdaddr12pair>;
1238263509Sdim    let DispSize = "20" in
1239251607Sdim      def Y  : CompareSIY<mnemonic#"y", siyOpcode, operator, load, imm,
1240251607Sdim                          bdaddr20pair>;
1241251607Sdim  }
1242251607Sdim}
1243251607Sdim
1244251607Sdimclass TernaryRRD<string mnemonic, bits<16> opcode,
1245251607Sdim                 SDPatternOperator operator, RegisterOperand cls>
1246263509Sdim  : InstRRD<opcode, (outs cls:$R1), (ins cls:$R1src, cls:$R3, cls:$R2),
1247263509Sdim            mnemonic#"r\t$R1, $R3, $R2",
1248263509Sdim            [(set cls:$R1, (operator cls:$R1src, cls:$R3, cls:$R2))]> {
1249263509Sdim  let OpKey = mnemonic ## cls;
1250263509Sdim  let OpType = "reg";
1251263509Sdim  let Constraints = "$R1 = $R1src";
1252263509Sdim  let DisableEncoding = "$R1src";
1253251607Sdim}
1254251607Sdim
1255251607Sdimclass TernaryRXF<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1256263509Sdim                 RegisterOperand cls, SDPatternOperator load, bits<5> bytes>
1257263509Sdim  : InstRXF<opcode, (outs cls:$R1),
1258263509Sdim            (ins cls:$R1src, cls:$R3, bdxaddr12only:$XBD2),
1259263509Sdim            mnemonic#"\t$R1, $R3, $XBD2",
1260263509Sdim            [(set cls:$R1, (operator cls:$R1src, cls:$R3,
1261263509Sdim                                     (load bdxaddr12only:$XBD2)))]> {
1262263509Sdim  let OpKey = mnemonic ## cls;
1263263509Sdim  let OpType = "mem";
1264263509Sdim  let Constraints = "$R1 = $R1src";
1265263509Sdim  let DisableEncoding = "$R1src";
1266251607Sdim  let mayLoad = 1;
1267263509Sdim  let AccessBytes = bytes;
1268251607Sdim}
1269251607Sdim
1270251607Sdimclass CmpSwapRS<string mnemonic, bits<8> opcode, SDPatternOperator operator,
1271251607Sdim                RegisterOperand cls, AddressingMode mode = bdaddr12only>
1272263509Sdim  : InstRS<opcode, (outs cls:$R1), (ins cls:$R1src, cls:$R3, mode:$BD2),
1273263509Sdim           mnemonic#"\t$R1, $R3, $BD2",
1274263509Sdim           [(set cls:$R1, (operator mode:$BD2, cls:$R1src, cls:$R3))]> {
1275263509Sdim  let Constraints = "$R1 = $R1src";
1276263509Sdim  let DisableEncoding = "$R1src";
1277251607Sdim  let mayLoad = 1;
1278251607Sdim  let mayStore = 1;
1279251607Sdim}
1280251607Sdim
1281251607Sdimclass CmpSwapRSY<string mnemonic, bits<16> opcode, SDPatternOperator operator,
1282251607Sdim                 RegisterOperand cls, AddressingMode mode = bdaddr20only>
1283263509Sdim  : InstRSY<opcode, (outs cls:$R1), (ins cls:$R1src, cls:$R3, mode:$BD2),
1284263509Sdim            mnemonic#"\t$R1, $R3, $BD2",
1285263509Sdim            [(set cls:$R1, (operator mode:$BD2, cls:$R1src, cls:$R3))]> {
1286263509Sdim  let Constraints = "$R1 = $R1src";
1287263509Sdim  let DisableEncoding = "$R1src";
1288251607Sdim  let mayLoad = 1;
1289251607Sdim  let mayStore = 1;
1290251607Sdim}
1291251607Sdim
1292251607Sdimmulticlass CmpSwapRSPair<string mnemonic, bits<8> rsOpcode, bits<16> rsyOpcode,
1293251607Sdim                         SDPatternOperator operator, RegisterOperand cls> {
1294263509Sdim  let DispKey = mnemonic ## #cls in {
1295263509Sdim    let DispSize = "12" in
1296251607Sdim      def "" : CmpSwapRS<mnemonic, rsOpcode, operator, cls, bdaddr12pair>;
1297263509Sdim    let DispSize = "20" in
1298251607Sdim      def Y  : CmpSwapRSY<mnemonic#"y", rsyOpcode, operator, cls, bdaddr20pair>;
1299251607Sdim  }
1300251607Sdim}
1301251607Sdim
1302251607Sdimclass RotateSelectRIEf<string mnemonic, bits<16> opcode, RegisterOperand cls1,
1303251607Sdim                       RegisterOperand cls2>
1304263509Sdim  : InstRIEf<opcode, (outs cls1:$R1),
1305263509Sdim             (ins cls1:$R1src, cls2:$R2, uimm8:$I3, uimm8:$I4, uimm8zx6:$I5),
1306263509Sdim             mnemonic#"\t$R1, $R2, $I3, $I4, $I5", []> {
1307263509Sdim  let Constraints = "$R1 = $R1src";
1308263509Sdim  let DisableEncoding = "$R1src";
1309251607Sdim}
1310251607Sdim
1311263509Sdimclass PrefetchRXY<string mnemonic, bits<16> opcode, SDPatternOperator operator>
1312263509Sdim  : InstRXY<opcode, (outs), (ins uimm8zx4:$R1, bdxaddr20only:$XBD2),
1313263509Sdim            mnemonic##"\t$R1, $XBD2",
1314263509Sdim            [(operator uimm8zx4:$R1, bdxaddr20only:$XBD2)]>;
1315263509Sdim
1316263509Sdimclass PrefetchRILPC<string mnemonic, bits<12> opcode,
1317263509Sdim                    SDPatternOperator operator>
1318263509Sdim  : InstRIL<opcode, (outs), (ins uimm8zx4:$R1, pcrel32:$I2),
1319263509Sdim            mnemonic##"\t$R1, $I2",
1320263509Sdim            [(operator uimm8zx4:$R1, pcrel32:$I2)]> {
1321263509Sdim  // We want PC-relative addresses to be tried ahead of BD and BDX addresses.
1322263509Sdim  // However, BDXs have two extra operands and are therefore 6 units more
1323263509Sdim  // complex.
1324263509Sdim  let AddedComplexity = 7;
1325263509Sdim}
1326263509Sdim
1327263509Sdim// A floating-point load-and test operation.  Create both a normal unary
1328263509Sdim// operation and one that acts as a comparison against zero.
1329263509Sdimmulticlass LoadAndTestRRE<string mnemonic, bits<16> opcode,
1330263509Sdim                          RegisterOperand cls> {
1331263509Sdim  def "" : UnaryRRE<mnemonic, opcode, null_frag, cls, cls>;
1332263509Sdim  let isCodeGenOnly = 1 in
1333263509Sdim    def Compare : CompareRRE<mnemonic, opcode, null_frag, cls, cls>;
1334263509Sdim}
1335263509Sdim
1336251607Sdim//===----------------------------------------------------------------------===//
1337251607Sdim// Pseudo instructions
1338251607Sdim//===----------------------------------------------------------------------===//
1339251607Sdim//
1340251607Sdim// Convenience instructions that get lowered to real instructions
1341251607Sdim// by either SystemZTargetLowering::EmitInstrWithCustomInserter()
1342251607Sdim// or SystemZInstrInfo::expandPostRAPseudo().
1343251607Sdim//
1344251607Sdim//===----------------------------------------------------------------------===//
1345251607Sdim
1346251607Sdimclass Pseudo<dag outs, dag ins, list<dag> pattern>
1347251607Sdim  : InstSystemZ<0, outs, ins, "", pattern> {
1348251607Sdim  let isPseudo = 1;
1349251607Sdim  let isCodeGenOnly = 1;
1350251607Sdim}
1351251607Sdim
1352263509Sdim// Like UnaryRI, but expanded after RA depending on the choice of register.
1353263509Sdimclass UnaryRIPseudo<SDPatternOperator operator, RegisterOperand cls,
1354263509Sdim                    Immediate imm>
1355263509Sdim  : Pseudo<(outs cls:$R1), (ins imm:$I2),
1356263509Sdim           [(set cls:$R1, (operator imm:$I2))]>;
1357263509Sdim
1358263509Sdim// Like UnaryRXY, but expanded after RA depending on the choice of register.
1359263509Sdimclass UnaryRXYPseudo<string key, SDPatternOperator operator,
1360263509Sdim                     RegisterOperand cls, bits<5> bytes,
1361263509Sdim                     AddressingMode mode = bdxaddr20only>
1362263509Sdim  : Pseudo<(outs cls:$R1), (ins mode:$XBD2),
1363263509Sdim           [(set cls:$R1, (operator mode:$XBD2))]> {
1364263509Sdim  let OpKey = key ## cls;
1365263509Sdim  let OpType = "mem";
1366263509Sdim  let mayLoad = 1;
1367263509Sdim  let Has20BitOffset = 1;
1368263509Sdim  let HasIndex = 1;
1369263509Sdim  let AccessBytes = bytes;
1370263509Sdim}
1371263509Sdim
1372263509Sdim// Like UnaryRR, but expanded after RA depending on the choice of registers.
1373263509Sdimclass UnaryRRPseudo<string key, SDPatternOperator operator,
1374263509Sdim                    RegisterOperand cls1, RegisterOperand cls2>
1375263509Sdim  : Pseudo<(outs cls1:$R1), (ins cls2:$R2),
1376263509Sdim           [(set cls1:$R1, (operator cls2:$R2))]> {
1377263509Sdim  let OpKey = key ## cls1;
1378263509Sdim  let OpType = "reg";
1379263509Sdim}
1380263509Sdim
1381263509Sdim// Like BinaryRI, but expanded after RA depending on the choice of register.
1382263509Sdimclass BinaryRIPseudo<SDPatternOperator operator, RegisterOperand cls,
1383263509Sdim                     Immediate imm>
1384263509Sdim  : Pseudo<(outs cls:$R1), (ins cls:$R1src, imm:$I2),
1385263509Sdim           [(set cls:$R1, (operator cls:$R1src, imm:$I2))]> {
1386263509Sdim  let Constraints = "$R1 = $R1src";
1387263509Sdim}
1388263509Sdim
1389263509Sdim// Like BinaryRIE, but expanded after RA depending on the choice of register.
1390263509Sdimclass BinaryRIEPseudo<SDPatternOperator operator, RegisterOperand cls,
1391263509Sdim                      Immediate imm>
1392263509Sdim  : Pseudo<(outs cls:$R1), (ins cls:$R3, imm:$I2),
1393263509Sdim           [(set cls:$R1, (operator cls:$R3, imm:$I2))]>;
1394263509Sdim
1395263509Sdim// Like BinaryRIAndK, but expanded after RA depending on the choice of register.
1396263509Sdimmulticlass BinaryRIAndKPseudo<string key, SDPatternOperator operator,
1397263509Sdim                              RegisterOperand cls, Immediate imm> {
1398263509Sdim  let NumOpsKey = key in {
1399263509Sdim    let NumOpsValue = "3" in
1400263509Sdim      def K : BinaryRIEPseudo<null_frag, cls, imm>,
1401263509Sdim              Requires<[FeatureHighWord, FeatureDistinctOps]>;
1402263509Sdim    let NumOpsValue = "2", isConvertibleToThreeAddress = 1 in
1403263509Sdim      def "" : BinaryRIPseudo<operator, cls, imm>,
1404263509Sdim               Requires<[FeatureHighWord]>;
1405263509Sdim  }
1406263509Sdim}
1407263509Sdim
1408263509Sdim// Like CompareRI, but expanded after RA depending on the choice of register.
1409263509Sdimclass CompareRIPseudo<SDPatternOperator operator, RegisterOperand cls,
1410263509Sdim                      Immediate imm>
1411263509Sdim  : Pseudo<(outs), (ins cls:$R1, imm:$I2), [(operator cls:$R1, imm:$I2)]>;
1412263509Sdim
1413263509Sdim// Like CompareRXY, but expanded after RA depending on the choice of register.
1414263509Sdimclass CompareRXYPseudo<SDPatternOperator operator, RegisterOperand cls,
1415263509Sdim                       SDPatternOperator load, bits<5> bytes,
1416263509Sdim                       AddressingMode mode = bdxaddr20only>
1417263509Sdim  : Pseudo<(outs), (ins cls:$R1, mode:$XBD2),
1418263509Sdim           [(operator cls:$R1, (load mode:$XBD2))]> {
1419263509Sdim  let mayLoad = 1;
1420263509Sdim  let Has20BitOffset = 1;
1421263509Sdim  let HasIndex = 1;
1422263509Sdim  let AccessBytes = bytes;
1423263509Sdim}
1424263509Sdim
1425263509Sdim// Like StoreRXY, but expanded after RA depending on the choice of register.
1426263509Sdimclass StoreRXYPseudo<SDPatternOperator operator, RegisterOperand cls,
1427263509Sdim                     bits<5> bytes, AddressingMode mode = bdxaddr20only>
1428263509Sdim  : Pseudo<(outs), (ins cls:$R1, mode:$XBD2),
1429263509Sdim           [(operator cls:$R1, mode:$XBD2)]> {
1430263509Sdim  let mayStore = 1;
1431263509Sdim  let Has20BitOffset = 1;
1432263509Sdim  let HasIndex = 1;
1433263509Sdim  let AccessBytes = bytes;
1434263509Sdim}
1435263509Sdim
1436263509Sdim// Like RotateSelectRIEf, but expanded after RA depending on the choice
1437263509Sdim// of registers.
1438263509Sdimclass RotateSelectRIEfPseudo<RegisterOperand cls1, RegisterOperand cls2>
1439263509Sdim  : Pseudo<(outs cls1:$R1),
1440263509Sdim           (ins cls1:$R1src, cls2:$R2, uimm8:$I3, uimm8:$I4, uimm8zx6:$I5),
1441263509Sdim           []> {
1442263509Sdim  let Constraints = "$R1 = $R1src";
1443263509Sdim  let DisableEncoding = "$R1src";
1444263509Sdim}
1445263509Sdim
1446251607Sdim// Implements "$dst = $cc & (8 >> CC) ? $src1 : $src2", where CC is
1447251607Sdim// the value of the PSW's 2-bit condition code field.
1448251607Sdimclass SelectWrapper<RegisterOperand cls>
1449263509Sdim  : Pseudo<(outs cls:$dst),
1450263509Sdim           (ins cls:$src1, cls:$src2, uimm8zx4:$valid, uimm8zx4:$cc),
1451263509Sdim           [(set cls:$dst, (z_select_ccmask cls:$src1, cls:$src2,
1452263509Sdim                                            uimm8zx4:$valid, uimm8zx4:$cc))]> {
1453251607Sdim  let usesCustomInserter = 1;
1454251607Sdim  // Although the instructions used by these nodes do not in themselves
1455263509Sdim  // change CC, the insertion requires new blocks, and CC cannot be live
1456263509Sdim  // across them.
1457263509Sdim  let Defs = [CC];
1458263509Sdim  let Uses = [CC];
1459251607Sdim}
1460251607Sdim
1461263509Sdim// Stores $new to $addr if $cc is true ("" case) or false (Inv case).
1462263509Sdimmulticlass CondStores<RegisterOperand cls, SDPatternOperator store,
1463263509Sdim                      SDPatternOperator load, AddressingMode mode> {
1464263509Sdim  let Defs = [CC], Uses = [CC], usesCustomInserter = 1 in {
1465263509Sdim    def "" : Pseudo<(outs),
1466263509Sdim                    (ins cls:$new, mode:$addr, uimm8zx4:$valid, uimm8zx4:$cc),
1467263509Sdim                    [(store (z_select_ccmask cls:$new, (load mode:$addr),
1468263509Sdim                                             uimm8zx4:$valid, uimm8zx4:$cc),
1469263509Sdim                            mode:$addr)]>;
1470263509Sdim    def Inv : Pseudo<(outs),
1471263509Sdim                     (ins cls:$new, mode:$addr, uimm8zx4:$valid, uimm8zx4:$cc),
1472263509Sdim                     [(store (z_select_ccmask (load mode:$addr), cls:$new,
1473263509Sdim                                              uimm8zx4:$valid, uimm8zx4:$cc),
1474263509Sdim                              mode:$addr)]>;
1475263509Sdim  }
1476263509Sdim}
1477263509Sdim
1478251607Sdim// OPERATOR is ATOMIC_SWAP or an ATOMIC_LOAD_* operation.  PAT and OPERAND
1479251607Sdim// describe the second (non-memory) operand.
1480251607Sdimclass AtomicLoadBinary<SDPatternOperator operator, RegisterOperand cls,
1481251607Sdim                       dag pat, DAGOperand operand>
1482251607Sdim  : Pseudo<(outs cls:$dst), (ins bdaddr20only:$ptr, operand:$src2),
1483251607Sdim           [(set cls:$dst, (operator bdaddr20only:$ptr, pat))]> {
1484263509Sdim  let Defs = [CC];
1485251607Sdim  let Has20BitOffset = 1;
1486251607Sdim  let mayLoad = 1;
1487251607Sdim  let mayStore = 1;
1488251607Sdim  let usesCustomInserter = 1;
1489251607Sdim}
1490251607Sdim
1491251607Sdim// Specializations of AtomicLoadWBinary.
1492251607Sdimclass AtomicLoadBinaryReg32<SDPatternOperator operator>
1493251607Sdim  : AtomicLoadBinary<operator, GR32, (i32 GR32:$src2), GR32>;
1494251607Sdimclass AtomicLoadBinaryImm32<SDPatternOperator operator, Immediate imm>
1495251607Sdim  : AtomicLoadBinary<operator, GR32, (i32 imm:$src2), imm>;
1496251607Sdimclass AtomicLoadBinaryReg64<SDPatternOperator operator>
1497251607Sdim  : AtomicLoadBinary<operator, GR64, (i64 GR64:$src2), GR64>;
1498251607Sdimclass AtomicLoadBinaryImm64<SDPatternOperator operator, Immediate imm>
1499251607Sdim  : AtomicLoadBinary<operator, GR64, (i64 imm:$src2), imm>;
1500251607Sdim
1501251607Sdim// OPERATOR is ATOMIC_SWAPW or an ATOMIC_LOADW_* operation.  PAT and OPERAND
1502251607Sdim// describe the second (non-memory) operand.
1503251607Sdimclass AtomicLoadWBinary<SDPatternOperator operator, dag pat,
1504251607Sdim                        DAGOperand operand>
1505251607Sdim  : Pseudo<(outs GR32:$dst),
1506251607Sdim           (ins bdaddr20only:$ptr, operand:$src2, ADDR32:$bitshift,
1507251607Sdim                ADDR32:$negbitshift, uimm32:$bitsize),
1508251607Sdim           [(set GR32:$dst, (operator bdaddr20only:$ptr, pat, ADDR32:$bitshift,
1509251607Sdim                                      ADDR32:$negbitshift, uimm32:$bitsize))]> {
1510263509Sdim  let Defs = [CC];
1511251607Sdim  let Has20BitOffset = 1;
1512251607Sdim  let mayLoad = 1;
1513251607Sdim  let mayStore = 1;
1514251607Sdim  let usesCustomInserter = 1;
1515251607Sdim}
1516251607Sdim
1517251607Sdim// Specializations of AtomicLoadWBinary.
1518251607Sdimclass AtomicLoadWBinaryReg<SDPatternOperator operator>
1519251607Sdim  : AtomicLoadWBinary<operator, (i32 GR32:$src2), GR32>;
1520251607Sdimclass AtomicLoadWBinaryImm<SDPatternOperator operator, Immediate imm>
1521251607Sdim  : AtomicLoadWBinary<operator, (i32 imm:$src2), imm>;
1522263509Sdim
1523263509Sdim// Define an instruction that operates on two fixed-length blocks of memory,
1524263509Sdim// and associated pseudo instructions for operating on blocks of any size.
1525263509Sdim// The Sequence form uses a straight-line sequence of instructions and
1526263509Sdim// the Loop form uses a loop of length-256 instructions followed by
1527263509Sdim// another instruction to handle the excess.
1528263509Sdimmulticlass MemorySS<string mnemonic, bits<8> opcode,
1529263509Sdim                    SDPatternOperator sequence, SDPatternOperator loop> {
1530263509Sdim  def "" : InstSS<opcode, (outs), (ins bdladdr12onlylen8:$BDL1,
1531263509Sdim                                       bdaddr12only:$BD2),
1532263509Sdim                  mnemonic##"\t$BDL1, $BD2", []>;
1533263509Sdim  let usesCustomInserter = 1 in {
1534263509Sdim    def Sequence : Pseudo<(outs), (ins bdaddr12only:$dest, bdaddr12only:$src,
1535263509Sdim                                       imm64:$length),
1536263509Sdim                           [(sequence bdaddr12only:$dest, bdaddr12only:$src,
1537263509Sdim                                      imm64:$length)]>;
1538263509Sdim    def Loop : Pseudo<(outs), (ins bdaddr12only:$dest, bdaddr12only:$src,
1539263509Sdim                                   imm64:$length, GR64:$count256),
1540263509Sdim                      [(loop bdaddr12only:$dest, bdaddr12only:$src,
1541263509Sdim                             imm64:$length, GR64:$count256)]>;
1542263509Sdim  }
1543263509Sdim}
1544263509Sdim
1545263509Sdim// Define an instruction that operates on two strings, both terminated
1546263509Sdim// by the character in R0.  The instruction processes a CPU-determinated
1547263509Sdim// number of bytes at a time and sets CC to 3 if the instruction needs
1548263509Sdim// to be repeated.  Also define a pseudo instruction that represents
1549263509Sdim// the full loop (the main instruction plus the branch on CC==3).
1550263509Sdimmulticlass StringRRE<string mnemonic, bits<16> opcode,
1551263509Sdim                     SDPatternOperator operator> {
1552263509Sdim  def "" : InstRRE<opcode, (outs GR64:$R1, GR64:$R2),
1553263509Sdim                   (ins GR64:$R1src, GR64:$R2src),
1554263509Sdim                   mnemonic#"\t$R1, $R2", []> {
1555263509Sdim    let Constraints = "$R1 = $R1src, $R2 = $R2src";
1556263509Sdim    let DisableEncoding = "$R1src, $R2src";
1557263509Sdim  }
1558263509Sdim  let usesCustomInserter = 1 in
1559263509Sdim    def Loop : Pseudo<(outs GR64:$end),
1560263509Sdim                      (ins GR64:$start1, GR64:$start2, GR32:$char),
1561263509Sdim                      [(set GR64:$end, (operator GR64:$start1, GR64:$start2,
1562263509Sdim                                                 GR32:$char))]>;
1563263509Sdim}
1564263509Sdim
1565263509Sdim// A pseudo instruction that is a direct alias of a real instruction.
1566263509Sdim// These aliases are used in cases where a particular register operand is
1567263509Sdim// fixed or where the same instruction is used with different register sizes.
1568263509Sdim// The size parameter is the size in bytes of the associated real instruction.
1569263509Sdimclass Alias<int size, dag outs, dag ins, list<dag> pattern>
1570263509Sdim  : InstSystemZ<size, outs, ins, "", pattern> {
1571263509Sdim  let isPseudo = 1;
1572263509Sdim  let isCodeGenOnly = 1;
1573263509Sdim}
1574263509Sdim
1575263509Sdim// An alias of a BinaryRI, but with different register sizes.
1576263509Sdimclass BinaryAliasRI<SDPatternOperator operator, RegisterOperand cls,
1577263509Sdim                    Immediate imm>
1578263509Sdim  : Alias<4, (outs cls:$R1), (ins cls:$R1src, imm:$I2),
1579263509Sdim          [(set cls:$R1, (operator cls:$R1src, imm:$I2))]> {
1580263509Sdim  let Constraints = "$R1 = $R1src";
1581263509Sdim}
1582263509Sdim
1583263509Sdim// An alias of a BinaryRIL, but with different register sizes.
1584263509Sdimclass BinaryAliasRIL<SDPatternOperator operator, RegisterOperand cls,
1585263509Sdim                     Immediate imm>
1586263509Sdim  : Alias<6, (outs cls:$R1), (ins cls:$R1src, imm:$I2),
1587263509Sdim          [(set cls:$R1, (operator cls:$R1src, imm:$I2))]> {
1588263509Sdim  let Constraints = "$R1 = $R1src";
1589263509Sdim}
1590263509Sdim
1591263509Sdim// An alias of a CompareRI, but with different register sizes.
1592263509Sdimclass CompareAliasRI<SDPatternOperator operator, RegisterOperand cls,
1593263509Sdim                     Immediate imm>
1594263509Sdim  : Alias<4, (outs), (ins cls:$R1, imm:$I2), [(operator cls:$R1, imm:$I2)]> {
1595263509Sdim  let isCompare = 1;
1596263509Sdim}
1597263509Sdim
1598263509Sdim// An alias of a RotateSelectRIEf, but with different register sizes.
1599263509Sdimclass RotateSelectAliasRIEf<RegisterOperand cls1, RegisterOperand cls2>
1600263509Sdim  : Alias<6, (outs cls1:$R1),
1601263509Sdim          (ins cls1:$R1src, cls2:$R2, uimm8:$I3, uimm8:$I4, uimm8zx6:$I5), []> {
1602263509Sdim  let Constraints = "$R1 = $R1src";
1603263509Sdim}
1604