1//===-- VEInstrInfo.td - Target Description for VE Target -----------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file describes the VE instructions in TableGen format.
10//
11//===----------------------------------------------------------------------===//
12
13//===----------------------------------------------------------------------===//
14// Instruction format superclass
15//===----------------------------------------------------------------------===//
16
17include "VEInstrFormats.td"
18
19//===----------------------------------------------------------------------===//
20// Helper functions to retrieve target constants.
21//
22// VE instructions have a space to hold following immediates
23//   $sy has 7 bits to represent simm7, uimm7, simm7fp, or uimm7fp.
24//   $sz also has 7 bits to represent mimm or mimmfp.
25//   $disp has 32 bits to represent simm32.
26//
27// The mimm is a special immediate value of sequential bit stream of 0 or 1.
28//     `(m)0`: Represents 0 sequence then 1 sequence like 0b00...0011...11,
29//             where `m` is equal to the number of leading zeros.
30//     `(m)1`: Represents 1 sequence then 0 sequence like 0b11...1100...00,
31//             where `m` is equal to the number of leading ones.
32// Each bit of mimm's 7 bits is used like below:
33//     bit 6  : If `(m)0`, this bit is 1.  Otherwise, this bit is 0.
34//     bit 5-0: Represents the m (0-63).
35// Use `!add(m, 64)` to generates an immediate value in pattern matchings.
36//
37// The floating point immediate value is not something like compacted value.
38// It is simple integer representation, so it works rarely.
39//     e.g. 0.0 (0x00000000) or -2.0 (0xC0000000=(2)1).
40//===----------------------------------------------------------------------===//
41
42def ULO7 : SDNodeXForm<imm, [{
43  return CurDAG->getTargetConstant(N->getZExtValue() & 0x7f,
44                                   SDLoc(N), MVT::i32);
45}]>;
46def LO7 : SDNodeXForm<imm, [{
47  return CurDAG->getTargetConstant(SignExtend32(N->getSExtValue(), 7),
48                                   SDLoc(N), MVT::i32);
49}]>;
50def MIMM : SDNodeXForm<imm, [{
51  return CurDAG->getTargetConstant(convMImmVal(getImmVal(N)),
52                                   SDLoc(N), MVT::i32);
53}]>;
54def LO32 : SDNodeXForm<imm, [{
55  return CurDAG->getTargetConstant(Lo_32(N->getZExtValue()),
56                                   SDLoc(N), MVT::i32);
57}]>;
58def HI32 : SDNodeXForm<imm, [{
59  // Transformation function: shift the immediate value down into the low bits.
60  return CurDAG->getTargetConstant(Hi_32(N->getZExtValue()),
61                                   SDLoc(N), MVT::i32);
62}]>;
63
64def LO7FP : SDNodeXForm<fpimm, [{
65  uint64_t Val = getFpImmVal(N);
66  return CurDAG->getTargetConstant(SignExtend32(Val, 7), SDLoc(N), MVT::i32);
67}]>;
68def MIMMFP : SDNodeXForm<fpimm, [{
69  return CurDAG->getTargetConstant(convMImmVal(getFpImmVal(N)),
70                                   SDLoc(N), MVT::i32);
71}]>;
72def LOFP32 : SDNodeXForm<fpimm, [{
73  return CurDAG->getTargetConstant(Lo_32(getFpImmVal(N) & 0xffffffff),
74                                   SDLoc(N), MVT::i32);
75}]>;
76def HIFP32 : SDNodeXForm<fpimm, [{
77  return CurDAG->getTargetConstant(Hi_32(getFpImmVal(N)), SDLoc(N), MVT::i32);
78}]>;
79
80def icond2cc : SDNodeXForm<cond, [{
81  VECC::CondCode VECC = intCondCode2Icc(N->get());
82  return CurDAG->getTargetConstant(VECC, SDLoc(N), MVT::i32);
83}]>;
84
85def icond2ccSwap : SDNodeXForm<cond, [{
86  ISD::CondCode CC = getSetCCSwappedOperands(N->get());
87  VECC::CondCode VECC = intCondCode2Icc(CC);
88  return CurDAG->getTargetConstant(VECC, SDLoc(N), MVT::i32);
89}]>;
90
91def fcond2cc : SDNodeXForm<cond, [{
92  VECC::CondCode VECC = fpCondCode2Fcc(N->get());
93  return CurDAG->getTargetConstant(VECC, SDLoc(N), MVT::i32);
94}]>;
95
96def fcond2ccSwap : SDNodeXForm<cond, [{
97  ISD::CondCode CC = getSetCCSwappedOperands(N->get());
98  VECC::CondCode VECC = fpCondCode2Fcc(CC);
99  return CurDAG->getTargetConstant(VECC, SDLoc(N), MVT::i32);
100}]>;
101
102def CCOP : SDNodeXForm<imm, [{
103  return CurDAG->getTargetConstant(N->getZExtValue(),
104                                   SDLoc(N), MVT::i32);
105}]>;
106
107//===----------------------------------------------------------------------===//
108// Feature predicates.
109//===----------------------------------------------------------------------===//
110
111//===----------------------------------------------------------------------===//
112// Instruction Pattern Stuff
113//===----------------------------------------------------------------------===//
114
115// zero
116def ZeroAsmOperand : AsmOperandClass {
117  let Name = "Zero";
118}
119def zero : Operand<i32>, PatLeaf<(imm), [{
120    return N->getSExtValue() == 0; }]> {
121  let ParserMatchClass = ZeroAsmOperand;
122}
123
124// uimm0to2 - Special immediate value represents 0, 1, and 2.
125def UImm0to2AsmOperand : AsmOperandClass {
126  let Name = "UImm0to2";
127}
128def uimm0to2 : Operand<i32>, PatLeaf<(imm), [{
129    return N->getZExtValue() < 3; }], ULO7> {
130  let ParserMatchClass = UImm0to2AsmOperand;
131}
132
133// uimm1 - Generic immediate value.
134def UImm1AsmOperand : AsmOperandClass {
135  let Name = "UImm1";
136}
137def uimm1 : Operand<i32>, PatLeaf<(imm), [{
138    return isUInt<1>(N->getZExtValue()); }], ULO7> {
139  let ParserMatchClass = UImm1AsmOperand;
140}
141
142// uimm2 - Generic immediate value.
143def UImm2AsmOperand : AsmOperandClass {
144  let Name = "UImm2";
145}
146def uimm2 : Operand<i32>, PatLeaf<(imm), [{
147    return isUInt<2>(N->getZExtValue()); }], ULO7> {
148  let ParserMatchClass = UImm2AsmOperand;
149}
150
151// uimm3 - Generic immediate value.
152def UImm3AsmOperand : AsmOperandClass {
153  let Name = "UImm3";
154}
155def uimm3 : Operand<i32>, PatLeaf<(imm), [{
156    return isUInt<3>(N->getZExtValue()); }], ULO7> {
157  let ParserMatchClass = UImm3AsmOperand;
158}
159
160// uimm6 - Generic immediate value.
161def UImm6AsmOperand : AsmOperandClass {
162  let Name = "UImm6";
163}
164def uimm6 : Operand<i32>, PatLeaf<(imm), [{
165    return isUInt<6>(N->getZExtValue()); }], ULO7> {
166  let ParserMatchClass = UImm6AsmOperand;
167}
168
169// uimm7 - Generic immediate value.
170def UImm7AsmOperand : AsmOperandClass {
171  let Name = "UImm7";
172}
173def uimm7 : Operand<i32>, PatLeaf<(imm), [{
174    return isUInt<7>(N->getZExtValue()); }], ULO7> {
175  let ParserMatchClass = UImm7AsmOperand;
176}
177
178// simm7 - Generic immediate value.
179def SImm7AsmOperand : AsmOperandClass {
180  let Name = "SImm7";
181}
182def simm7 : Operand<i32>, PatLeaf<(imm), [{
183    return isInt<7>(N->getSExtValue()); }], LO7> {
184  let ParserMatchClass = SImm7AsmOperand;
185  let DecoderMethod = "DecodeSIMM7";
186}
187
188// mimm - Special immediate value of sequential bit stream of 0 or 1.
189def MImmAsmOperand : AsmOperandClass {
190  let Name = "MImm";
191  let ParserMethod = "parseMImmOperand";
192}
193def mimm : Operand<i32>, PatLeaf<(imm), [{
194    return isMImmVal(getImmVal(N)); }], MIMM> {
195  let ParserMatchClass = MImmAsmOperand;
196  let PrintMethod = "printMImmOperand";
197}
198
199// simm7fp - Generic fp immediate value.
200def simm7fp : Operand<i32>, PatLeaf<(fpimm), [{
201    return isInt<7>(getFpImmVal(N));
202  }], LO7FP> {
203  let ParserMatchClass = SImm7AsmOperand;
204  let DecoderMethod = "DecodeSIMM7";
205}
206
207// mimmfp - Special fp immediate value of sequential bit stream of 0 or 1.
208def mimmfp : Operand<i32>, PatLeaf<(fpimm), [{
209    return isMImmVal(getFpImmVal(N)); }], MIMMFP> {
210  let ParserMatchClass = MImmAsmOperand;
211  let PrintMethod = "printMImmOperand";
212}
213
214// mimmfp32 - 32 bit width mimmfp
215//   Float value places at higher bits, so ignore lower 32 bits.
216def mimmfp32 : Operand<i32>, PatLeaf<(fpimm), [{
217    return isMImm32Val(getFpImmVal(N) >> 32); }], MIMMFP> {
218  let ParserMatchClass = MImmAsmOperand;
219  let PrintMethod = "printMImmOperand";
220}
221
222// other generic patterns to use in pattern matchings
223def simm32      : PatLeaf<(imm), [{ return isInt<32>(N->getSExtValue()); }]>;
224def uimm32      : PatLeaf<(imm), [{ return isUInt<32>(N->getZExtValue()); }]>;
225def lomsbzero   : PatLeaf<(imm), [{ return (N->getZExtValue() & 0x80000000)
226                                      == 0; }]>;
227def lozero      : PatLeaf<(imm), [{ return (N->getZExtValue() & 0xffffffff)
228                                      == 0; }]>;
229def fplomsbzero : PatLeaf<(fpimm), [{ return (getFpImmVal(N) & 0x80000000)
230                                        == 0; }]>;
231def fplozero    : PatLeaf<(fpimm), [{ return (getFpImmVal(N) & 0xffffffff)
232                                        == 0; }]>;
233
234def CCSIOp : PatLeaf<(cond), [{
235  switch (N->get()) {
236  default:          return true;
237  case ISD::SETULT:
238  case ISD::SETULE:
239  case ISD::SETUGT:
240  case ISD::SETUGE: return false;
241  }
242}]>;
243
244def CCUIOp : PatLeaf<(cond), [{
245  switch (N->get()) {
246  default:         return true;
247  case ISD::SETLT:
248  case ISD::SETLE:
249  case ISD::SETGT:
250  case ISD::SETGE: return false;
251  }
252}]>;
253
254//===----------------------------------------------------------------------===//
255// Addressing modes.
256// SX-Aurora has following fields.
257//    sz: register or 0
258//    sy: register or immediate (-64 to 63)
259//    disp: immediate (-2147483648 to 2147483647)
260//
261// There are two kinds of instruction.
262//    ASX format uses sz + sy + disp.
263//    AS format uses sz + disp.
264//
265// Moreover, there are four kinds of assembly instruction format.
266//    ASX format uses "disp", "disp(, sz)", "disp(sy)", "disp(sy, sz)",
267//    "(, sz)", "(sy)", or "(sy, sz)".
268//    AS format uses "disp", "disp(, sz)", or "(, sz)" in general.
269//    AS format in RRM format uses "disp", "disp(sz)", or "(sz)".
270//    AS format in RRM format for host memory access uses "sz", "(sz)",
271//    or "disp(sz)".
272//
273// We defined them below.
274//
275// ASX format:
276//    MEMrri, MEMrii, MEMzri, MEMzii
277// AS format:
278//    MEMriASX, MEMziASX    : simple AS format
279//    MEMriRRM, MEMziRRM    : AS format in RRM format
280//    MEMriHM, MEMziHM      : AS format in RRM format for host memory access
281//===----------------------------------------------------------------------===//
282
283// DAG selections for both ASX and AS formats.
284def ADDRrri : ComplexPattern<iPTR, 3, "selectADDRrri", [frameindex], []>;
285def ADDRrii : ComplexPattern<iPTR, 3, "selectADDRrii", [frameindex], []>;
286def ADDRzri : ComplexPattern<iPTR, 3, "selectADDRzri", [], []>;
287def ADDRzii : ComplexPattern<iPTR, 3, "selectADDRzii", [], []>;
288def ADDRri : ComplexPattern<iPTR, 2, "selectADDRri", [frameindex], []>;
289def ADDRzi : ComplexPattern<iPTR, 2, "selectADDRzi", [], []>;
290
291// ASX format.
292def VEMEMrriAsmOperand : AsmOperandClass {
293  let Name = "MEMrri";
294  let ParserMethod = "parseMEMOperand";
295}
296def VEMEMriiAsmOperand : AsmOperandClass {
297  let Name = "MEMrii";
298  let ParserMethod = "parseMEMOperand";
299}
300def VEMEMzriAsmOperand : AsmOperandClass {
301  let Name = "MEMzri";
302  let ParserMethod = "parseMEMOperand";
303}
304def VEMEMziiAsmOperand : AsmOperandClass {
305  let Name = "MEMzii";
306  let ParserMethod = "parseMEMOperand";
307}
308
309// ASX format uses single assembly instruction format.
310def MEMrri : Operand<iPTR> {
311  let PrintMethod = "printMemASXOperand";
312  let MIOperandInfo = (ops ptr_rc, ptr_rc, i32imm);
313  let ParserMatchClass = VEMEMrriAsmOperand;
314}
315def MEMrii : Operand<iPTR> {
316  let PrintMethod = "printMemASXOperand";
317  let MIOperandInfo = (ops ptr_rc, i32imm, i32imm);
318  let ParserMatchClass = VEMEMriiAsmOperand;
319}
320def MEMzri : Operand<iPTR> {
321  let PrintMethod = "printMemASXOperand";
322  let MIOperandInfo = (ops i32imm /* = 0 */, ptr_rc, i32imm);
323  let ParserMatchClass = VEMEMzriAsmOperand;
324}
325def MEMzii : Operand<iPTR> {
326  let PrintMethod = "printMemASXOperand";
327  let MIOperandInfo = (ops i32imm /* = 0 */, i32imm, i32imm);
328  let ParserMatchClass = VEMEMziiAsmOperand;
329}
330
331// AS format.
332def VEMEMriAsmOperand : AsmOperandClass {
333  let Name = "MEMri";
334  let ParserMethod = "parseMEMAsOperand";
335}
336def VEMEMziAsmOperand : AsmOperandClass {
337  let Name = "MEMzi";
338  let ParserMethod = "parseMEMAsOperand";
339}
340
341// AS format uses multiple assembly instruction formats
342//   1. AS generic assembly instruction format:
343def MEMriASX : Operand<iPTR> {
344  let PrintMethod = "printMemASOperandASX";
345  let MIOperandInfo = (ops ptr_rc, i32imm);
346  let ParserMatchClass = VEMEMriAsmOperand;
347}
348def MEMziASX : Operand<iPTR> {
349  let PrintMethod = "printMemASOperandASX";
350  let MIOperandInfo = (ops i32imm /* = 0 */, i32imm);
351  let ParserMatchClass = VEMEMziAsmOperand;
352}
353
354//   2. AS RRM style assembly instruction format:
355def MEMriRRM : Operand<iPTR> {
356  let PrintMethod = "printMemASOperandRRM";
357  let MIOperandInfo = (ops ptr_rc, i32imm);
358  let ParserMatchClass = VEMEMriAsmOperand;
359}
360def MEMziRRM : Operand<iPTR> {
361  let PrintMethod = "printMemASOperandRRM";
362  let MIOperandInfo = (ops i32imm /* = 0 */, i32imm);
363  let ParserMatchClass = VEMEMziAsmOperand;
364}
365
366//   3. AS HM style assembly instruction format:
367def MEMriHM : Operand<iPTR> {
368  let PrintMethod = "printMemASOperandHM";
369  let MIOperandInfo = (ops ptr_rc, i32imm);
370  let ParserMatchClass = VEMEMriAsmOperand;
371}
372def MEMziHM : Operand<iPTR> {
373  let PrintMethod = "printMemASOperandHM";
374  let MIOperandInfo = (ops i32imm /* = 0 */, i32imm);
375  let ParserMatchClass = VEMEMziAsmOperand;
376}
377
378//===----------------------------------------------------------------------===//
379// Other operands.
380//===----------------------------------------------------------------------===//
381
382// Branch targets have OtherVT type.
383def brtarget32 : Operand<OtherVT> {
384  let EncoderMethod = "getBranchTargetOpValue";
385  let DecoderMethod = "DecodeSIMM32";
386}
387
388// Operand for printing out a condition code.
389def CCOpAsmOperand : AsmOperandClass { let Name = "CCOp"; }
390def CCOp : Operand<i32>, ImmLeaf<i32, [{
391    return Imm >= 0 && Imm < 22; }], CCOP> {
392  let PrintMethod = "printCCOperand";
393  let DecoderMethod = "DecodeCCOperand";
394  let EncoderMethod = "getCCOpValue";
395  let ParserMatchClass = CCOpAsmOperand;
396}
397
398// Operand for a rounding mode code.
399def RDOpAsmOperand : AsmOperandClass {
400  let Name = "RDOp";
401}
402def RDOp : Operand<i32> {
403  let PrintMethod = "printRDOperand";
404  let DecoderMethod = "DecodeRDOperand";
405  let EncoderMethod = "getRDOpValue";
406  let ParserMatchClass = RDOpAsmOperand;
407}
408
409def VEhi    : SDNode<"VEISD::Hi", SDTIntUnaryOp>;
410def VElo    : SDNode<"VEISD::Lo", SDTIntUnaryOp>;
411
412//  These are target-independent nodes, but have target-specific formats.
413def SDT_SPCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i64>,
414                                          SDTCisVT<1, i64> ]>;
415def SDT_SPCallSeqEnd   : SDCallSeqEnd<[ SDTCisVT<0, i64>,
416                                        SDTCisVT<1, i64> ]>;
417
418def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SPCallSeqStart,
419                           [SDNPHasChain, SDNPOutGlue]>;
420def callseq_end   : SDNode<"ISD::CALLSEQ_END",   SDT_SPCallSeqEnd,
421                           [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
422
423def SDT_SPCall    : SDTypeProfile<0, -1, [SDTCisVT<0, i64>]>;
424def call          : SDNode<"VEISD::CALL", SDT_SPCall,
425                           [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
426                            SDNPVariadic]>;
427
428def retflag       : SDNode<"VEISD::RET_FLAG", SDTNone,
429                           [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
430
431def getGOT        : Operand<iPTR>;
432
433// GETFUNPLT for PIC
434def GetFunPLT : SDNode<"VEISD::GETFUNPLT", SDTIntUnaryOp>;
435
436// GETTLSADDR for TLS
437def GetTLSAddr : SDNode<"VEISD::GETTLSADDR", SDT_SPCall,
438                        [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
439                         SDNPVariadic]>;
440
441// GETSTACKTOP
442def GetStackTop : SDNode<"VEISD::GETSTACKTOP", SDTNone,
443                        [SDNPHasChain, SDNPSideEffect]>;
444
445
446//===----------------------------------------------------------------------===//
447// VE Flag Conditions
448//===----------------------------------------------------------------------===//
449
450// Note that these values must be kept in sync with the CCOp::CondCode enum
451// values.
452class CC_VAL<int N> : PatLeaf<(i32 N)>;
453def CC_IG    : CC_VAL< 0>;  // Greater
454def CC_IL    : CC_VAL< 1>;  // Less
455def CC_INE   : CC_VAL< 2>;  // Not Equal
456def CC_IEQ   : CC_VAL< 3>;  // Equal
457def CC_IGE   : CC_VAL< 4>;  // Greater or Equal
458def CC_ILE   : CC_VAL< 5>;  // Less or Equal
459def CC_AF    : CC_VAL< 6>;  // Always false
460def CC_G     : CC_VAL< 7>;  // Greater
461def CC_L     : CC_VAL< 8>;  // Less
462def CC_NE    : CC_VAL< 9>;  // Not Equal
463def CC_EQ    : CC_VAL<10>;  // Equal
464def CC_GE    : CC_VAL<11>;  // Greater or Equal
465def CC_LE    : CC_VAL<12>;  // Less or Equal
466def CC_NUM   : CC_VAL<13>;  // Number
467def CC_NAN   : CC_VAL<14>;  // NaN
468def CC_GNAN  : CC_VAL<15>;  // Greater or NaN
469def CC_LNAN  : CC_VAL<16>;  // Less or NaN
470def CC_NENAN : CC_VAL<17>;  // Not Equal or NaN
471def CC_EQNAN : CC_VAL<18>;  // Equal or NaN
472def CC_GENAN : CC_VAL<19>;  // Greater or Equal or NaN
473def CC_LENAN : CC_VAL<20>;  // Less or Equal or NaN
474def CC_AT    : CC_VAL<21>;  // Always true
475
476//===----------------------------------------------------------------------===//
477// VE Rounding Mode
478//===----------------------------------------------------------------------===//
479
480// Note that these values must be kept in sync with the VERD::RoundingMode enum
481// values.
482class RD_VAL<int N> : PatLeaf<(i32 N)>;
483def RD_NONE  : RD_VAL< 0>;  // According to PSW
484def RD_RZ    : RD_VAL< 8>;  // Round toward Zero
485def RD_RP    : RD_VAL< 9>;  // Round toward Plus infinity
486def RD_RM    : RD_VAL<10>;  // Round toward Minus infinity
487def RD_RN    : RD_VAL<11>;  // Round to Nearest (ties to Even)
488def RD_RA    : RD_VAL<12>;  // Round to Nearest (ties to Away)
489
490//===----------------------------------------------------------------------===//
491// VE Multiclasses for common instruction formats
492//===----------------------------------------------------------------------===//
493
494// Multiclass for generic RR type instructions
495let hasSideEffects = 0 in
496multiclass RRbm<string opcStr, bits<8>opc,
497                RegisterClass RCo, ValueType Tyo,
498                RegisterClass RCi, ValueType Tyi,
499                SDPatternOperator OpNode = null_frag,
500                Operand immOp = simm7, Operand mOp = mimm> {
501  def rr : RR<opc, (outs RCo:$sx), (ins RCi:$sy, RCi:$sz),
502              !strconcat(opcStr, " $sx, $sy, $sz"),
503              [(set Tyo:$sx, (OpNode Tyi:$sy, Tyi:$sz))]>;
504  // VE calculates (OpNode $sy, $sz), but llvm requires to have immediate
505  // in RHS, so we use following definition.
506  let cy = 0 in
507  def ri : RR<opc, (outs RCo:$sx), (ins RCi:$sz, immOp:$sy),
508              !strconcat(opcStr, " $sx, $sy, $sz"),
509              [(set Tyo:$sx, (OpNode Tyi:$sz, (Tyi immOp:$sy)))]>;
510  let cz = 0 in
511  def rm : RR<opc, (outs RCo:$sx), (ins RCi:$sy, mOp:$sz),
512              !strconcat(opcStr, " $sx, $sy, $sz"),
513              [(set Tyo:$sx, (OpNode Tyi:$sy, (Tyi mOp:$sz)))]>;
514  let cy = 0, cz = 0 in
515  def im : RR<opc, (outs RCo:$sx), (ins immOp:$sy, mOp:$sz),
516              !strconcat(opcStr, " $sx, $sy, $sz"),
517              [(set Tyo:$sx, (OpNode (Tyi immOp:$sy), (Tyi mOp:$sz)))]>;
518}
519
520// Multiclass for non-commutative RR type instructions
521let hasSideEffects = 0 in
522multiclass RRNCbm<string opcStr, bits<8>opc,
523                RegisterClass RCo, ValueType Tyo,
524                RegisterClass RCi, ValueType Tyi,
525                SDPatternOperator OpNode = null_frag,
526                Operand immOp = simm7, Operand mOp = mimm> {
527  def rr : RR<opc, (outs RCo:$sx), (ins RCi:$sy, RCi:$sz),
528              !strconcat(opcStr, " $sx, $sy, $sz"),
529              [(set Tyo:$sx, (OpNode Tyi:$sy, Tyi:$sz))]>;
530  let cy = 0 in
531  def ir : RR<opc, (outs RCo:$sx), (ins immOp:$sy, RCi:$sz),
532              !strconcat(opcStr, " $sx, $sy, $sz"),
533              [(set Tyo:$sx, (OpNode (Tyi immOp:$sy), Tyi:$sz))]>;
534  let cz = 0 in
535  def rm : RR<opc, (outs RCo:$sx), (ins RCi:$sy, mOp:$sz),
536              !strconcat(opcStr, " $sx, $sy, $sz"),
537              [(set Tyo:$sx, (OpNode Tyi:$sy, (Tyi mOp:$sz)))]>;
538  let cy = 0, cz = 0 in
539  def im : RR<opc, (outs RCo:$sx), (ins immOp:$sy, mOp:$sz),
540              !strconcat(opcStr, " $sx, $sy, $sz"),
541              [(set Tyo:$sx, (OpNode (Tyi immOp:$sy), (Tyi mOp:$sz)))]>;
542}
543
544// Generic RR multiclass with 2 arguments.
545//   e.g. ADDUL, ADDSWSX, ADDSWZX, and etc.
546multiclass RRm<string opcStr, bits<8>opc,
547               RegisterClass RC, ValueType Ty,
548               SDPatternOperator OpNode = null_frag,
549               Operand immOp = simm7, Operand mOp = mimm> :
550  RRbm<opcStr, opc, RC, Ty, RC, Ty, OpNode, immOp, mOp>;
551
552// Generic RR multiclass for non-commutative instructions with 2 arguments.
553//   e.g. SUBUL, SUBUW, SUBSWSX, and etc.
554multiclass RRNCm<string opcStr, bits<8>opc,
555                 RegisterClass RC, ValueType Ty,
556                 SDPatternOperator OpNode = null_frag,
557                 Operand immOp = simm7, Operand mOp = mimm> :
558  RRNCbm<opcStr, opc, RC, Ty, RC, Ty, OpNode, immOp, mOp>;
559
560// Generic RR multiclass for floating point instructions with 2 arguments.
561//   e.g. FADDD, FADDS, FSUBD, and etc.
562multiclass RRFm<string opcStr, bits<8>opc,
563                RegisterClass RC, ValueType Ty,
564                SDPatternOperator OpNode = null_frag,
565                Operand immOp = simm7fp, Operand mOp = mimmfp> :
566  RRNCbm<opcStr, opc, RC, Ty, RC, Ty, OpNode, immOp, mOp>;
567
568// Generic RR multiclass for shift instructions with 2 arguments.
569//   e.g. SLL, SRL, SLAWSX, and etc.
570let hasSideEffects = 0 in
571multiclass RRIm<string opcStr, bits<8>opc,
572                RegisterClass RC, ValueType Ty,
573                SDPatternOperator OpNode = null_frag> {
574  def rr : RR<opc, (outs RC:$sx), (ins RC:$sz, I32:$sy),
575              !strconcat(opcStr, " $sx, $sz, $sy"),
576              [(set Ty:$sx, (OpNode Ty:$sz, i32:$sy))]>;
577  let cz = 0 in
578  def mr : RR<opc, (outs RC:$sx), (ins mimm:$sz, I32:$sy),
579              !strconcat(opcStr, " $sx, $sz, $sy"),
580              [(set Ty:$sx, (OpNode (Ty mimm:$sz), i32:$sy))]>;
581  let cy = 0 in
582  def ri : RR<opc, (outs RC:$sx), (ins RC:$sz, uimm7:$sy),
583              !strconcat(opcStr, " $sx, $sz, $sy"),
584              [(set Ty:$sx, (OpNode Ty:$sz, (i32 uimm7:$sy)))]>;
585  let cy = 0, cz = 0 in
586  def mi : RR<opc, (outs RC:$sx), (ins mimm:$sz, uimm7:$sy),
587              !strconcat(opcStr, " $sx, $sz, $sy"),
588              [(set Ty:$sx, (OpNode (Ty mimm:$sz), (i32 uimm7:$sy)))]>;
589}
590
591// Special RR multiclass for 128 bits shift left instruction.
592//   e.g. SLD
593let Constraints = "$hi = $sx", DisableEncoding = "$hi", hasSideEffects = 0 in
594multiclass RRILDm<string opcStr, bits<8>opc,
595                  RegisterClass RC, ValueType Ty,
596                  SDPatternOperator OpNode = null_frag> {
597  def rrr : RR<opc, (outs RC:$sx), (ins RC:$hi, RC:$sz, I32:$sy),
598              !strconcat(opcStr, " $sx, $sz, $sy")>;
599  let cz = 0 in
600  def rmr : RR<opc, (outs RC:$sx), (ins RC:$hi, mimm:$sz, I32:$sy),
601              !strconcat(opcStr, " $sx, $sz, $sy")>;
602  let cy = 0 in
603  def rri : RR<opc, (outs RC:$sx), (ins RC:$hi, RC:$sz, uimm7:$sy),
604              !strconcat(opcStr, " $sx, $sz, $sy")>;
605  let cy = 0, cz = 0 in
606  def rmi : RR<opc, (outs RC:$sx), (ins RC:$hi, mimm:$sz, uimm7:$sy),
607              !strconcat(opcStr, " $sx, $sz, $sy")>;
608}
609
610// Special RR multiclass for 128 bits shift right instruction.
611//   e.g. SRD
612let Constraints = "$low = $sx", DisableEncoding = "$low", hasSideEffects = 0 in
613multiclass RRIRDm<string opcStr, bits<8>opc,
614                  RegisterClass RC, ValueType Ty,
615                  SDPatternOperator OpNode = null_frag> {
616  def rrr : RR<opc, (outs RC:$sx), (ins RC:$sz, RC:$low, I32:$sy),
617              !strconcat(opcStr, " $sx, $sz, $sy")>;
618  let cz = 0 in
619  def mrr : RR<opc, (outs RC:$sx), (ins mimm:$sz, RC:$low, I32:$sy),
620              !strconcat(opcStr, " $sx, $sz, $sy")>;
621  let cy = 0 in
622  def rri : RR<opc, (outs RC:$sx), (ins RC:$sz, RC:$low, uimm7:$sy),
623              !strconcat(opcStr, " $sx, $sz, $sy")>;
624  let cy = 0, cz = 0 in
625  def mri : RR<opc, (outs RC:$sx), (ins mimm:$sz, RC:$low, uimm7:$sy),
626              !strconcat(opcStr, " $sx, $sz, $sy")>;
627}
628
629// Generic RR multiclass with an argument.
630//   e.g. LDZ, PCNT, and  BRV
631let cy = 0, sy = 0, hasSideEffects = 0 in
632multiclass RRI1m<string opcStr, bits<8>opc, RegisterClass RC, ValueType Ty,
633                 SDPatternOperator OpNode = null_frag> {
634  def r : RR<opc, (outs RC:$sx), (ins RC:$sz), !strconcat(opcStr, " $sx, $sz"),
635             [(set Ty:$sx, (OpNode Ty:$sz))]>;
636  let cz = 0 in
637  def m : RR<opc, (outs RC:$sx), (ins mimm:$sz),
638             !strconcat(opcStr, " $sx, $sz"),
639             [(set Ty:$sx, (OpNode (Ty mimm:$sz)))]>;
640}
641
642// Special RR multiclass for MRG instruction.
643//   e.g. MRG
644let Constraints = "$sx = $sd", DisableEncoding = "$sd", hasSideEffects = 0 in
645multiclass RRMRGm<string opcStr, bits<8>opc, RegisterClass RC, ValueType Ty> {
646  def rr : RR<opc, (outs RC:$sx), (ins RC:$sy, RC:$sz, RC:$sd),
647              !strconcat(opcStr, " $sx, $sy, $sz")>;
648  let cy = 0 in
649  def ir : RR<opc, (outs RC:$sx), (ins simm7:$sy, RC:$sz, RC:$sd),
650              !strconcat(opcStr, " $sx, $sy, $sz")>;
651  let cz = 0 in
652  def rm : RR<opc, (outs RC:$sx), (ins RC:$sy, mimm:$sz, RC:$sd),
653              !strconcat(opcStr, " $sx, $sy, $sz")>;
654  let cy = 0, cz = 0 in
655  def im : RR<opc, (outs RC:$sx), (ins simm7:$sy, mimm:$sz, RC:$sd),
656              !strconcat(opcStr, " $sx, $sy, $sz")>;
657}
658
659// Special RR multiclass for BSWP instruction.
660//   e.g. BSWP
661let hasSideEffects = 0 in
662multiclass RRSWPm<string opcStr, bits<8>opc,
663                  RegisterClass RC, ValueType Ty,
664                  SDPatternOperator OpNode = null_frag> {
665  let cy = 0 in
666  def ri : RR<opc, (outs RC:$sx), (ins RC:$sz, uimm1:$sy),
667              !strconcat(opcStr, " $sx, $sz, $sy"),
668              [(set Ty:$sx, (OpNode Ty:$sz, (i32 uimm1:$sy)))]>;
669  let cy = 0, cz = 0 in
670  def mi : RR<opc, (outs RC:$sx), (ins mimm:$sz, uimm1:$sy),
671              !strconcat(opcStr, " $sx, $sz, $sy"),
672              [(set Ty:$sx, (OpNode (Ty mimm:$sz), (i32 uimm1:$sy)))]>;
673}
674
675// Multiclass for CMOV instructions.
676//   e.g. CMOVL, CMOVW, CMOVD, and etc.
677let Constraints = "$sx = $sd", DisableEncoding = "$sd", hasSideEffects = 0,
678    cfw = ? in
679multiclass RRCMOVm<string opcStr, bits<8>opc, RegisterClass RC, ValueType Ty> {
680  def rr : RR<opc, (outs I64:$sx), (ins CCOp:$cfw, RC:$sy, I64:$sz, I64:$sd),
681              !strconcat(opcStr, " $sx, $sz, $sy")>;
682  let cy = 0 in
683  def ir : RR<opc, (outs I64:$sx),
684              (ins CCOp:$cfw, simm7:$sy, I64:$sz, I64:$sd),
685              !strconcat(opcStr, " $sx, $sz, $sy")>;
686  let cz = 0 in
687  def rm : RR<opc, (outs I64:$sx),
688              (ins CCOp:$cfw, RC:$sy, mimm:$sz, I64:$sd),
689              !strconcat(opcStr, " $sx, $sz, $sy")>;
690  let cy = 0, cz = 0 in
691  def im : RR<opc, (outs I64:$sx),
692              (ins CCOp:$cfw, simm7:$sy, mimm:$sz, I64:$sd),
693              !strconcat(opcStr, " $sx, $sz, $sy")>;
694}
695
696// Multiclass for floating point conversion instructions.
697//   e.g. CVTWDSX, CVTWDZX, CVTWSSX, and etc.
698// sz{3-0} = rounding mode
699let cz = 0, hasSideEffects = 0 in
700multiclass CVTRDm<string opcStr, bits<8> opc, RegisterClass RCo, ValueType Tyo,
701                  RegisterClass RCi, ValueType Tyi> {
702  def r : RR<opc, (outs RCo:$sx), (ins RDOp:$rd, RCi:$sy),
703             !strconcat(opcStr, "${rd} $sx, $sy")> {
704    bits<4> rd;
705    let sz{5-4} = 0;
706    let sz{3-0} = rd;
707  }
708  let cy = 0 in
709  def i : RR<opc, (outs RCo:$sx), (ins RDOp:$rd, simm7:$sy),
710             !strconcat(opcStr, "${rd} $sx, $sy")> {
711    bits<4> rd;
712    let sz{5-4} = 0;
713    let sz{3-0} = rd;
714  }
715}
716
717// Multiclass for floating point conversion instructions.
718//   e.g. CVTDW, CVTSW, CVTDL, and etc.
719let cz = 0, sz = 0, hasSideEffects = 0 in
720multiclass CVTm<string opcStr, bits<8> opc, RegisterClass RCo, ValueType Tyo,
721                RegisterClass RCi, ValueType Tyi,
722                SDPatternOperator OpNode = null_frag> {
723  def r : RR<opc, (outs RCo:$sx), (ins RCi:$sy),
724             !strconcat(opcStr, " $sx, $sy"),
725             [(set Tyo:$sx, (OpNode Tyi:$sy))]>;
726  let cy = 0 in
727  def i : RR<opc, (outs RCo:$sx), (ins simm7:$sy),
728             !strconcat(opcStr, " $sx, $sy")>;
729}
730
731// Multiclass for PFCH instructions.
732//   e.g. PFCH
733let sx = 0, hasSideEffects = 0 in
734multiclass PFCHm<string opcStr, bits<8>opc> {
735  def rri : RM<opc, (outs), (ins MEMrri:$addr), !strconcat(opcStr, " $addr"),
736               [(prefetch ADDRrri:$addr, imm, imm, (i32 1))]>;
737  let cy = 0 in
738  def rii : RM<opc, (outs), (ins MEMrii:$addr), !strconcat(opcStr, " $addr"),
739               [(prefetch ADDRrii:$addr, imm, imm, (i32 1))]>;
740  let cz = 0 in
741  def zri : RM<opc, (outs), (ins MEMzri:$addr), !strconcat(opcStr, " $addr"),
742               [(prefetch ADDRzri:$addr, imm, imm, (i32 1))]>;
743  let cy = 0, cz = 0 in
744  def zii : RM<opc, (outs), (ins MEMzii:$addr), !strconcat(opcStr, " $addr"),
745               [(prefetch ADDRzii:$addr, imm, imm, (i32 1))]>;
746}
747
748// Multiclass for CAS instructions.
749//   e.g. TS1AML, TS1AMW, TS2AM, and etc.
750let Constraints = "$dest = $sd", DisableEncoding = "$sd",
751    mayStore=1, mayLoad = 1, hasSideEffects = 0 in
752multiclass RRCAStgm<string opcStr, bits<8>opc, RegisterClass RC, ValueType Ty,
753                    Operand immOp, Operand MEM, Operand ADDR,
754                    SDPatternOperator OpNode = null_frag> {
755  def r : RRM<opc, (outs RC:$dest), (ins MEM:$addr, RC:$sy, RC:$sd),
756              !strconcat(opcStr, " $dest, $addr, $sy"),
757              [(set Ty:$dest, (OpNode ADDR:$addr, Ty:$sy, Ty:$sd))]>;
758  let cy = 0 in
759  def i : RRM<opc, (outs RC:$dest), (ins MEM:$addr, immOp:$sy, RC:$sd),
760              !strconcat(opcStr, " $dest, $addr, $sy"),
761              [(set Ty:$dest, (OpNode ADDR:$addr, (Ty immOp:$sy), Ty:$sd))]>;
762}
763multiclass RRCASm<string opcStr, bits<8>opc, RegisterClass RC, ValueType Ty,
764                  Operand immOp, SDPatternOperator OpNode = null_frag> {
765  defm ri : RRCAStgm<opcStr, opc, RC, Ty, immOp, MEMriRRM, ADDRri, OpNode>;
766  let cz = 0 in
767  defm zi : RRCAStgm<opcStr, opc, RC, Ty, immOp, MEMziRRM, ADDRzi, OpNode>;
768}
769
770// Multiclass for branch instructions
771//   e.g. BCFL, BCFW, BCFD, and etc.
772let isBranch = 1, isTerminator = 1, isIndirectBranch = 1, hasSideEffects = 0 in
773multiclass BCbpfm<string opcStr, string cmpStr, bits<8> opc, dag cond,
774                  Operand ADDR> {
775  let bpf = 0 /* NONE */ in
776  def "" : CF<opc, (outs), !con(cond, (ins ADDR:$addr)),
777              !strconcat(opcStr, " ", cmpStr, "$addr")>;
778  let bpf = 2 /* NOT TaKEN */ in
779  def _nt : CF<opc, (outs), !con(cond, (ins ADDR:$addr)),
780               !strconcat(opcStr, ".nt ", cmpStr, "$addr")>;
781  let bpf = 3 /* TaKEN */ in
782  def _t : CF<opc, (outs), !con(cond, (ins ADDR:$addr)),
783              !strconcat(opcStr, ".t ", cmpStr, "$addr")>;
784}
785multiclass BCtgm<string opcStr, string cmpStr, bits<8> opc, dag cond> {
786  defm ri : BCbpfm<opcStr, cmpStr, opc, cond, MEMriASX>;
787  let cz = 0 in defm zi : BCbpfm<opcStr, cmpStr, opc, cond, MEMziASX>;
788}
789multiclass BCm<string opcStr, string opcStrAt, string opcStrAf, bits<8> opc,
790               RegisterClass RC, Operand immOp> {
791  let DecoderMethod = "DecodeBranchCondition" in
792  defm r : BCtgm<opcStr, "$comp, ", opc, (ins CCOp:$cond, RC:$comp)>;
793  let DecoderMethod = "DecodeBranchCondition", cy = 0 in
794  defm i : BCtgm<opcStr, "$comp, ", opc, (ins CCOp:$cond, immOp:$comp)>;
795  let DecoderMethod = "DecodeBranchConditionAlways", cy = 0, sy = 0,
796      cf = 15 /* AT */, isBarrier = 1 in
797  defm a : BCtgm<opcStrAt, "", opc, (ins)>;
798  let DecoderMethod = "DecodeBranchConditionAlways", cy = 0, sy = 0,
799      cf = 0 /* AF */ in
800  defm na : BCtgm<opcStrAf, "", opc, (ins)>;
801}
802
803// Multiclass for relative branch instructions
804//   e.g. BRCFL, BRCFW, BRCFD, and etc.
805let isBranch = 1, isTerminator = 1, hasSideEffects = 0 in
806multiclass BCRbpfm<string opcStr, string cmpStr, bits<8> opc, dag cond> {
807  let bpf = 0 /* NONE */ in
808  def "" : CF<opc, (outs), !con(cond, (ins brtarget32:$imm32)),
809              !strconcat(opcStr, " ", cmpStr, "$imm32")>;
810  let bpf = 2 /* NOT TaKEN */ in
811  def _nt : CF<opc, (outs), !con(cond, (ins brtarget32:$imm32)),
812               !strconcat(opcStr, ".nt ", cmpStr, "$imm32")>;
813  let bpf = 3 /* TaKEN */ in
814  def _t : CF<opc, (outs), !con(cond, (ins brtarget32:$imm32)),
815              !strconcat(opcStr, ".t ", cmpStr, "$imm32")>;
816}
817multiclass BCRm<string opcStr, string opcStrAt, string opcStrAf, bits<8> opc,
818               RegisterClass RC, Operand immOp> {
819  defm rr : BCRbpfm<opcStr, "$sy, $sz, ", opc, (ins CCOp:$cf, RC:$sy, RC:$sz)>;
820  let cy = 0 in
821  defm ir : BCRbpfm<opcStr, "$sy, $sz, ", opc, (ins CCOp:$cf, immOp:$sy, RC:$sz)>;
822  let cy = 0, sy = 0, cz = 0, sz = 0, cf = 15 /* AT */, isBarrier = 1 in
823  defm a : BCRbpfm<opcStrAt, "", opc, (ins)>;
824  let cy = 0, sy = 0, cz = 0, sz = 0, cf = 0 /* AF */ in
825  defm na : BCRbpfm<opcStrAf, "", opc, (ins)>;
826}
827
828// Multiclass for communication register instructions.
829//   e.g. LCR
830let hasSideEffects = 1 in
831multiclass LOADCRm<string opcStr, bits<8>opc, RegisterClass RC> {
832  def rr : RR<opc, (outs RC:$sx), (ins RC:$sz, RC:$sy),
833              !strconcat(opcStr, " $sx, $sy, $sz")>;
834  let cy = 0 in def ri : RR<opc, (outs RC:$sx), (ins RC:$sz, simm7:$sy),
835                            !strconcat(opcStr, " $sx, $sy, $sz")>;
836  let cz = 0 in def zr : RR<opc, (outs RC:$sx), (ins zero:$sz, RC:$sy),
837                            !strconcat(opcStr, " $sx, $sy, $sz")>;
838  let cy = 0, cz = 0 in
839  def zi : RR<opc, (outs RC:$sx), (ins zero:$sz, simm7:$sy),
840              !strconcat(opcStr, " $sx, $sy, $sz")>;
841}
842
843// Multiclass for communication register instructions.
844//   e.g. SCR
845let hasSideEffects = 1 in
846multiclass STORECRm<string opcStr, bits<8>opc, RegisterClass RC> {
847  def rr : RR<opc, (outs), (ins RC:$sz, RC:$sy, RC:$sx),
848              !strconcat(opcStr, " $sx, $sy, $sz")>;
849  let cy = 0 in def ri : RR<opc, (outs), (ins RC:$sz, simm7:$sy, RC:$sx),
850                            !strconcat(opcStr, " $sx, $sy, $sz")>;
851  let cz = 0 in def zr : RR<opc, (outs), (ins zero:$sz, RC:$sy, RC:$sx),
852                            !strconcat(opcStr, " $sx, $sy, $sz")>;
853  let cy = 0, cz = 0 in
854  def zi : RR<opc, (outs), (ins zero:$sz, simm7:$sy, RC:$sx),
855              !strconcat(opcStr, " $sx, $sy, $sz")>;
856}
857
858// Multiclass for communication register instructions.
859//   e.g. FIDCR
860let cz = 0, hasSideEffects = 1 in
861multiclass FIDCRm<string opcStr, bits<8>opc, RegisterClass RC> {
862  def ri : RR<opc, (outs RC:$sx), (ins RC:$sy, uimm3:$sz),
863              !strconcat(opcStr, " $sx, $sy, $sz")>;
864  let cy = 0 in def ii : RR<opc, (outs RC:$sx), (ins simm7:$sy, uimm3:$sz),
865                            !strconcat(opcStr, " $sx, $sy, $sz")>;
866}
867
868// Multiclass for LHM instruction.
869let mayLoad = 1, hasSideEffects = 0 in
870multiclass LHMm<string opcStr, bits<8> opc, RegisterClass RC> {
871  def ri : RRMHM<opc, (outs RC:$dest), (ins MEMriHM:$addr),
872                 !strconcat(opcStr, " $dest, $addr")>;
873  let cz = 0 in
874  def zi : RRMHM<opc, (outs RC:$dest), (ins MEMziHM:$addr),
875                 !strconcat(opcStr, " $dest, $addr")>;
876}
877
878// Multiclass for SHM instruction.
879let mayStore = 1, hasSideEffects = 0 in
880multiclass SHMm<string opcStr, bits<8> opc, RegisterClass RC> {
881  def ri : RRMHM<opc, (outs), (ins MEMriHM:$addr, RC:$sx),
882                 !strconcat(opcStr, " $sx, $addr")>;
883  let cz = 0 in
884  def zi : RRMHM<opc, (outs), (ins MEMziHM:$addr, RC:$sx),
885                 !strconcat(opcStr, " $sx, $addr")>;
886}
887
888//===----------------------------------------------------------------------===//
889// Instructions
890//
891// Define all scalar instructions defined in SX-Aurora TSUBASA Architecture
892// Guide here.  As those mnemonics, we use mnemonics defined in Vector Engine
893// Assembly Language Reference Manual.
894//===----------------------------------------------------------------------===//
895
896//-----------------------------------------------------------------------------
897// Section 8.2 - Load/Store instructions
898//-----------------------------------------------------------------------------
899
900// Multiclass for generic RM instructions
901multiclass RMm<string opcStr, bits<8>opc, RegisterClass RC> {
902  def rri : RM<opc, (outs RC:$dest), (ins MEMrri:$addr),
903               !strconcat(opcStr, " $dest, $addr"), []>;
904  let cy = 0 in
905  def rii : RM<opc, (outs RC:$dest), (ins MEMrii:$addr),
906               !strconcat(opcStr, " $dest, $addr"), []>;
907  let cz = 0 in
908  def zri : RM<opc, (outs RC:$dest), (ins MEMzri:$addr),
909               !strconcat(opcStr, " $dest, $addr"), []>;
910  let cy = 0, cz = 0 in
911  def zii : RM<opc, (outs RC:$dest), (ins MEMzii:$addr),
912               !strconcat(opcStr, " $dest, $addr"), []>;
913}
914
915// Section 8.2.1 - LEA
916let cx = 0, DecoderMethod = "DecodeLoadI64" in
917defm LEA : RMm<"lea", 0x06, I64>;
918let cx = 1, DecoderMethod = "DecodeLoadI64" in
919defm LEASL : RMm<"lea.sl", 0x06, I64>;
920let cx = 0, DecoderMethod = "DecodeLoadI32", isCodeGenOnly = 1 in
921defm LEA32 : RMm<"lea", 0x06, I32>;
922
923def : Pat<(iPTR ADDRrri:$addr), (LEArri MEMrri:$addr)>;
924def : Pat<(iPTR ADDRrii:$addr), (LEArii MEMrii:$addr)>;
925def : Pat<(add I64:$base, simm32:$disp), (LEArii $base, 0, (LO32 $disp))>;
926def : Pat<(add I64:$base, lozero:$disp), (LEASLrii $base, 0, (HI32 $disp))>;
927def : Pat<(add I32:$base, simm32:$disp),
928          (LEA32rii (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $base, sub_i32), 0,
929                    (LO32 $disp))>;
930
931def lea_add : PatFrags<(ops node:$base, node:$idx, node:$disp),
932                       [(add (add node:$base, node:$idx), node:$disp),
933                        (add (add node:$base, node:$disp), node:$idx)]>;
934def : Pat<(lea_add I64:$base, simm7:$idx, simm32:$disp),
935          (LEArii $base, (LO7 $idx), (LO32 $disp))>;
936def : Pat<(lea_add I64:$base, I64:$idx, simm32:$disp),
937          (LEArri $base, $idx, (LO32 $disp))>;
938def : Pat<(lea_add I64:$base, simm7:$idx, lozero:$disp),
939          (LEASLrii $base, (LO7 $idx), (HI32 $disp))>;
940def : Pat<(lea_add I64:$base, I64:$idx, lozero:$disp),
941          (LEASLrri $base, $idx, (HI32 $disp))>;
942
943// Multiclass for load instructions.
944let mayLoad = 1, hasSideEffects = 0 in
945multiclass LOADm<string opcStr, bits<8> opc, RegisterClass RC, ValueType Ty,
946                 SDPatternOperator OpNode = null_frag> {
947  def rri : RM<opc, (outs RC:$dest), (ins MEMrri:$addr),
948               !strconcat(opcStr, " $dest, $addr"),
949               [(set Ty:$dest, (OpNode ADDRrri:$addr))]>;
950  let cy = 0 in
951  def rii : RM<opc, (outs RC:$dest), (ins MEMrii:$addr),
952               !strconcat(opcStr, " $dest, $addr"),
953               [(set Ty:$dest, (OpNode ADDRrii:$addr))]>;
954  let cz = 0 in
955  def zri : RM<opc, (outs RC:$dest), (ins MEMzri:$addr),
956               !strconcat(opcStr, " $dest, $addr"),
957               [(set Ty:$dest, (OpNode ADDRzri:$addr))]>;
958  let cy = 0, cz = 0 in
959  def zii : RM<opc, (outs RC:$dest), (ins MEMzii:$addr),
960               !strconcat(opcStr, " $dest, $addr"),
961               [(set Ty:$dest, (OpNode ADDRzii:$addr))]>;
962}
963
964// Section 8.2.2 - LDS
965let DecoderMethod = "DecodeLoadI64" in
966defm LD : LOADm<"ld", 0x01, I64, i64, load>;
967def : Pat<(f64 (load ADDRrri:$addr)), (LDrri MEMrri:$addr)>;
968def : Pat<(f64 (load ADDRrii:$addr)), (LDrii MEMrii:$addr)>;
969def : Pat<(f64 (load ADDRzri:$addr)), (LDzri MEMzri:$addr)>;
970def : Pat<(f64 (load ADDRzii:$addr)), (LDzii MEMzii:$addr)>;
971
972// Section 8.2.3 - LDU
973let DecoderMethod = "DecodeLoadF32" in
974defm LDU : LOADm<"ldu", 0x02, F32, f32, load>;
975
976// Section 8.2.4 - LDL
977let DecoderMethod = "DecodeLoadI32" in
978defm LDLSX : LOADm<"ldl.sx", 0x03, I32, i32, load>;
979let cx = 1, DecoderMethod = "DecodeLoadI32" in
980defm LDLZX : LOADm<"ldl.zx", 0x03, I32, i32, load>;
981
982// Section 8.2.5 - LD2B
983let DecoderMethod = "DecodeLoadI32" in
984defm LD2BSX : LOADm<"ld2b.sx", 0x04, I32, i32, sextloadi16>;
985let cx = 1, DecoderMethod = "DecodeLoadI32" in
986defm LD2BZX : LOADm<"ld2b.zx", 0x04, I32, i32, zextloadi16>;
987
988// Section 8.2.6 - LD1B
989let DecoderMethod = "DecodeLoadI32" in
990defm LD1BSX : LOADm<"ld1b.sx", 0x05, I32, i32, sextloadi8>;
991let cx = 1, DecoderMethod = "DecodeLoadI32" in
992defm LD1BZX : LOADm<"ld1b.zx", 0x05, I32, i32, zextloadi8>;
993
994// Multiclass for store instructions.
995let mayStore = 1 in
996multiclass STOREm<string opcStr, bits<8> opc, RegisterClass RC, ValueType Ty,
997                  SDPatternOperator OpNode = null_frag> {
998  def rri : RM<opc, (outs), (ins MEMrri:$addr, RC:$sx),
999               !strconcat(opcStr, " $sx, $addr"),
1000               [(OpNode Ty:$sx, ADDRrri:$addr)]>;
1001  let cy = 0 in
1002  def rii : RM<opc, (outs), (ins MEMrii:$addr, RC:$sx),
1003               !strconcat(opcStr, " $sx, $addr"),
1004               [(OpNode Ty:$sx, ADDRrii:$addr)]>;
1005  let cz = 0 in
1006  def zri : RM<opc, (outs), (ins MEMzri:$addr, RC:$sx),
1007               !strconcat(opcStr, " $sx, $addr"),
1008               [(OpNode Ty:$sx, ADDRzri:$addr)]>;
1009  let cy = 0, cz = 0 in
1010  def zii : RM<opc, (outs), (ins MEMzii:$addr, RC:$sx),
1011               !strconcat(opcStr, " $sx, $addr"),
1012               [(OpNode Ty:$sx, ADDRzii:$addr)]>;
1013}
1014
1015// Section 8.2.7 - STS
1016let DecoderMethod = "DecodeStoreI64" in
1017defm ST : STOREm<"st", 0x11, I64, i64, store>;
1018def : Pat<(store f64:$src, ADDRrri:$addr), (STrri MEMrri:$addr, $src)>;
1019def : Pat<(store f64:$src, ADDRrii:$addr), (STrii MEMrii:$addr, $src)>;
1020def : Pat<(store f64:$src, ADDRzri:$addr), (STzri MEMzri:$addr, $src)>;
1021def : Pat<(store f64:$src, ADDRzii:$addr), (STzii MEMzii:$addr, $src)>;
1022
1023// Section 8.2.8 - STU
1024let DecoderMethod = "DecodeStoreF32" in
1025defm STU : STOREm<"stu", 0x12, F32, f32, store>;
1026
1027// Section 8.2.9 - STL
1028let DecoderMethod = "DecodeStoreI32" in
1029defm STL : STOREm<"stl", 0x13, I32, i32, store>;
1030
1031// Section 8.2.10 - ST2B
1032let DecoderMethod = "DecodeStoreI32" in
1033defm ST2B : STOREm<"st2b", 0x14, I32, i32, truncstorei16>;
1034
1035// Section 8.2.11 - ST1B
1036let DecoderMethod = "DecodeStoreI32" in
1037defm ST1B : STOREm<"st1b", 0x15, I32, i32, truncstorei8>;
1038
1039// Section 8.2.12 - DLDS
1040let DecoderMethod = "DecodeLoadI64" in
1041defm DLD : LOADm<"dld", 0x09, I64, i64, load>;
1042
1043// Section 8.2.13 - DLDU
1044let DecoderMethod = "DecodeLoadF32" in
1045defm DLDU : LOADm<"dldu", 0x0a, F32, f32, load>;
1046
1047// Section 8.2.14 - DLDL
1048let DecoderMethod = "DecodeLoadI32" in
1049defm DLDLSX : LOADm<"dldl.sx", 0x0b, I32, i32, load>;
1050let cx = 1, DecoderMethod = "DecodeLoadI32" in
1051defm DLDLZX : LOADm<"dldl.zx", 0x0b, I32, i32, load>;
1052
1053// Section 8.2.15 - PFCH
1054let DecoderMethod = "DecodeASX" in
1055defm PFCH : PFCHm<"pfch", 0x0c>;
1056
1057// Section 8.2.16 - TS1AM (Test and Set 1 AM)
1058let DecoderMethod = "DecodeTS1AMI64" in
1059defm TS1AML : RRCASm<"ts1am.l", 0x42, I64, i64, uimm7>;
1060let DecoderMethod = "DecodeTS1AMI32", cx = 1 in
1061defm TS1AMW : RRCASm<"ts1am.w", 0x42, I32, i32, uimm7>;
1062
1063// Section 8.2.17 - TS2AM (Test and Set 2 AM)
1064let DecoderMethod = "DecodeTS1AMI64" in
1065defm TS2AM : RRCASm<"ts2am", 0x43, I64, i64, uimm7>;
1066
1067// Section 8.2.18 - TS3AM (Test and Set 3 AM)
1068let DecoderMethod = "DecodeTS1AMI64" in
1069defm TS3AM : RRCASm<"ts3am", 0x52, I64, i64, uimm1>;
1070
1071// Section 8.2.19 - ATMAM (Atomic AM)
1072let DecoderMethod = "DecodeTS1AMI64" in
1073defm ATMAM : RRCASm<"atmam", 0x53, I64, i64, uimm0to2>;
1074
1075// Section 8.2.20 - CAS (Compare and Swap)
1076let DecoderMethod = "DecodeCASI64" in
1077defm CASL : RRCASm<"cas.l", 0x62, I64, i64, simm7>;
1078let DecoderMethod = "DecodeCASI32", cx = 1 in
1079defm CASW : RRCASm<"cas.w", 0x62, I32, i32, simm7>;
1080
1081//-----------------------------------------------------------------------------
1082// Section 8.3 - Transfer Control Instructions
1083//-----------------------------------------------------------------------------
1084
1085// Section 8.3.1 - FENCE (Fence)
1086let hasSideEffects = 1 in {
1087  let avo = 1 in def FENCEI : RRFENCE<0x20, (outs), (ins), "fencei">;
1088  def FENCEM : RRFENCE<0x20, (outs), (ins uimm2:$kind), "fencem $kind"> {
1089    bits<2> kind;
1090    let lf = kind{1};
1091    let sf = kind{0};
1092  }
1093  def FENCEC : RRFENCE<0x20, (outs), (ins uimm3:$kind), "fencec $kind"> {
1094    bits<3> kind;
1095    let c2 = kind{2};
1096    let c1 = kind{1};
1097    let c0 = kind{0};
1098  }
1099}
1100
1101// Section 8.3.2 - SVOB (Set Vector Out-of-order memory access Boundary)
1102let sx = 0, cy = 0, sy = 0, cz = 0, sz = 0, hasSideEffects = 1 in
1103def SVOB : RR<0x30, (outs), (ins), "svob">;
1104
1105//-----------------------------------------------------------------------------
1106// Section 8.4 - Fixed-point Operation Instructions
1107//-----------------------------------------------------------------------------
1108
1109// Section 8.4.1 - ADD (Add)
1110defm ADDUL : RRm<"addu.l", 0x48, I64, i64>;
1111let cx = 1 in defm ADDUW : RRm<"addu.w", 0x48, I32, i32>;
1112
1113// Section 8.4.2 - ADS (Add Single)
1114defm ADDSWSX : RRm<"adds.w.sx", 0x4A, I32, i32, add>;
1115let cx = 1 in defm ADDSWZX : RRm<"adds.w.zx", 0x4A, I32, i32>;
1116
1117// Section 8.4.3 - ADX (Add)
1118defm ADDSL : RRm<"adds.l", 0x59, I64, i64, add>;
1119
1120// Section 8.4.4 - SUB (Subtract)
1121defm SUBUL : RRNCm<"subu.l", 0x58, I64, i64>;
1122let cx = 1 in defm SUBUW : RRNCm<"subu.w", 0x58, I32, i32>;
1123
1124// Section 8.4.5 - SBS (Subtract Single)
1125defm SUBSWSX : RRNCm<"subs.w.sx", 0x5A, I32, i32, sub>;
1126let cx = 1 in defm SUBSWZX : RRNCm<"subs.w.zx", 0x5A, I32, i32>;
1127
1128// Section 8.4.6 - SBX (Subtract)
1129defm SUBSL : RRNCm<"subs.l", 0x5B, I64, i64, sub>;
1130
1131// Section 8.4.7 - MPY (Multiply)
1132defm MULUL : RRm<"mulu.l", 0x49, I64, i64>;
1133let cx = 1 in defm MULUW : RRm<"mulu.w", 0x49, I32, i32>;
1134
1135// Section 8.4.8 - MPS (Multiply Single)
1136defm MULSWSX : RRm<"muls.w.sx", 0x4B, I32, i32, mul>;
1137let cx = 1 in defm MULSWZX : RRm<"muls.w.zx", 0x4B, I32, i32>;
1138
1139// Section 8.4.9 - MPX (Multiply)
1140defm MULSL : RRm<"muls.l", 0x6E, I64, i64, mul>;
1141
1142// Section 8.4.10 - MPD (Multiply)
1143defm MULSLW : RRbm<"muls.l.w", 0x6B, I64, i64, I32, i32>;
1144
1145// Section 8.4.11 - DIV (Divide)
1146defm DIVUL : RRNCm<"divu.l", 0x6F, I64, i64, udiv>;
1147let cx = 1 in defm DIVUW : RRNCm<"divu.w", 0x6F, I32, i32, udiv>;
1148
1149// Section 8.4.12 - DVS (Divide Single)
1150defm DIVSWSX : RRNCm<"divs.w.sx", 0x7B, I32, i32, sdiv>;
1151let cx = 1 in defm DIVSWZX : RRNCm<"divs.w.zx", 0x7B, I32, i32>;
1152
1153// Section 8.4.13 - DVX (Divide)
1154defm DIVSL : RRNCm<"divs.l", 0x7F, I64, i64, sdiv>;
1155
1156// Section 8.4.14 - CMP (Compare)
1157defm CMPUL : RRNCm<"cmpu.l", 0x55, I64, i64>;
1158let cx = 1 in defm CMPUW : RRNCm<"cmpu.w", 0x55, I32, i32>;
1159
1160// Section 8.4.15 - CPS (Compare Single)
1161defm CMPSWSX : RRNCm<"cmps.w.sx", 0x7A, I32, i32>;
1162let cx = 1 in defm CMPSWZX : RRNCm<"cmps.w.zx", 0x7A, I32, i32>;
1163
1164// Section 8.4.16 - CPX (Compare)
1165defm CMPSL : RRNCm<"cmps.l", 0x6A, I64, i64>;
1166
1167// Section 8.4.17 - CMS (Compare and Select Maximum/Minimum Single)
1168// cx: sx/zx, cw: max/min
1169defm MAXSWSX : RRm<"maxs.w.sx", 0x78, I32, i32>;
1170let cx = 1 in defm MAXSWZX : RRm<"maxs.w.zx", 0x78, I32, i32>;
1171let cw = 1 in defm MINSWSX : RRm<"mins.w.sx", 0x78, I32, i32>;
1172let cx = 1, cw = 1 in defm MINSWZX : RRm<"mins.w.zx", 0x78, I32, i32>;
1173
1174// Section 8.4.18 - CMX (Compare and Select Maximum/Minimum)
1175defm MAXSL : RRm<"maxs.l", 0x68, I64, i64>;
1176let cw = 1 in defm MINSL : RRm<"mins.l", 0x68, I64, i64>;
1177
1178//-----------------------------------------------------------------------------
1179// Section 8.5 - Logical Operation Instructions
1180//-----------------------------------------------------------------------------
1181
1182// Section 8.5.1 - AND (AND)
1183defm AND : RRm<"and", 0x44, I64, i64, and>;
1184let isCodeGenOnly = 1 in defm AND32 : RRm<"and", 0x44, I32, i32, and>;
1185
1186// Section 8.5.2 - OR (OR)
1187defm OR : RRm<"or", 0x45, I64, i64, or>;
1188let isCodeGenOnly = 1 in defm OR32 : RRm<"or", 0x45, I32, i32, or>;
1189
1190// Section 8.5.3 - XOR (Exclusive OR)
1191defm XOR : RRm<"xor", 0x46, I64, i64, xor>;
1192let isCodeGenOnly = 1 in defm XOR32 : RRm<"xor", 0x46, I32, i32, xor>;
1193
1194// Section 8.5.4 - EQV (Equivalence)
1195defm EQV : RRm<"eqv", 0x47, I64, i64>;
1196
1197// Section 8.5.5 - NND (Negate AND)
1198def and_not : PatFrags<(ops node:$x, node:$y),
1199                       [(and (not node:$x), node:$y)]>;
1200defm NND : RRNCm<"nnd", 0x54, I64, i64, and_not>;
1201
1202// Section 8.5.6 - MRG (Merge)
1203defm MRG : RRMRGm<"mrg", 0x56, I64, i64>;
1204
1205// Section 8.5.7 - LDZ (Leading Zero Count)
1206defm LDZ : RRI1m<"ldz", 0x67, I64, i64, ctlz>;
1207
1208// Section 8.5.8 - PCNT (Population Count)
1209defm PCNT : RRI1m<"pcnt", 0x38, I64, i64, ctpop>;
1210
1211// Section 8.5.9 - BRV (Bit Reverse)
1212defm BRV : RRI1m<"brv", 0x39, I64, i64, bitreverse>;
1213
1214// Section 8.5.10 - BSWP (Byte Swap)
1215defm BSWP : RRSWPm<"bswp", 0x2B, I64, i64>;
1216
1217// Section 8.5.11 - CMOV (Conditional Move)
1218let cw = 0, cw2 = 0 in defm CMOVL : RRCMOVm<"cmov.l.${cfw}", 0x3B, I64, i64>;
1219let cw = 1, cw2 = 0 in defm CMOVW : RRCMOVm<"cmov.w.${cfw}", 0x3B, I32, i32>;
1220let cw = 0, cw2 = 1 in defm CMOVD : RRCMOVm<"cmov.d.${cfw}", 0x3B, I64, f64>;
1221let cw = 1, cw2 = 1 in defm CMOVS : RRCMOVm<"cmov.s.${cfw}", 0x3B, F32, f32>;
1222def : MnemonicAlias<"cmov.l", "cmov.l.at">;
1223def : MnemonicAlias<"cmov.w", "cmov.w.at">;
1224def : MnemonicAlias<"cmov.d", "cmov.d.at">;
1225def : MnemonicAlias<"cmov.s", "cmov.s.at">;
1226
1227//-----------------------------------------------------------------------------
1228// Section 8.6 - Shift Operation Instructions
1229//-----------------------------------------------------------------------------
1230
1231// Section 8.6.1 - SLL (Shift Left Logical)
1232defm SLL : RRIm<"sll", 0x65, I64, i64, shl>;
1233
1234// Section 8.6.2 - SLD (Shift Left Double)
1235defm SLD : RRILDm<"sld", 0x64, I64, i64>;
1236
1237// Section 8.6.3 - SRL (Shift Right Logical)
1238defm SRL : RRIm<"srl", 0x75, I64, i64, srl>;
1239
1240// Section 8.6.4 - SRD (Shift Right Double)
1241defm SRD : RRIRDm<"srd", 0x74, I64, i64>;
1242
1243// Section 8.6.5 - SLA (Shift Left Arithmetic)
1244defm SLAWSX : RRIm<"sla.w.sx", 0x66, I32, i32, shl>;
1245let cx = 1 in defm SLAWZX : RRIm<"sla.w.zx", 0x66, I32, i32>;
1246
1247// Section 8.6.6 - SLAX (Shift Left Arithmetic)
1248defm SLAL : RRIm<"sla.l", 0x57, I64, i64>;
1249
1250// Section 8.6.7 - SRA (Shift Right Arithmetic)
1251defm SRAWSX : RRIm<"sra.w.sx", 0x76, I32, i32, sra>;
1252let cx = 1 in defm SRAWZX : RRIm<"sra.w.zx", 0x76, I32, i32>;
1253
1254// Section 8.6.8 - SRAX (Shift Right Arithmetic)
1255defm SRAL : RRIm<"sra.l", 0x77, I64, i64, sra>;
1256
1257def : Pat<(i32 (srl i32:$src, (i32 simm7:$val))),
1258          (EXTRACT_SUBREG (SRLri (ANDrm (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
1259            $src, sub_i32), !add(32, 64)), imm:$val), sub_i32)>;
1260def : Pat<(i32 (srl i32:$src, i32:$val)),
1261          (EXTRACT_SUBREG (SRLrr (ANDrm (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
1262            $src, sub_i32), !add(32, 64)), $val), sub_i32)>;
1263
1264//-----------------------------------------------------------------------------
1265// Section 8.7 - Floating-point Arithmetic Instructions
1266//-----------------------------------------------------------------------------
1267
1268// Section 8.7.1 - FAD (Floating Add)
1269defm FADDD : RRFm<"fadd.d", 0x4C, I64, f64, fadd>;
1270let cx = 1 in
1271defm FADDS : RRFm<"fadd.s", 0x4C, F32, f32, fadd, simm7fp, mimmfp32>;
1272
1273// Section 8.7.2 - FSB (Floating Subtract)
1274defm FSUBD : RRFm<"fsub.d", 0x5C, I64, f64, fsub>;
1275let cx = 1 in
1276defm FSUBS : RRFm<"fsub.s", 0x5C, F32, f32, fsub, simm7fp, mimmfp32>;
1277
1278// Section 8.7.3 - FMP (Floating Multiply)
1279defm FMULD : RRFm<"fmul.d", 0x4D, I64, f64, fmul>;
1280let cx = 1 in
1281defm FMULS : RRFm<"fmul.s", 0x4D, F32, f32, fmul, simm7fp, mimmfp32>;
1282
1283// Section 8.7.4 - FDV (Floating Divide)
1284defm FDIVD : RRFm<"fdiv.d", 0x5D, I64, f64, fdiv>;
1285let cx = 1 in
1286defm FDIVS : RRFm<"fdiv.s", 0x5D, F32, f32, fdiv, simm7fp, mimmfp32>;
1287
1288// Section 8.7.5 - FCP (Floating Compare)
1289defm FCMPD : RRFm<"fcmp.d", 0x7E, I64, f64>;
1290let cx = 1 in
1291defm FCMPS : RRFm<"fcmp.s", 0x7E, F32, f32, null_frag, simm7fp, mimmfp32>;
1292
1293// Section 8.7.6 - CMS (Compare and Select Maximum/Minimum Single)
1294// cx: double/float, cw: max/min
1295let cw = 0, cx = 0 in
1296defm FMAXD : RRFm<"fmax.d", 0x3E, I64, f64, fmaxnum>;
1297let cw = 0, cx = 1 in
1298defm FMAXS : RRFm<"fmax.s", 0x3E, F32, f32, fmaxnum, simm7fp, mimmfp32>;
1299let cw = 1, cx = 0 in
1300defm FMIND : RRFm<"fmin.d", 0x3E, I64, f64, fminnum>;
1301let cw = 1, cx = 1 in
1302defm FMINS : RRFm<"fmin.s", 0x3E, F32, f32, fminnum, simm7fp, mimmfp32>;
1303
1304// Section 8.7.7 - FAQ (Floating Add Quadruple)
1305defm FADDQ : RRFm<"fadd.q", 0x6C, F128, f128>;
1306
1307// Section 8.7.8 - FSQ (Floating Subtract Quadruple)
1308defm FSUBQ : RRFm<"fsub.q", 0x7C, F128, f128>;
1309
1310// Section 8.7.9 - FMQ (Floating Subtract Quadruple)
1311defm FMULQ : RRFm<"fmul.q", 0x6D, F128, f128>;
1312
1313// Section 8.7.10 - FCQ (Floating Compare Quadruple)
1314defm FCMPQ : RRNCbm<"fcmp.q", 0x7D, I64, f64, F128, f128, null_frag, simm7fp,
1315                    mimmfp>;
1316
1317// Section 8.7.11 - FIX (Convert to Fixed Point)
1318// cx: double/float, cw: sx/zx, sz{0-3} = round
1319let cx = 0, cw = 0 /* sign extend */ in
1320defm CVTWDSX : CVTRDm<"cvt.w.d.sx", 0x4E, I32, i32, I64, f64>;
1321let cx = 0, cw = 1 /* zero extend */ in
1322defm CVTWDZX : CVTRDm<"cvt.w.d.zx", 0x4E, I32, i32, I64, f64>;
1323let cx = 1, cw = 0 /* sign extend */ in
1324defm CVTWSSX : CVTRDm<"cvt.w.s.sx", 0x4E, I32, i32, F32, f32>;
1325let cx = 1, cw = 1 /* zero extend */ in
1326defm CVTWSZX : CVTRDm<"cvt.w.s.zx", 0x4E, I32, i32, F32, f32>;
1327
1328// Section 8.7.12 - FIXX (Convert to Fixed Point)
1329defm CVTLD : CVTRDm<"cvt.l.d", 0x4F, I64, i64, I64, f64>;
1330
1331// Section 8.7.13 - FLT (Convert to Floating Point)
1332defm CVTDW : CVTm<"cvt.d.w", 0x5E, I64, f64, I32, i32, sint_to_fp>;
1333let cx = 1 in
1334defm CVTSW : CVTm<"cvt.s.w", 0x5E, F32, f32, I32, i32, sint_to_fp>;
1335
1336// Section 8.7.14 - FLTX (Convert to Floating Point)
1337defm CVTDL : CVTm<"cvt.d.l", 0x5F, I64, f64, I64, i64, sint_to_fp>;
1338
1339// Section 8.7.15 - CVS (Convert to Single-format)
1340defm CVTSD : CVTm<"cvt.s.d", 0x1F, F32, f32, I64, f64, fpround>;
1341let cx = 1 in
1342defm CVTSQ : CVTm<"cvt.s.q", 0x1F, F32, f32, F128, f128>;
1343
1344// Section 8.7.16 - CVD (Convert to Double-format)
1345defm CVTDS : CVTm<"cvt.d.s", 0x0F, I64, f64, F32, f32, fpextend>;
1346let cx = 1 in
1347defm CVTDQ : CVTm<"cvt.d.q", 0x0F, I64, f64, F128, f128>;
1348
1349// Section 8.7.17 - CVQ (Convert to Single-format)
1350defm CVTQD : CVTm<"cvt.q.d", 0x2D, F128, f128, I64, f64>;
1351let cx = 1 in
1352defm CVTQS : CVTm<"cvt.q.s", 0x2D, F128, f128, F32, f32>;
1353
1354//-----------------------------------------------------------------------------
1355// Section 8.8 - Branch instructions
1356//-----------------------------------------------------------------------------
1357
1358// Section 8.8.1 - BC (Branch on Codition)
1359defm BCFL : BCm<"b${cond}.l", "b.l", "baf.l", 0x19, I64, simm7>;
1360
1361// Indirect branch aliases
1362def : Pat<(brind I64:$reg), (BCFLari_t $reg, 0)>;
1363def : Pat<(brind tblockaddress:$imm), (BCFLazi_t 0, $imm)>;
1364
1365// Return instruction is a special case of jump.
1366let Uses = [SX10], bpf = 3 /* TAKEN */, cf = 15 /* AT */, cy = 0, sy = 0,
1367    sz = 10 /* SX10 */, imm32 = 0, isReturn = 1, isTerminator = 1,
1368    isBarrier = 1, isCodeGenOnly = 1, hasSideEffects = 0 in
1369def RET : CF<0x19, (outs), (ins), "b.l.t (, %s10)", [(retflag)]>;
1370
1371// Section 8.8.2 - BCS (Branch on Condition Single)
1372defm BCFW : BCm<"b${cond}.w", "b.w", "baf.w", 0x1B, I32, simm7>;
1373
1374// Section 8.8.3 - BCF (Branch on Condition Floating Point)
1375defm BCFD : BCm<"b${cond}.d", "b.d", "baf.d", 0x1C, I64, simm7fp>;
1376let cx = 1 in
1377defm BCFS : BCm<"b${cond}.s", "b.s", "baf.s", 0x1C, F32, simm7fp>;
1378
1379// Section 8.8.4 - BCR (Branch on Condition Relative)
1380let cx = 0, cx2 = 0 in
1381defm BRCFL : BCRm<"br${cf}.l", "br.l", "braf.l", 0x18, I64, simm7>;
1382let cx = 1, cx2 = 0 in
1383defm BRCFW : BCRm<"br${cf}.w", "br.w", "braf.w", 0x18, I32, simm7>;
1384let cx = 0, cx2 = 1 in
1385defm BRCFD : BCRm<"br${cf}.d", "br.d", "braf.d", 0x18, I64, simm7fp>;
1386let cx = 1, cx2 = 1 in
1387defm BRCFS : BCRm<"br${cf}.s", "br.s", "braf.s", 0x18, F32, simm7fp>;
1388
1389// Section 8.8.5 - BSIC (Branch and Save IC)
1390let isCall = 1, hasSideEffects = 0, DecoderMethod = "DecodeCall" in
1391defm BSIC : RMm<"bsic", 0x08, I64>;
1392
1393// Call instruction is a special case of BSIC.
1394let Defs = [SX10], sx = 10 /* SX10 */, cy = 0, sy = 0, imm32 = 0,
1395    isCall = 1, isCodeGenOnly = 1, hasSideEffects = 0 in
1396def CALLr : RM<0x08, (outs), (ins I64:$sz, variable_ops),
1397               "bsic %s10, (, $sz)", [(call i64:$sz)]>;
1398
1399//-----------------------------------------------------------------------------
1400// Section 8.19 - Control Instructions
1401//-----------------------------------------------------------------------------
1402
1403// Section 8.19.1 - SIC (Save Instruction Counter)
1404let cy = 0, sy = 0, cz = 0, sz = 0, hasSideEffects = 1, Uses = [IC] in
1405def SIC : RR<0x28, (outs I32:$sx), (ins), "sic $sx">;
1406
1407// Section 8.19.2 - LPM (Load Program Mode Flags)
1408let sx = 0, cz = 0, sz = 0, hasSideEffects = 1, Defs = [PSW] in
1409def LPM : RR<0x3a, (outs), (ins I64:$sy), "lpm $sy">;
1410
1411// Section 8.19.3 - SPM (Save Program Mode Flags)
1412let cy = 0, sy = 0, cz = 0, sz = 0, hasSideEffects = 1, Uses = [PSW] in
1413def SPM : RR<0x2a, (outs I64:$sx), (ins), "spm $sx">;
1414
1415// Section 8.19.4 - LFR (Load Flag Register)
1416let sx = 0, cz = 0, sz = 0, hasSideEffects = 1, Defs = [PSW] in {
1417  def LFRr : RR<0x69, (outs), (ins I64:$sy), "lfr $sy">;
1418  let cy = 0 in def LFRi : RR<0x69, (outs), (ins uimm6:$sy), "lfr $sy">;
1419}
1420
1421// Section 8.19.5 - SFR (Save Flag Register)
1422let cy = 0, sy = 0, cz = 0, sz = 0, hasSideEffects = 1, Uses = [PSW] in
1423def SFR : RR<0x29, (outs I64:$sx), (ins), "sfr $sx">;
1424
1425// Section 8.19.6 - SMIR (Save Miscellaneous Register)
1426let cy = 0, cz = 0, sz = 0, hasSideEffects = 1 in {
1427  def SMIR : RR<0x22, (outs I64:$sx), (ins MISC:$sy), "smir $sx, $sy">;
1428}
1429
1430// Section 8.19.7 - NOP (No Operation)
1431let sx = 0, cy = 0, sy = 0, cz = 0, sz = 0, hasSideEffects = 0 in
1432def NOP : RR<0x79, (outs), (ins), "nop">;
1433
1434// Section 8.19.8 - MONC (Monitor Call)
1435let sx = 0, cy = 0, sy = 0, cz = 0, sz = 0, hasSideEffects = 1 in {
1436  def MONC : RR<0x3F, (outs), (ins), "monc">;
1437  let cx = 1, isTrap = 1 in def MONCHDB : RR<0x3F, (outs), (ins), "monc.hdb">;
1438}
1439
1440// Section 8.19.9 - LCR (Load Communication Register)
1441defm LCR : LOADCRm<"lcr", 0x40, I64>;
1442
1443// Section 8.19.10 - SCR (Save Communication Register)
1444defm SCR : STORECRm<"scr", 0x50, I64>;
1445
1446// Section 8.19.11 - TSCR (Test & Set Communication Register)
1447defm TSCR : LOADCRm<"tscr", 0x41, I64>;
1448
1449// Section 8.19.12 - FIDCR (Fetch & Increment/Decrement CR)
1450defm FIDCR : FIDCRm<"fidcr", 0x51, I64>;
1451
1452//-----------------------------------------------------------------------------
1453// Section 8.20 - Host Memory Access Instructions
1454//-----------------------------------------------------------------------------
1455
1456// Section 8.20.1 - LHM (Load Host Memory)
1457let ry = 3, DecoderMethod = "DecodeLoadASI64" in
1458defm LHML : LHMm<"lhm.l", 0x21, I64>;
1459let ry = 2, DecoderMethod = "DecodeLoadASI64" in
1460defm LHMW : LHMm<"lhm.w", 0x21, I64>;
1461let ry = 1, DecoderMethod = "DecodeLoadASI64" in
1462defm LHMH : LHMm<"lhm.h", 0x21, I64>;
1463let ry = 0, DecoderMethod = "DecodeLoadASI64" in
1464defm LHMB : LHMm<"lhm.b", 0x21, I64>;
1465
1466// Section 8.20.2 - SHM (Store Host Memory)
1467let ry = 3, DecoderMethod = "DecodeStoreASI64" in
1468defm SHML : SHMm<"shm.l", 0x31, I64>;
1469let ry = 2, DecoderMethod = "DecodeStoreASI64" in
1470defm SHMW : SHMm<"shm.w", 0x31, I64>;
1471let ry = 1, DecoderMethod = "DecodeStoreASI64" in
1472defm SHMH : SHMm<"shm.h", 0x31, I64>;
1473let ry = 0, DecoderMethod = "DecodeStoreASI64" in
1474defm SHMB : SHMm<"shm.b", 0x31, I64>;
1475
1476//===----------------------------------------------------------------------===//
1477// Instructions for CodeGenOnly
1478//===----------------------------------------------------------------------===//
1479
1480//===----------------------------------------------------------------------===//
1481// Pattern Matchings
1482//===----------------------------------------------------------------------===//
1483
1484// Small immediates.
1485def : Pat<(i32 simm7:$val), (OR32im (LO7 $val), 0)>;
1486def : Pat<(i64 simm7:$val), (ORim (LO7 $val), 0)>;
1487// Medium immediates.
1488def : Pat<(i32 simm32:$val), (LEA32zii 0, 0, (LO32 $val))>;
1489def : Pat<(i64 simm32:$val), (LEAzii 0, 0, (LO32 $val))>;
1490def : Pat<(i64 uimm32:$val), (ANDrm (LEAzii 0, 0, (LO32 $val)), !add(32, 64))>;
1491// Arbitrary immediates.
1492def : Pat<(i64 lozero:$val),
1493          (LEASLzii 0, 0, (HI32 imm:$val))>;
1494def : Pat<(i64 lomsbzero:$val),
1495          (LEASLrii (LEAzii 0, 0, (LO32 imm:$val)), 0, (HI32 imm:$val))>;
1496def : Pat<(i64 imm:$val),
1497          (LEASLrii (ANDrm (LEAzii 0, 0, (LO32 imm:$val)), !add(32, 64)), 0,
1498                    (HI32 imm:$val))>;
1499
1500// floating point
1501def : Pat<(f32 fpimm:$val),
1502          (EXTRACT_SUBREG (LEASLzii 0, 0, (HIFP32 $val)), sub_f32)>;
1503def : Pat<(f64 fplozero:$val),
1504          (LEASLzii 0, 0, (HIFP32 $val))>;
1505def : Pat<(f64 fplomsbzero:$val),
1506          (LEASLrii (LEAzii 0, 0, (LOFP32 $val)), 0, (HIFP32 $val))>;
1507def : Pat<(f64 fpimm:$val),
1508          (LEASLrii (ANDrm (LEAzii 0, 0, (LOFP32 $val)), !add(32, 64)), 0,
1509                    (HIFP32 $val))>;
1510
1511// The same integer registers are used for i32 and i64 values.
1512// When registers hold i32 values, the high bits are unused.
1513
1514// TODO Use standard expansion for shift-based lowering of sext_inreg
1515
1516// Cast to i1
1517def : Pat<(sext_inreg I32:$src, i1),
1518          (SRAWSXri (SLAWSXri $src, 31), 31)>;
1519def : Pat<(sext_inreg I64:$src, i1),
1520          (SRALri (SLLri $src, 63), 63)>;
1521
1522// Cast to i8
1523def : Pat<(sext_inreg I32:$src, i8),
1524          (SRAWSXri (SLAWSXri $src, 24), 24)>;
1525def : Pat<(sext_inreg I64:$src, i8),
1526          (SRALri (SLLri $src, 56), 56)>;
1527def : Pat<(sext_inreg (i32 (trunc i64:$src)), i8),
1528          (EXTRACT_SUBREG (SRALri (SLLri $src, 56), 56), sub_i32)>;
1529def : Pat<(and (trunc i64:$src), 0xff),
1530          (AND32rm (EXTRACT_SUBREG $src, sub_i32), !add(56, 64))>;
1531
1532// Cast to i16
1533def : Pat<(sext_inreg I32:$src, i16),
1534          (SRAWSXri (SLAWSXri $src, 16), 16)>;
1535def : Pat<(sext_inreg I64:$src, i16),
1536          (SRALri (SLLri $src, 48), 48)>;
1537def : Pat<(sext_inreg (i32 (trunc i64:$src)), i16),
1538          (EXTRACT_SUBREG (SRALri (SLLri $src, 48), 48), sub_i32)>;
1539def : Pat<(and (trunc i64:$src), 0xffff),
1540          (AND32rm (EXTRACT_SUBREG $src, sub_i32), !add(48, 64))>;
1541
1542// Cast to i32
1543def : Pat<(i32 (trunc i64:$src)),
1544          (ADDSWSXrm (EXTRACT_SUBREG $src, sub_i32), 0)>;
1545def : Pat<(i32 (fp_to_sint I64:$reg)), (CVTWDSXr RD_RZ, $reg)>;
1546def : Pat<(i32 (fp_to_sint F32:$reg)), (CVTWSSXr RD_RZ, $reg)>;
1547
1548// Cast to i64
1549def : Pat<(sext_inreg I64:$src, i32),
1550          (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
1551            (ADDSWSXrm (EXTRACT_SUBREG $src, sub_i32), 0), sub_i32)>;
1552def : Pat<(i64 (sext i32:$sy)),
1553          (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (ADDSWSXrm $sy, 0), sub_i32)>;
1554def : Pat<(i64 (zext i32:$sy)),
1555          (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (ADDSWZXrm $sy, 0), sub_i32)>;
1556def : Pat<(i64 (fp_to_sint f32:$sy)), (CVTLDr RD_RZ, (CVTDSr $sy))>;
1557def : Pat<(i64 (fp_to_sint I64:$reg)), (CVTLDr RD_RZ, $reg)>;
1558
1559// Cast to f32
1560def : Pat<(f32 (sint_to_fp i64:$sy)), (CVTSDr (CVTDLr i64:$sy))>;
1561
1562def : Pat<(i64 (anyext i32:$sy)),
1563          (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $sy, sub_i32)>;
1564
1565
1566// extload, sextload and zextload stuff
1567multiclass EXT64m<SDPatternOperator from,
1568                  SDPatternOperator torri,
1569                  SDPatternOperator torii,
1570                  SDPatternOperator tozri,
1571                  SDPatternOperator tozii> {
1572  def : Pat<(i64 (from ADDRrri:$addr)),
1573            (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (torri MEMrri:$addr),
1574                           sub_i32)>;
1575  def : Pat<(i64 (from ADDRrii:$addr)),
1576            (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (torii MEMrii:$addr),
1577                           sub_i32)>;
1578  def : Pat<(i64 (from ADDRzri:$addr)),
1579            (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (tozri MEMzri:$addr),
1580                           sub_i32)>;
1581  def : Pat<(i64 (from ADDRzii:$addr)),
1582            (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (tozii MEMzii:$addr),
1583                           sub_i32)>;
1584}
1585defm : EXT64m<sextloadi8, LD1BSXrri, LD1BSXrii, LD1BSXzri, LD1BSXzii>;
1586defm : EXT64m<zextloadi8, LD1BZXrri, LD1BZXrii, LD1BZXzri, LD1BZXzii>;
1587defm : EXT64m<extloadi8, LD1BZXrri, LD1BZXrii, LD1BZXzri, LD1BZXzii>;
1588defm : EXT64m<sextloadi16, LD2BSXrri, LD2BSXrii, LD2BSXzri, LD2BSXzii>;
1589defm : EXT64m<zextloadi16, LD2BZXrri, LD2BZXrii, LD2BZXzri, LD2BZXzii>;
1590defm : EXT64m<extloadi16, LD2BZXrri, LD2BZXrii, LD2BZXzri, LD2BZXzii>;
1591defm : EXT64m<sextloadi32, LDLSXrri, LDLSXrii, LDLSXzri, LDLSXzii>;
1592defm : EXT64m<zextloadi32, LDLZXrri, LDLZXrii, LDLZXzri, LDLZXzii>;
1593defm : EXT64m<extloadi32, LDLSXrri, LDLSXrii, LDLSXzri, LDLSXzii>;
1594
1595// anyextload
1596multiclass EXT32m<SDPatternOperator from,
1597                  SDPatternOperator torri,
1598                  SDPatternOperator torii,
1599                  SDPatternOperator tozri,
1600                  SDPatternOperator tozii> {
1601  def : Pat<(from ADDRrri:$addr), (torri MEMrri:$addr)>;
1602  def : Pat<(from ADDRrii:$addr), (torii MEMrii:$addr)>;
1603  def : Pat<(from ADDRzri:$addr), (tozri MEMzri:$addr)>;
1604  def : Pat<(from ADDRzii:$addr), (tozii MEMzii:$addr)>;
1605}
1606defm : EXT32m<extloadi8, LD1BZXrri, LD1BZXrii, LD1BZXzri, LD1BZXzii>;
1607defm : EXT32m<extloadi16, LD2BZXrri, LD2BZXrii, LD2BZXzri, LD2BZXzii>;
1608
1609// truncstore
1610multiclass TRUNC64m<SDPatternOperator from,
1611                    SDPatternOperator torri,
1612                    SDPatternOperator torii,
1613                    SDPatternOperator tozri,
1614                    SDPatternOperator tozii> {
1615  def : Pat<(from i64:$src, ADDRrri:$addr),
1616            (torri MEMrri:$addr, (EXTRACT_SUBREG $src, sub_i32))>;
1617  def : Pat<(from i64:$src, ADDRrii:$addr),
1618            (torii MEMrii:$addr, (EXTRACT_SUBREG $src, sub_i32))>;
1619  def : Pat<(from i64:$src, ADDRzri:$addr),
1620            (tozri MEMzri:$addr, (EXTRACT_SUBREG $src, sub_i32))>;
1621  def : Pat<(from i64:$src, ADDRzii:$addr),
1622            (tozii MEMzii:$addr, (EXTRACT_SUBREG $src, sub_i32))>;
1623}
1624defm : TRUNC64m<truncstorei8, ST1Brri, ST1Brii, ST1Bzri, ST1Bzii>;
1625defm : TRUNC64m<truncstorei16, ST2Brri, ST2Brii, ST2Bzri, ST2Bzii>;
1626defm : TRUNC64m<truncstorei32, STLrri, STLrii, STLzri, ST1Bzii>;
1627
1628// Address calculation and its optimization
1629def : Pat<(VEhi tglobaladdr:$in), (LEASLzii 0, 0, tglobaladdr:$in)>;
1630def : Pat<(VElo tglobaladdr:$in),
1631          (ANDrm (LEAzii 0, 0, tglobaladdr:$in), !add(32, 64))>;
1632def : Pat<(add (VEhi tglobaladdr:$in1), (VElo tglobaladdr:$in2)),
1633          (LEASLrii (ANDrm (LEAzii 0, 0, tglobaladdr:$in2), !add(32, 64)), 0,
1634                    (tglobaladdr:$in1))>;
1635
1636// GlobalTLS address calculation and its optimization
1637def : Pat<(VEhi tglobaltlsaddr:$in), (LEASLzii 0, 0, tglobaltlsaddr:$in)>;
1638def : Pat<(VElo tglobaltlsaddr:$in),
1639          (ANDrm (LEAzii 0, 0, tglobaltlsaddr:$in), !add(32, 64))>;
1640def : Pat<(add (VEhi tglobaltlsaddr:$in1), (VElo tglobaltlsaddr:$in2)),
1641          (LEASLrii (ANDrm (LEAzii 0, 0, tglobaltlsaddr:$in2), !add(32, 64)), 0,
1642                    (tglobaltlsaddr:$in1))>;
1643
1644// Address calculation and its optimization
1645def : Pat<(VEhi texternalsym:$in), (LEASLzii 0, 0, texternalsym:$in)>;
1646def : Pat<(VElo texternalsym:$in),
1647          (ANDrm (LEAzii 0, 0, texternalsym:$in), !add(32, 64))>;
1648def : Pat<(add (VEhi texternalsym:$in1), (VElo texternalsym:$in2)),
1649          (LEASLrii (ANDrm (LEAzii 0, 0, texternalsym:$in2), !add(32, 64)), 0,
1650                    (texternalsym:$in1))>;
1651
1652// Branches
1653def : Pat<(br bb:$addr), (BRCFLa bb:$addr)>;
1654
1655// brcc
1656// integer brcc
1657multiclass BRCCIm<ValueType ty, SDPatternOperator BrOpNode1,
1658                 SDPatternOperator BrOpNode2,
1659                 SDPatternOperator CmpOpNode1,
1660                 SDPatternOperator CmpOpNode2> {
1661  def : Pat<(brcc CCSIOp:$cond, ty:$l, simm7:$r, bb:$addr),
1662            (BrOpNode2 (icond2ccSwap $cond), (LO7 $r), $l, bb:$addr)>;
1663  def : Pat<(brcc CCSIOp:$cond, ty:$l, ty:$r, bb:$addr),
1664            (BrOpNode1 (icond2cc $cond), $l, $r, bb:$addr)>;
1665  def : Pat<(brcc CCUIOp:$cond, ty:$l, simm7:$r, bb:$addr),
1666            (BrOpNode2 (icond2cc $cond), 0, (CmpOpNode2 (LO7 $r), $l),
1667                       bb:$addr)>;
1668  def : Pat<(brcc CCUIOp:$cond, ty:$l, ty:$r, bb:$addr),
1669            (BrOpNode2 (icond2cc $cond), 0, (CmpOpNode1 $r, $l), bb:$addr)>;
1670}
1671defm : BRCCIm<i32, BRCFWrr, BRCFWir, CMPUWrr, CMPUWir>;
1672defm : BRCCIm<i64, BRCFLrr, BRCFLir, CMPULrr, CMPULir>;
1673
1674// floating point brcc
1675multiclass BRCCFm<ValueType ty, SDPatternOperator BrOpNode1,
1676                 SDPatternOperator BrOpNode2> {
1677  def : Pat<(brcc cond:$cond, ty:$l, simm7fp:$r, bb:$addr),
1678            (BrOpNode2 (fcond2ccSwap $cond), (LO7FP $r), $l, bb:$addr)>;
1679  def : Pat<(brcc cond:$cond, ty:$l, ty:$r, bb:$addr),
1680            (BrOpNode1 (fcond2cc $cond), $l, $r, bb:$addr)>;
1681}
1682defm : BRCCFm<f32, BRCFSrr, BRCFSir>;
1683defm : BRCCFm<f64, BRCFDrr, BRCFDir>;
1684
1685//===----------------------------------------------------------------------===//
1686// Pseudo Instructions
1687//===----------------------------------------------------------------------===//
1688
1689// GETGOT for PIC
1690let Defs = [SX15 /* %got */, SX16 /* %plt */], hasSideEffects = 0 in {
1691  def GETGOT : Pseudo<(outs getGOT:$getpcseq), (ins), "$getpcseq">;
1692}
1693
1694// GETFUNPLT for PIC
1695let hasSideEffects = 0 in
1696def GETFUNPLT : Pseudo<(outs I64:$dst), (ins i64imm:$addr),
1697                       "$dst, $addr",
1698                       [(set iPTR:$dst, (GetFunPLT tglobaladdr:$addr))] >;
1699
1700def : Pat<(GetFunPLT tglobaladdr:$dst),
1701          (GETFUNPLT tglobaladdr:$dst)>;
1702def : Pat<(GetFunPLT texternalsym:$dst),
1703          (GETFUNPLT texternalsym:$dst)>;
1704
1705// GETTLSADDR for TLS
1706let Defs = [SX0, SX10, SX12], hasSideEffects = 0 in
1707def GETTLSADDR : Pseudo<(outs), (ins i64imm:$addr),
1708                        "# GETTLSADDR $addr",
1709                        [(GetTLSAddr tglobaltlsaddr:$addr)] >;
1710
1711def : Pat<(GetTLSAddr tglobaltlsaddr:$dst),
1712          (GETTLSADDR tglobaltlsaddr:$dst)>;
1713
1714let Defs = [SX11], Uses = [SX11], hasSideEffects = 0 in {
1715def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i64imm:$amt, i64imm:$amt2),
1716                              "# ADJCALLSTACKDOWN $amt, $amt2",
1717                              [(callseq_start timm:$amt, timm:$amt2)]>;
1718def ADJCALLSTACKUP : Pseudo<(outs), (ins i64imm:$amt1, i64imm:$amt2),
1719                            "# ADJCALLSTACKUP $amt1",
1720                            [(callseq_end timm:$amt1, timm:$amt2)]>;
1721}
1722
1723let Defs = [SX8], Uses = [SX8, SX11], hasSideEffects = 0 in
1724def EXTEND_STACK : Pseudo<(outs), (ins),
1725                          "# EXTEND STACK",
1726                          []>;
1727let  hasSideEffects = 0 in
1728def EXTEND_STACK_GUARD : Pseudo<(outs), (ins),
1729                                "# EXTEND STACK GUARD",
1730                                []>;
1731
1732// Dynamic stack allocation yields a __llvm_grow_stack for VE targets.
1733// These calls are needed to probe the stack when allocating more over
1734// %s8 (%sl - stack limit).
1735
1736let Uses = [SX11], hasSideEffects = 1 in
1737def GETSTACKTOP : Pseudo<(outs I64:$dst), (ins),
1738                         "# GET STACK TOP",
1739                         [(set iPTR:$dst, (GetStackTop))]>;
1740// SETCC pattern matches
1741//
1742//   CMP  %tmp, lhs, rhs     ; compare lhs and rhs
1743//   or   %res, 0, (0)1      ; initialize by 0
1744//   CMOV %res, (63)0, %tmp  ; set 1 if %tmp is true
1745
1746def : Pat<(i32 (setcc i64:$LHS, i64:$RHS, CCSIOp:$cond)),
1747          (EXTRACT_SUBREG
1748              (CMOVLrm (icond2cc $cond),
1749                       (CMPSLrr i64:$LHS, i64:$RHS),
1750                       !add(63, 64),
1751                       (ORim 0, 0)), sub_i32)>;
1752
1753def : Pat<(i32 (setcc i64:$LHS, i64:$RHS, CCUIOp:$cond)),
1754          (EXTRACT_SUBREG
1755              (CMOVLrm (icond2cc $cond),
1756                       (CMPULrr i64:$LHS, i64:$RHS),
1757                       !add(63, 64),
1758                       (ORim 0, 0)), sub_i32)>;
1759
1760def : Pat<(i32 (setcc i32:$LHS, i32:$RHS, CCSIOp:$cond)),
1761          (EXTRACT_SUBREG
1762              (CMOVWrm (icond2cc $cond),
1763                       (CMPSWSXrr i32:$LHS, i32:$RHS),
1764                       !add(63, 64),
1765                       (ORim 0, 0)), sub_i32)>;
1766
1767def : Pat<(i32 (setcc i32:$LHS, i32:$RHS, CCUIOp:$cond)),
1768          (EXTRACT_SUBREG
1769              (CMOVWrm (icond2cc $cond),
1770                       (CMPUWrr i32:$LHS, i32:$RHS),
1771                       !add(63, 64),
1772                       (ORim 0, 0)), sub_i32)>;
1773
1774def : Pat<(i32 (setcc f64:$LHS, f64:$RHS, cond:$cond)),
1775          (EXTRACT_SUBREG
1776              (CMOVDrm (fcond2cc $cond),
1777                       (FCMPDrr f64:$LHS, f64:$RHS),
1778                       !add(63, 64),
1779                       (ORim 0, 0)), sub_i32)>;
1780
1781def : Pat<(i32 (setcc f32:$LHS, f32:$RHS, cond:$cond)),
1782          (EXTRACT_SUBREG
1783              (CMOVSrm (fcond2cc $cond),
1784                       (FCMPSrr f32:$LHS, f32:$RHS),
1785                       !add(63, 64),
1786                       (ORim 0, 0)), sub_i32)>;
1787
1788// Special SELECTCC pattern matches
1789// Use min/max for better performance.
1790//
1791//   MAX/MIN  %res, %lhs, %rhs
1792
1793def : Pat<(f64 (selectcc f64:$LHS, f64:$RHS, f64:$LHS, f64:$RHS, SETOGT)),
1794          (FMAXDrr $LHS, $RHS)>;
1795def : Pat<(f32 (selectcc f32:$LHS, f32:$RHS, f32:$LHS, f32:$RHS, SETOGT)),
1796          (FMAXSrr $LHS, $RHS)>;
1797def : Pat<(i64 (selectcc i64:$LHS, i64:$RHS, i64:$LHS, i64:$RHS, SETGT)),
1798          (MAXSLrr $LHS, $RHS)>;
1799def : Pat<(i32 (selectcc i32:$LHS, i32:$RHS, i32:$LHS, i32:$RHS, SETGT)),
1800          (MAXSWSXrr $LHS, $RHS)>;
1801def : Pat<(f64 (selectcc f64:$LHS, f64:$RHS, f64:$LHS, f64:$RHS, SETOGE)),
1802          (FMAXDrr $LHS, $RHS)>;
1803def : Pat<(f32 (selectcc f32:$LHS, f32:$RHS, f32:$LHS, f32:$RHS, SETOGE)),
1804          (FMAXSrr $LHS, $RHS)>;
1805def : Pat<(i64 (selectcc i64:$LHS, i64:$RHS, i64:$LHS, i64:$RHS, SETGE)),
1806          (MAXSLrr $LHS, $RHS)>;
1807def : Pat<(i32 (selectcc i32:$LHS, i32:$RHS, i32:$LHS, i32:$RHS, SETGE)),
1808          (MAXSWSXrr $LHS, $RHS)>;
1809
1810def : Pat<(f64 (selectcc f64:$LHS, f64:$RHS, f64:$LHS, f64:$RHS, SETOLT)),
1811          (FMINDrr $LHS, $RHS)>;
1812def : Pat<(f32 (selectcc f32:$LHS, f32:$RHS, f32:$LHS, f32:$RHS, SETOLT)),
1813          (FMINSrr $LHS, $RHS)>;
1814def : Pat<(i64 (selectcc i64:$LHS, i64:$RHS, i64:$LHS, i64:$RHS, SETLT)),
1815          (MINSLrr $LHS, $RHS)>;
1816def : Pat<(i32 (selectcc i32:$LHS, i32:$RHS, i32:$LHS, i32:$RHS, SETLT)),
1817          (MINSWSXrr $LHS, $RHS)>;
1818def : Pat<(f64 (selectcc f64:$LHS, f64:$RHS, f64:$LHS, f64:$RHS, SETOLE)),
1819          (FMINDrr $LHS, $RHS)>;
1820def : Pat<(f32 (selectcc f32:$LHS, f32:$RHS, f32:$LHS, f32:$RHS, SETOLE)),
1821          (FMINSrr $LHS, $RHS)>;
1822def : Pat<(i64 (selectcc i64:$LHS, i64:$RHS, i64:$LHS, i64:$RHS, SETLE)),
1823          (MINSLrr $LHS, $RHS)>;
1824def : Pat<(i32 (selectcc i32:$LHS, i32:$RHS, i32:$LHS, i32:$RHS, SETLE)),
1825          (MINSWSXrr $LHS, $RHS)>;
1826
1827// Generic SELECTCC pattern matches
1828//
1829//   CMP  %tmp, %l, %r       ; compare %l and %r
1830//   or   %res, %f, (0)1     ; initialize by %f
1831//   CMOV %res, %t, %tmp     ; set %t if %tmp is true
1832
1833// selectcc for i64 result
1834def : Pat<(i64 (selectcc i32:$l, i32:$r, i64:$t, i64:$f, CCSIOp:$cond)),
1835          (CMOVWrr (icond2cc $cond), (CMPSWSXrr $l, $r), $t, $f)>;
1836def : Pat<(i64 (selectcc i32:$l, i32:$r, i64:$t, i64:$f, CCUIOp:$cond)),
1837          (CMOVWrr (icond2cc $cond), (CMPUWrr $l, $r), $t, $f)>;
1838def : Pat<(i64 (selectcc i64:$l, i64:$r, i64:$t, i64:$f, CCSIOp:$cond)),
1839          (CMOVLrr (icond2cc $cond), (CMPSLrr $l, $r), $t, $f)>;
1840def : Pat<(i64 (selectcc i64:$l, i64:$r, i64:$t, i64:$f, CCUIOp:$cond)),
1841          (CMOVLrr (icond2cc $cond), (CMPULrr $l, $r), $t, $f)>;
1842def : Pat<(i64 (selectcc f32:$l, f32:$r, i64:$t, i64:$f, cond:$cond)),
1843          (CMOVSrr (fcond2cc $cond), (FCMPSrr $l, $r), $t, $f)>;
1844def : Pat<(i64 (selectcc f64:$l, f64:$r, i64:$t, i64:$f, cond:$cond)),
1845          (CMOVDrr (fcond2cc $cond), (FCMPDrr $l, $r), $t, $f)>;
1846
1847// selectcc for i32 result
1848def : Pat<(i32 (selectcc i32:$l, i32:$r, i32:$t, i32:$f, CCSIOp:$cond)),
1849          (EXTRACT_SUBREG
1850              (CMOVWrr (icond2cc $cond),
1851                       (CMPSWSXrr $l, $r),
1852                       (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $t, sub_i32),
1853                       (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $f, sub_i32)),
1854              sub_i32)>;
1855def : Pat<(i32 (selectcc i32:$l, i32:$r, i32:$t, i32:$f, CCUIOp:$cond)),
1856          (EXTRACT_SUBREG
1857              (CMOVWrr (icond2cc $cond),
1858                       (CMPUWrr $l, $r),
1859                       (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $t, sub_i32),
1860                       (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $f, sub_i32)),
1861              sub_i32)>;
1862def : Pat<(i32 (selectcc i64:$l, i64:$r, i32:$t, i32:$f, CCSIOp:$cond)),
1863          (EXTRACT_SUBREG
1864              (CMOVLrr (icond2cc $cond),
1865                       (CMPSLrr $l, $r),
1866                       (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $t, sub_i32),
1867                       (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $f, sub_i32)),
1868              sub_i32)>;
1869def : Pat<(i32 (selectcc i64:$l, i64:$r, i32:$t, i32:$f, CCUIOp:$cond)),
1870          (EXTRACT_SUBREG
1871              (CMOVLrr (icond2cc $cond),
1872                       (CMPULrr $l, $r),
1873                       (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $t, sub_i32),
1874                       (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $f, sub_i32)),
1875              sub_i32)>;
1876def : Pat<(i32 (selectcc f32:$l, f32:$r, i32:$t, i32:$f, cond:$cond)),
1877          (EXTRACT_SUBREG
1878              (CMOVSrr (fcond2cc $cond),
1879                       (FCMPSrr $l, $r),
1880                       (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $t, sub_i32),
1881                       (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $f, sub_i32)),
1882              sub_i32)>;
1883def : Pat<(i32 (selectcc f64:$l, f64:$r, i32:$t, i32:$f, cond:$cond)),
1884          (EXTRACT_SUBREG
1885              (CMOVDrr (fcond2cc $cond),
1886                       (FCMPDrr $l, $r),
1887                       (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $t, sub_i32),
1888                       (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $f, sub_i32)),
1889              sub_i32)>;
1890
1891// selectcc for f64 result
1892def : Pat<(f64 (selectcc i32:$l, i32:$r, f64:$t, f64:$f, CCSIOp:$cond)),
1893          (CMOVWrr (icond2cc $cond), (CMPSWSXrr $l, $r), $t, $f)>;
1894def : Pat<(f64 (selectcc i32:$l, i32:$r, f64:$t, f64:$f, CCUIOp:$cond)),
1895          (CMOVWrr (icond2cc $cond), (CMPUWrr $l, $r), $t, $f)>;
1896def : Pat<(f64 (selectcc i64:$l, i64:$r, f64:$t, f64:$f, CCSIOp:$cond)),
1897          (CMOVLrr (icond2cc $cond), (CMPSLrr $l, $r), $t, $f)>;
1898def : Pat<(f64 (selectcc i64:$l, i64:$r, f64:$t, f64:$f, CCUIOp:$cond)),
1899          (CMOVLrr (icond2cc $cond), (CMPULrr $l, $r), $t, $f)>;
1900def : Pat<(f64 (selectcc f32:$l, f32:$r, f64:$t, f64:$f, cond:$cond)),
1901          (CMOVSrr (fcond2cc $cond), (FCMPSrr $l, $r), $t, $f)>;
1902def : Pat<(f64 (selectcc f64:$l, f64:$r, f64:$t, f64:$f, cond:$cond)),
1903          (CMOVDrr (fcond2cc $cond), (FCMPDrr $l, $r), $t, $f)>;
1904
1905// selectcc for f32 result
1906def : Pat<(f32 (selectcc i32:$l, i32:$r, f32:$t, f32:$f, CCSIOp:$cond)),
1907          (EXTRACT_SUBREG
1908              (CMOVWrr (icond2cc $cond),
1909                       (CMPSWSXrr $l, $r),
1910                       (INSERT_SUBREG (f64 (IMPLICIT_DEF)), $t, sub_f32),
1911                       (INSERT_SUBREG (f64 (IMPLICIT_DEF)), $f, sub_f32)),
1912              sub_f32)>;
1913def : Pat<(f32 (selectcc i32:$l, i32:$r, f32:$t, f32:$f, CCUIOp:$cond)),
1914          (EXTRACT_SUBREG
1915              (CMOVWrr (icond2cc $cond),
1916                       (CMPUWrr $l, $r),
1917                       (INSERT_SUBREG (f64 (IMPLICIT_DEF)), $t, sub_f32),
1918                       (INSERT_SUBREG (f64 (IMPLICIT_DEF)), $f, sub_f32)),
1919              sub_f32)>;
1920def : Pat<(f32 (selectcc i64:$l, i64:$r, f32:$t, f32:$f, CCSIOp:$cond)),
1921          (EXTRACT_SUBREG
1922              (CMOVLrr (icond2cc $cond),
1923                       (CMPSLrr $l, $r),
1924                       (INSERT_SUBREG (f64 (IMPLICIT_DEF)), $t, sub_f32),
1925                       (INSERT_SUBREG (f64 (IMPLICIT_DEF)), $f, sub_f32)),
1926              sub_f32)>;
1927def : Pat<(f32 (selectcc i64:$l, i64:$r, f32:$t, f32:$f, CCUIOp:$cond)),
1928          (EXTRACT_SUBREG
1929              (CMOVLrr (icond2cc $cond),
1930                       (CMPULrr $l, $r),
1931                       (INSERT_SUBREG (f64 (IMPLICIT_DEF)), $t, sub_f32),
1932                       (INSERT_SUBREG (f64 (IMPLICIT_DEF)), $f, sub_f32)),
1933              sub_f32)>;
1934def : Pat<(f32 (selectcc f32:$l, f32:$r, f32:$t, f32:$f, cond:$cond)),
1935          (EXTRACT_SUBREG
1936              (CMOVSrr (fcond2cc $cond),
1937                       (FCMPSrr $l, $r),
1938                       (INSERT_SUBREG (f64 (IMPLICIT_DEF)), $t, sub_f32),
1939                       (INSERT_SUBREG (f64 (IMPLICIT_DEF)), $f, sub_f32)),
1940              sub_f32)>;
1941def : Pat<(f32 (selectcc f64:$l, f64:$r, f32:$t, f32:$f, cond:$cond)),
1942          (EXTRACT_SUBREG
1943              (CMOVDrr (fcond2cc $cond),
1944                       (FCMPDrr $l, $r),
1945                       (INSERT_SUBREG (f64 (IMPLICIT_DEF)), $t, sub_f32),
1946                       (INSERT_SUBREG (f64 (IMPLICIT_DEF)), $f, sub_f32)),
1947              sub_f32)>;
1948
1949// Generic SELECT pattern matches
1950// Use cmov.w for all cases since %pred holds i32.
1951//
1952//   CMOV.w.ne %res, %tval, %tmp  ; set tval if %tmp is true
1953
1954def : Pat<(i64 (select i32:$pred, i64:$t, i64:$f)),
1955          (CMOVWrr CC_INE, $pred, $t, $f)>;
1956
1957def : Pat<(i32 (select i32:$pred, i32:$t, i32:$f)),
1958          (EXTRACT_SUBREG
1959              (CMOVWrr CC_INE, $pred,
1960                       (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $t, sub_i32),
1961                       (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $f, sub_i32)),
1962              sub_i32)>;
1963
1964def : Pat<(f64 (select i32:$pred, f64:$t, f64:$f)),
1965          (CMOVWrr CC_INE, $pred, $t, $f)>;
1966
1967def : Pat<(f32 (select i32:$pred, f32:$t, f32:$f)),
1968          (EXTRACT_SUBREG
1969            (CMOVWrr CC_INE, $pred,
1970                     (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $t, sub_f32),
1971                     (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $f, sub_f32)),
1972            sub_f32)>;
1973
1974// bitconvert
1975def : Pat<(f64 (bitconvert i64:$src)), (COPY_TO_REGCLASS $src, I64)>;
1976def : Pat<(i64 (bitconvert f64:$src)), (COPY_TO_REGCLASS $src, I64)>;
1977
1978def : Pat<(i32 (bitconvert f32:$op)),
1979          (EXTRACT_SUBREG (SRALri (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
1980            $op, sub_f32), 32), sub_i32)>;
1981def : Pat<(f32 (bitconvert i32:$op)),
1982          (EXTRACT_SUBREG (SLLri (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
1983            $op, sub_i32), 32), sub_f32)>;
1984
1985// Bits operations pattern matchings.
1986def : Pat<(i32 (ctpop i32:$src)),
1987          (EXTRACT_SUBREG (PCNTr (ANDrm (INSERT_SUBREG
1988            (i64 (IMPLICIT_DEF)), $src, sub_i32), !add(32, 64))), sub_i32)>;
1989def : Pat<(i32 (ctlz i32:$src)),
1990          (EXTRACT_SUBREG (LDZr (SLLri (INSERT_SUBREG
1991            (i64 (IMPLICIT_DEF)), $src, sub_i32), 32)), sub_i32)>;
1992def : Pat<(i64 (bswap i64:$src)),
1993          (BSWPri $src, 0)>;
1994def : Pat<(i32 (bswap i32:$src)),
1995          (EXTRACT_SUBREG (BSWPri (INSERT_SUBREG
1996            (i64 (IMPLICIT_DEF)), $src, sub_i32), 1), sub_i32)>;
1997
1998// Several special pattern matches to optimize code
1999
2000def : Pat<(i32 (and i32:$lhs, 0xff)),
2001          (AND32rm $lhs, !add(56, 64))>;
2002def : Pat<(i32 (and i32:$lhs, 0xffff)),
2003          (AND32rm $lhs, !add(48, 64))>;
2004def : Pat<(i32 (and i32:$lhs, 0xffffffff)),
2005          (AND32rm $lhs, !add(32, 64))>;
2006