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