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