xref: /freebsd/contrib/llvm-project/llvm/lib/Target/VE/VEInstrInfo.td (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1480093f4SDimitry Andric//===-- VEInstrInfo.td - Target Description for VE Target -----------------===//
2480093f4SDimitry Andric//
3480093f4SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4480093f4SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
5480093f4SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6480093f4SDimitry Andric//
7480093f4SDimitry Andric//===----------------------------------------------------------------------===//
8480093f4SDimitry Andric//
9480093f4SDimitry Andric// This file describes the VE instructions in TableGen format.
10480093f4SDimitry Andric//
11480093f4SDimitry Andric//===----------------------------------------------------------------------===//
12480093f4SDimitry Andric
13480093f4SDimitry Andric//===----------------------------------------------------------------------===//
14480093f4SDimitry Andric// Instruction format superclass
15480093f4SDimitry Andric//===----------------------------------------------------------------------===//
16480093f4SDimitry Andric
17480093f4SDimitry Andricinclude "VEInstrFormats.td"
18480093f4SDimitry Andric
19480093f4SDimitry Andric//===----------------------------------------------------------------------===//
205ffd83dbSDimitry Andric// Helper functions to retrieve target constants.
215ffd83dbSDimitry Andric//
225ffd83dbSDimitry Andric// VE instructions have a space to hold following immediates
235ffd83dbSDimitry Andric//   $sy has 7 bits to represent simm7, uimm7, simm7fp, or uimm7fp.
245ffd83dbSDimitry Andric//   $sz also has 7 bits to represent mimm or mimmfp.
255ffd83dbSDimitry Andric//   $disp has 32 bits to represent simm32.
265ffd83dbSDimitry Andric//
275ffd83dbSDimitry Andric// The mimm is a special immediate value of sequential bit stream of 0 or 1.
285ffd83dbSDimitry Andric//     `(m)0`: Represents 0 sequence then 1 sequence like 0b00...0011...11,
295ffd83dbSDimitry Andric//             where `m` is equal to the number of leading zeros.
305ffd83dbSDimitry Andric//     `(m)1`: Represents 1 sequence then 0 sequence like 0b11...1100...00,
315ffd83dbSDimitry Andric//             where `m` is equal to the number of leading ones.
325ffd83dbSDimitry Andric// Each bit of mimm's 7 bits is used like below:
335ffd83dbSDimitry Andric//     bit 6  : If `(m)0`, this bit is 1.  Otherwise, this bit is 0.
345ffd83dbSDimitry Andric//     bit 5-0: Represents the m (0-63).
355ffd83dbSDimitry Andric// Use `!add(m, 64)` to generates an immediate value in pattern matchings.
365ffd83dbSDimitry Andric//
375ffd83dbSDimitry Andric// The floating point immediate value is not something like compacted value.
385ffd83dbSDimitry Andric// It is simple integer representation, so it works rarely.
395ffd83dbSDimitry Andric//     e.g. 0.0 (0x00000000) or -2.0 (0xC0000000=(2)1).
405ffd83dbSDimitry Andric//===----------------------------------------------------------------------===//
415ffd83dbSDimitry Andric
425ffd83dbSDimitry Andricdef ULO7 : SDNodeXForm<imm, [{
435ffd83dbSDimitry Andric  return CurDAG->getTargetConstant(N->getZExtValue() & 0x7f,
445ffd83dbSDimitry Andric                                   SDLoc(N), MVT::i32);
455ffd83dbSDimitry Andric}]>;
465ffd83dbSDimitry Andricdef LO7 : SDNodeXForm<imm, [{
475ffd83dbSDimitry Andric  return CurDAG->getTargetConstant(SignExtend32(N->getSExtValue(), 7),
485ffd83dbSDimitry Andric                                   SDLoc(N), MVT::i32);
495ffd83dbSDimitry Andric}]>;
505ffd83dbSDimitry Andricdef MIMM : SDNodeXForm<imm, [{
51e8d8bef9SDimitry Andric  return CurDAG->getTargetConstant(val2MImm(getImmVal(N)),
525ffd83dbSDimitry Andric                                   SDLoc(N), MVT::i32);
535ffd83dbSDimitry Andric}]>;
545ffd83dbSDimitry Andricdef LO32 : SDNodeXForm<imm, [{
555ffd83dbSDimitry Andric  return CurDAG->getTargetConstant(Lo_32(N->getZExtValue()),
565ffd83dbSDimitry Andric                                   SDLoc(N), MVT::i32);
575ffd83dbSDimitry Andric}]>;
585ffd83dbSDimitry Andricdef HI32 : SDNodeXForm<imm, [{
595ffd83dbSDimitry Andric  // Transformation function: shift the immediate value down into the low bits.
605ffd83dbSDimitry Andric  return CurDAG->getTargetConstant(Hi_32(N->getZExtValue()),
615ffd83dbSDimitry Andric                                   SDLoc(N), MVT::i32);
625ffd83dbSDimitry Andric}]>;
635ffd83dbSDimitry Andric
645ffd83dbSDimitry Andricdef LO7FP : SDNodeXForm<fpimm, [{
655ffd83dbSDimitry Andric  uint64_t Val = getFpImmVal(N);
665ffd83dbSDimitry Andric  return CurDAG->getTargetConstant(SignExtend32(Val, 7), SDLoc(N), MVT::i32);
675ffd83dbSDimitry Andric}]>;
685ffd83dbSDimitry Andricdef MIMMFP : SDNodeXForm<fpimm, [{
69e8d8bef9SDimitry Andric  return CurDAG->getTargetConstant(val2MImm(getFpImmVal(N)),
705ffd83dbSDimitry Andric                                   SDLoc(N), MVT::i32);
715ffd83dbSDimitry Andric}]>;
725ffd83dbSDimitry Andricdef LOFP32 : SDNodeXForm<fpimm, [{
735ffd83dbSDimitry Andric  return CurDAG->getTargetConstant(Lo_32(getFpImmVal(N) & 0xffffffff),
745ffd83dbSDimitry Andric                                   SDLoc(N), MVT::i32);
755ffd83dbSDimitry Andric}]>;
765ffd83dbSDimitry Andricdef HIFP32 : SDNodeXForm<fpimm, [{
775ffd83dbSDimitry Andric  return CurDAG->getTargetConstant(Hi_32(getFpImmVal(N)), SDLoc(N), MVT::i32);
785ffd83dbSDimitry Andric}]>;
795ffd83dbSDimitry Andric
805ffd83dbSDimitry Andricdef icond2cc : SDNodeXForm<cond, [{
815ffd83dbSDimitry Andric  VECC::CondCode VECC = intCondCode2Icc(N->get());
825ffd83dbSDimitry Andric  return CurDAG->getTargetConstant(VECC, SDLoc(N), MVT::i32);
835ffd83dbSDimitry Andric}]>;
845ffd83dbSDimitry Andric
855ffd83dbSDimitry Andricdef icond2ccSwap : SDNodeXForm<cond, [{
865ffd83dbSDimitry Andric  ISD::CondCode CC = getSetCCSwappedOperands(N->get());
875ffd83dbSDimitry Andric  VECC::CondCode VECC = intCondCode2Icc(CC);
885ffd83dbSDimitry Andric  return CurDAG->getTargetConstant(VECC, SDLoc(N), MVT::i32);
895ffd83dbSDimitry Andric}]>;
905ffd83dbSDimitry Andric
915ffd83dbSDimitry Andricdef fcond2cc : SDNodeXForm<cond, [{
925ffd83dbSDimitry Andric  VECC::CondCode VECC = fpCondCode2Fcc(N->get());
935ffd83dbSDimitry Andric  return CurDAG->getTargetConstant(VECC, SDLoc(N), MVT::i32);
945ffd83dbSDimitry Andric}]>;
955ffd83dbSDimitry Andric
965ffd83dbSDimitry Andricdef fcond2ccSwap : SDNodeXForm<cond, [{
975ffd83dbSDimitry Andric  ISD::CondCode CC = getSetCCSwappedOperands(N->get());
985ffd83dbSDimitry Andric  VECC::CondCode VECC = fpCondCode2Fcc(CC);
995ffd83dbSDimitry Andric  return CurDAG->getTargetConstant(VECC, SDLoc(N), MVT::i32);
1005ffd83dbSDimitry Andric}]>;
1015ffd83dbSDimitry Andric
1025ffd83dbSDimitry Andricdef CCOP : SDNodeXForm<imm, [{
1035ffd83dbSDimitry Andric  return CurDAG->getTargetConstant(N->getZExtValue(),
1045ffd83dbSDimitry Andric                                   SDLoc(N), MVT::i32);
1055ffd83dbSDimitry Andric}]>;
1065ffd83dbSDimitry Andric
1075ffd83dbSDimitry Andric//===----------------------------------------------------------------------===//
108480093f4SDimitry Andric// Feature predicates.
109480093f4SDimitry Andric//===----------------------------------------------------------------------===//
110480093f4SDimitry Andric
111480093f4SDimitry Andric//===----------------------------------------------------------------------===//
112480093f4SDimitry Andric// Instruction Pattern Stuff
113480093f4SDimitry Andric//===----------------------------------------------------------------------===//
114480093f4SDimitry Andric
1155ffd83dbSDimitry Andric// zero
1165ffd83dbSDimitry Andricdef ZeroAsmOperand : AsmOperandClass {
1175ffd83dbSDimitry Andric  let Name = "Zero";
1185ffd83dbSDimitry Andric}
1195ffd83dbSDimitry Andricdef zero : Operand<i32>, PatLeaf<(imm), [{
1205ffd83dbSDimitry Andric    return N->getSExtValue() == 0; }]> {
1215ffd83dbSDimitry Andric  let ParserMatchClass = ZeroAsmOperand;
122480093f4SDimitry Andric}
123480093f4SDimitry Andric
1245ffd83dbSDimitry Andric// uimm0to2 - Special immediate value represents 0, 1, and 2.
1255ffd83dbSDimitry Andricdef UImm0to2AsmOperand : AsmOperandClass {
1265ffd83dbSDimitry Andric  let Name = "UImm0to2";
1275ffd83dbSDimitry Andric}
1285ffd83dbSDimitry Andricdef uimm0to2 : Operand<i32>, PatLeaf<(imm), [{
1295ffd83dbSDimitry Andric    return N->getZExtValue() < 3; }], ULO7> {
1305ffd83dbSDimitry Andric  let ParserMatchClass = UImm0to2AsmOperand;
131480093f4SDimitry Andric}
132480093f4SDimitry Andric
1335ffd83dbSDimitry Andric// uimm1 - Generic immediate value.
1345ffd83dbSDimitry Andricdef UImm1AsmOperand : AsmOperandClass {
1355ffd83dbSDimitry Andric  let Name = "UImm1";
1365ffd83dbSDimitry Andric}
1375ffd83dbSDimitry Andricdef uimm1 : Operand<i32>, PatLeaf<(imm), [{
1385ffd83dbSDimitry Andric    return isUInt<1>(N->getZExtValue()); }], ULO7> {
1395ffd83dbSDimitry Andric  let ParserMatchClass = UImm1AsmOperand;
140480093f4SDimitry Andric}
141480093f4SDimitry Andric
1425ffd83dbSDimitry Andric// uimm2 - Generic immediate value.
1435ffd83dbSDimitry Andricdef UImm2AsmOperand : AsmOperandClass {
1445ffd83dbSDimitry Andric  let Name = "UImm2";
1455ffd83dbSDimitry Andric}
1465ffd83dbSDimitry Andricdef uimm2 : Operand<i32>, PatLeaf<(imm), [{
1475ffd83dbSDimitry Andric    return isUInt<2>(N->getZExtValue()); }], ULO7> {
1485ffd83dbSDimitry Andric  let ParserMatchClass = UImm2AsmOperand;
1495ffd83dbSDimitry Andric}
1505ffd83dbSDimitry Andric
1515ffd83dbSDimitry Andric// uimm3 - Generic immediate value.
1525ffd83dbSDimitry Andricdef UImm3AsmOperand : AsmOperandClass {
1535ffd83dbSDimitry Andric  let Name = "UImm3";
1545ffd83dbSDimitry Andric}
1555ffd83dbSDimitry Andricdef uimm3 : Operand<i32>, PatLeaf<(imm), [{
1565ffd83dbSDimitry Andric    return isUInt<3>(N->getZExtValue()); }], ULO7> {
1575ffd83dbSDimitry Andric  let ParserMatchClass = UImm3AsmOperand;
1585ffd83dbSDimitry Andric}
1595ffd83dbSDimitry Andric
160e8d8bef9SDimitry Andric// uimm4 - Generic immediate value.
161e8d8bef9SDimitry Andricdef UImm4AsmOperand : AsmOperandClass {
162e8d8bef9SDimitry Andric  let Name = "UImm4";
163e8d8bef9SDimitry Andric}
164e8d8bef9SDimitry Andricdef uimm4 : Operand<i32>, PatLeaf<(imm), [{
165e8d8bef9SDimitry Andric    return isUInt<4>(N->getZExtValue()); }], ULO7> {
166e8d8bef9SDimitry Andric  let ParserMatchClass = UImm4AsmOperand;
167e8d8bef9SDimitry Andric}
168e8d8bef9SDimitry Andric
1695ffd83dbSDimitry Andric// uimm6 - Generic immediate value.
1705ffd83dbSDimitry Andricdef UImm6AsmOperand : AsmOperandClass {
1715ffd83dbSDimitry Andric  let Name = "UImm6";
1725ffd83dbSDimitry Andric}
1735ffd83dbSDimitry Andricdef uimm6 : Operand<i32>, PatLeaf<(imm), [{
1745ffd83dbSDimitry Andric    return isUInt<6>(N->getZExtValue()); }], ULO7> {
1755ffd83dbSDimitry Andric  let ParserMatchClass = UImm6AsmOperand;
1765ffd83dbSDimitry Andric}
1775ffd83dbSDimitry Andric
1785ffd83dbSDimitry Andric// uimm7 - Generic immediate value.
1795ffd83dbSDimitry Andricdef UImm7AsmOperand : AsmOperandClass {
1805ffd83dbSDimitry Andric  let Name = "UImm7";
1815ffd83dbSDimitry Andric}
1825ffd83dbSDimitry Andricdef uimm7 : Operand<i32>, PatLeaf<(imm), [{
1835ffd83dbSDimitry Andric    return isUInt<7>(N->getZExtValue()); }], ULO7> {
1845ffd83dbSDimitry Andric  let ParserMatchClass = UImm7AsmOperand;
1855ffd83dbSDimitry Andric}
1865ffd83dbSDimitry Andric
1875ffd83dbSDimitry Andric// simm7 - Generic immediate value.
1885ffd83dbSDimitry Andricdef SImm7AsmOperand : AsmOperandClass {
1895ffd83dbSDimitry Andric  let Name = "SImm7";
1905ffd83dbSDimitry Andric}
1915ffd83dbSDimitry Andricdef simm7 : Operand<i32>, PatLeaf<(imm), [{
1925ffd83dbSDimitry Andric    return isInt<7>(N->getSExtValue()); }], LO7> {
1935ffd83dbSDimitry Andric  let ParserMatchClass = SImm7AsmOperand;
194480093f4SDimitry Andric  let DecoderMethod = "DecodeSIMM7";
195480093f4SDimitry Andric}
196480093f4SDimitry Andric
1975ffd83dbSDimitry Andric// mimm - Special immediate value of sequential bit stream of 0 or 1.
1985ffd83dbSDimitry Andricdef MImmAsmOperand : AsmOperandClass {
1995ffd83dbSDimitry Andric  let Name = "MImm";
2005ffd83dbSDimitry Andric  let ParserMethod = "parseMImmOperand";
2015ffd83dbSDimitry Andric}
2025ffd83dbSDimitry Andricdef mimm : Operand<i32>, PatLeaf<(imm), [{
2035ffd83dbSDimitry Andric    return isMImmVal(getImmVal(N)); }], MIMM> {
2045ffd83dbSDimitry Andric  let ParserMatchClass = MImmAsmOperand;
2055ffd83dbSDimitry Andric  let PrintMethod = "printMImmOperand";
2065ffd83dbSDimitry Andric}
2075ffd83dbSDimitry Andric
208e8d8bef9SDimitry Andric// zerofp - Generic fp immediate zero value.
209e8d8bef9SDimitry Andricdef zerofp : Operand<i32>, PatLeaf<(fpimm), [{
210e8d8bef9SDimitry Andric    return getFpImmVal(N) == 0; }]> {
211e8d8bef9SDimitry Andric  let ParserMatchClass = ZeroAsmOperand;
212e8d8bef9SDimitry Andric}
213e8d8bef9SDimitry Andric
2145ffd83dbSDimitry Andric// simm7fp - Generic fp immediate value.
2155ffd83dbSDimitry Andricdef simm7fp : Operand<i32>, PatLeaf<(fpimm), [{
2165ffd83dbSDimitry Andric    return isInt<7>(getFpImmVal(N));
2175ffd83dbSDimitry Andric  }], LO7FP> {
2185ffd83dbSDimitry Andric  let ParserMatchClass = SImm7AsmOperand;
2195ffd83dbSDimitry Andric  let DecoderMethod = "DecodeSIMM7";
2205ffd83dbSDimitry Andric}
2215ffd83dbSDimitry Andric
2225ffd83dbSDimitry Andric// mimmfp - Special fp immediate value of sequential bit stream of 0 or 1.
2235ffd83dbSDimitry Andricdef mimmfp : Operand<i32>, PatLeaf<(fpimm), [{
2245ffd83dbSDimitry Andric    return isMImmVal(getFpImmVal(N)); }], MIMMFP> {
2255ffd83dbSDimitry Andric  let ParserMatchClass = MImmAsmOperand;
2265ffd83dbSDimitry Andric  let PrintMethod = "printMImmOperand";
2275ffd83dbSDimitry Andric}
2285ffd83dbSDimitry Andric
2295ffd83dbSDimitry Andric// mimmfp32 - 32 bit width mimmfp
2305ffd83dbSDimitry Andric//   Float value places at higher bits, so ignore lower 32 bits.
2315ffd83dbSDimitry Andricdef mimmfp32 : Operand<i32>, PatLeaf<(fpimm), [{
2325ffd83dbSDimitry Andric    return isMImm32Val(getFpImmVal(N) >> 32); }], MIMMFP> {
2335ffd83dbSDimitry Andric  let ParserMatchClass = MImmAsmOperand;
2345ffd83dbSDimitry Andric  let PrintMethod = "printMImmOperand";
2355ffd83dbSDimitry Andric}
2365ffd83dbSDimitry Andric
2375ffd83dbSDimitry Andric// other generic patterns to use in pattern matchings
2385ffd83dbSDimitry Andricdef simm32      : PatLeaf<(imm), [{ return isInt<32>(N->getSExtValue()); }]>;
2395ffd83dbSDimitry Andricdef uimm32      : PatLeaf<(imm), [{ return isUInt<32>(N->getZExtValue()); }]>;
2405ffd83dbSDimitry Andricdef lomsbzero   : PatLeaf<(imm), [{ return (N->getZExtValue() & 0x80000000)
2415ffd83dbSDimitry Andric                                      == 0; }]>;
2425ffd83dbSDimitry Andricdef lozero      : PatLeaf<(imm), [{ return (N->getZExtValue() & 0xffffffff)
2435ffd83dbSDimitry Andric                                      == 0; }]>;
2445ffd83dbSDimitry Andricdef fplomsbzero : PatLeaf<(fpimm), [{ return (getFpImmVal(N) & 0x80000000)
2455ffd83dbSDimitry Andric                                        == 0; }]>;
2465ffd83dbSDimitry Andricdef fplozero    : PatLeaf<(fpimm), [{ return (getFpImmVal(N) & 0xffffffff)
2475ffd83dbSDimitry Andric                                        == 0; }]>;
248e8d8bef9SDimitry Andricdef nonzero     : PatLeaf<(imm), [{ return N->getSExtValue() !=0 ; }]>;
2495ffd83dbSDimitry Andric
2505ffd83dbSDimitry Andricdef CCSIOp : PatLeaf<(cond), [{
2515ffd83dbSDimitry Andric  switch (N->get()) {
2525ffd83dbSDimitry Andric  default:          return true;
2535ffd83dbSDimitry Andric  case ISD::SETULT:
2545ffd83dbSDimitry Andric  case ISD::SETULE:
2555ffd83dbSDimitry Andric  case ISD::SETUGT:
2565ffd83dbSDimitry Andric  case ISD::SETUGE: return false;
2575ffd83dbSDimitry Andric  }
2585ffd83dbSDimitry Andric}]>;
2595ffd83dbSDimitry Andric
2605ffd83dbSDimitry Andricdef CCUIOp : PatLeaf<(cond), [{
2615ffd83dbSDimitry Andric  switch (N->get()) {
2625ffd83dbSDimitry Andric  default:         return true;
2635ffd83dbSDimitry Andric  case ISD::SETLT:
2645ffd83dbSDimitry Andric  case ISD::SETLE:
2655ffd83dbSDimitry Andric  case ISD::SETGT:
2665ffd83dbSDimitry Andric  case ISD::SETGE: return false;
2675ffd83dbSDimitry Andric  }
2685ffd83dbSDimitry Andric}]>;
2695ffd83dbSDimitry Andric
2705ffd83dbSDimitry Andric//===----------------------------------------------------------------------===//
2715ffd83dbSDimitry Andric// Addressing modes.
2725ffd83dbSDimitry Andric// SX-Aurora has following fields.
2735ffd83dbSDimitry Andric//    sz: register or 0
2745ffd83dbSDimitry Andric//    sy: register or immediate (-64 to 63)
2755ffd83dbSDimitry Andric//    disp: immediate (-2147483648 to 2147483647)
2765ffd83dbSDimitry Andric//
2775ffd83dbSDimitry Andric// There are two kinds of instruction.
2785ffd83dbSDimitry Andric//    ASX format uses sz + sy + disp.
2795ffd83dbSDimitry Andric//    AS format uses sz + disp.
2805ffd83dbSDimitry Andric//
2815ffd83dbSDimitry Andric// Moreover, there are four kinds of assembly instruction format.
2825ffd83dbSDimitry Andric//    ASX format uses "disp", "disp(, sz)", "disp(sy)", "disp(sy, sz)",
2835ffd83dbSDimitry Andric//    "(, sz)", "(sy)", or "(sy, sz)".
2845ffd83dbSDimitry Andric//    AS format uses "disp", "disp(, sz)", or "(, sz)" in general.
2855ffd83dbSDimitry Andric//    AS format in RRM format uses "disp", "disp(sz)", or "(sz)".
2865ffd83dbSDimitry Andric//    AS format in RRM format for host memory access uses "sz", "(sz)",
2875ffd83dbSDimitry Andric//    or "disp(sz)".
2885ffd83dbSDimitry Andric//
2895ffd83dbSDimitry Andric// We defined them below.
2905ffd83dbSDimitry Andric//
2915ffd83dbSDimitry Andric// ASX format:
2925ffd83dbSDimitry Andric//    MEMrri, MEMrii, MEMzri, MEMzii
2935ffd83dbSDimitry Andric// AS format:
2945ffd83dbSDimitry Andric//    MEMriASX, MEMziASX    : simple AS format
2955ffd83dbSDimitry Andric//    MEMriRRM, MEMziRRM    : AS format in RRM format
2965ffd83dbSDimitry Andric//    MEMriHM, MEMziHM      : AS format in RRM format for host memory access
2975ffd83dbSDimitry Andric//===----------------------------------------------------------------------===//
2985ffd83dbSDimitry Andric
2995ffd83dbSDimitry Andric// DAG selections for both ASX and AS formats.
3005ffd83dbSDimitry Andricdef ADDRrri : ComplexPattern<iPTR, 3, "selectADDRrri", [frameindex], []>;
3015ffd83dbSDimitry Andricdef ADDRrii : ComplexPattern<iPTR, 3, "selectADDRrii", [frameindex], []>;
3025ffd83dbSDimitry Andricdef ADDRzri : ComplexPattern<iPTR, 3, "selectADDRzri", [], []>;
3035ffd83dbSDimitry Andricdef ADDRzii : ComplexPattern<iPTR, 3, "selectADDRzii", [], []>;
3045ffd83dbSDimitry Andricdef ADDRri : ComplexPattern<iPTR, 2, "selectADDRri", [frameindex], []>;
3055ffd83dbSDimitry Andricdef ADDRzi : ComplexPattern<iPTR, 2, "selectADDRzi", [], []>;
3065ffd83dbSDimitry Andric
3075ffd83dbSDimitry Andric// ASX format.
3085ffd83dbSDimitry Andricdef VEMEMrriAsmOperand : AsmOperandClass {
3095ffd83dbSDimitry Andric  let Name = "MEMrri";
3105ffd83dbSDimitry Andric  let ParserMethod = "parseMEMOperand";
3115ffd83dbSDimitry Andric}
3125ffd83dbSDimitry Andricdef VEMEMriiAsmOperand : AsmOperandClass {
3135ffd83dbSDimitry Andric  let Name = "MEMrii";
3145ffd83dbSDimitry Andric  let ParserMethod = "parseMEMOperand";
3155ffd83dbSDimitry Andric}
3165ffd83dbSDimitry Andricdef VEMEMzriAsmOperand : AsmOperandClass {
3175ffd83dbSDimitry Andric  let Name = "MEMzri";
3185ffd83dbSDimitry Andric  let ParserMethod = "parseMEMOperand";
3195ffd83dbSDimitry Andric}
3205ffd83dbSDimitry Andricdef VEMEMziiAsmOperand : AsmOperandClass {
3215ffd83dbSDimitry Andric  let Name = "MEMzii";
3225ffd83dbSDimitry Andric  let ParserMethod = "parseMEMOperand";
3235ffd83dbSDimitry Andric}
3245ffd83dbSDimitry Andric
3255ffd83dbSDimitry Andric// ASX format uses single assembly instruction format.
3265ffd83dbSDimitry Andricdef MEMrri : Operand<iPTR> {
3275ffd83dbSDimitry Andric  let PrintMethod = "printMemASXOperand";
328753f127fSDimitry Andric  let MIOperandInfo = (ops ptr_rc, ptr_rc, i64imm);
3295ffd83dbSDimitry Andric  let ParserMatchClass = VEMEMrriAsmOperand;
3305ffd83dbSDimitry Andric}
3315ffd83dbSDimitry Andricdef MEMrii : Operand<iPTR> {
3325ffd83dbSDimitry Andric  let PrintMethod = "printMemASXOperand";
333753f127fSDimitry Andric  let MIOperandInfo = (ops ptr_rc, i32imm, i64imm);
3345ffd83dbSDimitry Andric  let ParserMatchClass = VEMEMriiAsmOperand;
3355ffd83dbSDimitry Andric}
3365ffd83dbSDimitry Andricdef MEMzri : Operand<iPTR> {
3375ffd83dbSDimitry Andric  let PrintMethod = "printMemASXOperand";
338753f127fSDimitry Andric  let MIOperandInfo = (ops i32imm /* = 0 */, ptr_rc, i64imm);
3395ffd83dbSDimitry Andric  let ParserMatchClass = VEMEMzriAsmOperand;
3405ffd83dbSDimitry Andric}
3415ffd83dbSDimitry Andricdef MEMzii : Operand<iPTR> {
3425ffd83dbSDimitry Andric  let PrintMethod = "printMemASXOperand";
343753f127fSDimitry Andric  let MIOperandInfo = (ops i32imm /* = 0 */, i32imm, i64imm);
3445ffd83dbSDimitry Andric  let ParserMatchClass = VEMEMziiAsmOperand;
3455ffd83dbSDimitry Andric}
3465ffd83dbSDimitry Andric
3475ffd83dbSDimitry Andric// AS format.
3485ffd83dbSDimitry Andricdef VEMEMriAsmOperand : AsmOperandClass {
3495ffd83dbSDimitry Andric  let Name = "MEMri";
3505ffd83dbSDimitry Andric  let ParserMethod = "parseMEMAsOperand";
3515ffd83dbSDimitry Andric}
3525ffd83dbSDimitry Andricdef VEMEMziAsmOperand : AsmOperandClass {
3535ffd83dbSDimitry Andric  let Name = "MEMzi";
3545ffd83dbSDimitry Andric  let ParserMethod = "parseMEMAsOperand";
3555ffd83dbSDimitry Andric}
3565ffd83dbSDimitry Andric
3575ffd83dbSDimitry Andric// AS format uses multiple assembly instruction formats
3585ffd83dbSDimitry Andric//   1. AS generic assembly instruction format:
3595ffd83dbSDimitry Andricdef MEMriASX : Operand<iPTR> {
3605ffd83dbSDimitry Andric  let PrintMethod = "printMemASOperandASX";
3615ffd83dbSDimitry Andric  let MIOperandInfo = (ops ptr_rc, i32imm);
3625ffd83dbSDimitry Andric  let ParserMatchClass = VEMEMriAsmOperand;
3635ffd83dbSDimitry Andric}
3645ffd83dbSDimitry Andricdef MEMziASX : Operand<iPTR> {
3655ffd83dbSDimitry Andric  let PrintMethod = "printMemASOperandASX";
3665ffd83dbSDimitry Andric  let MIOperandInfo = (ops i32imm /* = 0 */, i32imm);
3675ffd83dbSDimitry Andric  let ParserMatchClass = VEMEMziAsmOperand;
3685ffd83dbSDimitry Andric}
3695ffd83dbSDimitry Andric
3705ffd83dbSDimitry Andric//   2. AS RRM style assembly instruction format:
3715ffd83dbSDimitry Andricdef MEMriRRM : Operand<iPTR> {
3725ffd83dbSDimitry Andric  let PrintMethod = "printMemASOperandRRM";
3735ffd83dbSDimitry Andric  let MIOperandInfo = (ops ptr_rc, i32imm);
3745ffd83dbSDimitry Andric  let ParserMatchClass = VEMEMriAsmOperand;
3755ffd83dbSDimitry Andric}
3765ffd83dbSDimitry Andricdef MEMziRRM : Operand<iPTR> {
3775ffd83dbSDimitry Andric  let PrintMethod = "printMemASOperandRRM";
3785ffd83dbSDimitry Andric  let MIOperandInfo = (ops i32imm /* = 0 */, i32imm);
3795ffd83dbSDimitry Andric  let ParserMatchClass = VEMEMziAsmOperand;
3805ffd83dbSDimitry Andric}
3815ffd83dbSDimitry Andric
3825ffd83dbSDimitry Andric//   3. AS HM style assembly instruction format:
3835ffd83dbSDimitry Andricdef MEMriHM : Operand<iPTR> {
3845ffd83dbSDimitry Andric  let PrintMethod = "printMemASOperandHM";
3855ffd83dbSDimitry Andric  let MIOperandInfo = (ops ptr_rc, i32imm);
3865ffd83dbSDimitry Andric  let ParserMatchClass = VEMEMriAsmOperand;
3875ffd83dbSDimitry Andric}
3885ffd83dbSDimitry Andricdef MEMziHM : Operand<iPTR> {
3895ffd83dbSDimitry Andric  let PrintMethod = "printMemASOperandHM";
3905ffd83dbSDimitry Andric  let MIOperandInfo = (ops i32imm /* = 0 */, i32imm);
3915ffd83dbSDimitry Andric  let ParserMatchClass = VEMEMziAsmOperand;
3925ffd83dbSDimitry Andric}
3935ffd83dbSDimitry Andric
3945ffd83dbSDimitry Andric//===----------------------------------------------------------------------===//
3955ffd83dbSDimitry Andric// Other operands.
3965ffd83dbSDimitry Andric//===----------------------------------------------------------------------===//
3975ffd83dbSDimitry Andric
3985ffd83dbSDimitry Andric// Branch targets have OtherVT type.
3995ffd83dbSDimitry Andricdef brtarget32 : Operand<OtherVT> {
4005ffd83dbSDimitry Andric  let EncoderMethod = "getBranchTargetOpValue";
401480093f4SDimitry Andric  let DecoderMethod = "DecodeSIMM32";
402480093f4SDimitry Andric}
403480093f4SDimitry Andric
4045ffd83dbSDimitry Andric// Operand for printing out a condition code.
4055ffd83dbSDimitry Andricdef CCOpAsmOperand : AsmOperandClass { let Name = "CCOp"; }
4065ffd83dbSDimitry Andricdef CCOp : Operand<i32>, ImmLeaf<i32, [{
4075ffd83dbSDimitry Andric    return Imm >= 0 && Imm < 22; }], CCOP> {
4085ffd83dbSDimitry Andric  let PrintMethod = "printCCOperand";
4095ffd83dbSDimitry Andric  let DecoderMethod = "DecodeCCOperand";
4105ffd83dbSDimitry Andric  let EncoderMethod = "getCCOpValue";
4115ffd83dbSDimitry Andric  let ParserMatchClass = CCOpAsmOperand;
412480093f4SDimitry Andric}
413480093f4SDimitry Andric
4145ffd83dbSDimitry Andric// Operand for a rounding mode code.
4155ffd83dbSDimitry Andricdef RDOpAsmOperand : AsmOperandClass {
4165ffd83dbSDimitry Andric  let Name = "RDOp";
4175ffd83dbSDimitry Andric}
4185ffd83dbSDimitry Andricdef RDOp : Operand<i32> {
4195ffd83dbSDimitry Andric  let PrintMethod = "printRDOperand";
4205ffd83dbSDimitry Andric  let DecoderMethod = "DecodeRDOperand";
4215ffd83dbSDimitry Andric  let EncoderMethod = "getRDOpValue";
4225ffd83dbSDimitry Andric  let ParserMatchClass = RDOpAsmOperand;
4235ffd83dbSDimitry Andric}
4245ffd83dbSDimitry Andric
4255ffd83dbSDimitry Andricdef VEhi    : SDNode<"VEISD::Hi", SDTIntUnaryOp>;
4265ffd83dbSDimitry Andricdef VElo    : SDNode<"VEISD::Lo", SDTIntUnaryOp>;
427480093f4SDimitry Andric
428480093f4SDimitry Andric//  These are target-independent nodes, but have target-specific formats.
429480093f4SDimitry Andricdef SDT_SPCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i64>,
430480093f4SDimitry Andric                                          SDTCisVT<1, i64> ]>;
431480093f4SDimitry Andricdef SDT_SPCallSeqEnd   : SDCallSeqEnd<[ SDTCisVT<0, i64>,
432480093f4SDimitry Andric                                        SDTCisVT<1, i64> ]>;
433480093f4SDimitry Andric
434480093f4SDimitry Andricdef callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SPCallSeqStart,
435480093f4SDimitry Andric                           [SDNPHasChain, SDNPOutGlue]>;
436480093f4SDimitry Andricdef callseq_end   : SDNode<"ISD::CALLSEQ_END",   SDT_SPCallSeqEnd,
437480093f4SDimitry Andric                           [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
438480093f4SDimitry Andric
4395ffd83dbSDimitry Andricdef SDT_SPCall    : SDTypeProfile<0, -1, [SDTCisVT<0, i64>]>;
4405ffd83dbSDimitry Andricdef call          : SDNode<"VEISD::CALL", SDT_SPCall,
4415ffd83dbSDimitry Andric                           [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
4425ffd83dbSDimitry Andric                            SDNPVariadic]>;
443480093f4SDimitry Andric
44406c3fb27SDimitry Andricdef retglue       : SDNode<"VEISD::RET_GLUE", SDTNone,
445480093f4SDimitry Andric                           [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
4465ffd83dbSDimitry Andric
4475ffd83dbSDimitry Andricdef getGOT        : Operand<iPTR>;
4485ffd83dbSDimitry Andric
449bdd1243dSDimitry Andric// Comparisons
450bdd1243dSDimitry Andricdef cmpi          : SDNode<"VEISD::CMPI", SDTIntBinOp>;
451bdd1243dSDimitry Andricdef cmpu          : SDNode<"VEISD::CMPU", SDTIntBinOp>;
452bdd1243dSDimitry Andricdef cmpf          : SDNode<"VEISD::CMPF", SDTFPBinOp>;
453bdd1243dSDimitry Andricdef SDT_Cmpq      : SDTypeProfile<1, 2, [SDTCisSameAs<1, 2>, SDTCisFP<0>,
454bdd1243dSDimitry Andric                                  SDTCisFP<2>]>;
455bdd1243dSDimitry Andricdef cmpq          : SDNode<"VEISD::CMPQ", SDT_Cmpq>;
456bdd1243dSDimitry Andric
457bdd1243dSDimitry Andric// res = cmov cmp, t, f, cond
458bdd1243dSDimitry Andricdef SDT_Cmov      : SDTypeProfile<1, 4, [SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3>,
459bdd1243dSDimitry Andric                                  SDTCisVT<4, i32>]>;
460bdd1243dSDimitry Andricdef cmov          : SDNode<"VEISD::CMOV", SDT_Cmov>;
461bdd1243dSDimitry Andric
462e8d8bef9SDimitry Andricdef VEeh_sjlj_setjmp: SDNode<"VEISD::EH_SJLJ_SETJMP",
463e8d8bef9SDimitry Andric                             SDTypeProfile<1, 1, [SDTCisInt<0>,
464e8d8bef9SDimitry Andric                                                  SDTCisPtrTy<1>]>,
465e8d8bef9SDimitry Andric                             [SDNPHasChain, SDNPSideEffect]>;
466e8d8bef9SDimitry Andricdef VEeh_sjlj_longjmp: SDNode<"VEISD::EH_SJLJ_LONGJMP",
467e8d8bef9SDimitry Andric                              SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>,
468e8d8bef9SDimitry Andric                              [SDNPHasChain, SDNPSideEffect]>;
469e8d8bef9SDimitry Andricdef VEeh_sjlj_setup_dispatch: SDNode<"VEISD::EH_SJLJ_SETUP_DISPATCH",
470e8d8bef9SDimitry Andric                                     SDTypeProfile<0, 0, []>,
471e8d8bef9SDimitry Andric                                     [SDNPHasChain, SDNPSideEffect]>;
472e8d8bef9SDimitry Andric
4735ffd83dbSDimitry Andric// GETFUNPLT for PIC
4745ffd83dbSDimitry Andricdef GetFunPLT : SDNode<"VEISD::GETFUNPLT", SDTIntUnaryOp>;
4755ffd83dbSDimitry Andric
4765ffd83dbSDimitry Andric// GETTLSADDR for TLS
4775ffd83dbSDimitry Andricdef GetTLSAddr : SDNode<"VEISD::GETTLSADDR", SDT_SPCall,
4785ffd83dbSDimitry Andric                        [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
4795ffd83dbSDimitry Andric                         SDNPVariadic]>;
4805ffd83dbSDimitry Andric
4815ffd83dbSDimitry Andric// GETSTACKTOP
4825ffd83dbSDimitry Andricdef GetStackTop : SDNode<"VEISD::GETSTACKTOP", SDTNone,
4835ffd83dbSDimitry Andric                        [SDNPHasChain, SDNPSideEffect]>;
4845ffd83dbSDimitry Andric
485e8d8bef9SDimitry Andric// TS1AM
486e8d8bef9SDimitry Andricdef SDT_TS1AM : SDTypeProfile<1, 3, [SDTCisSameAs<0, 3>, SDTCisPtrTy<1>,
487e8d8bef9SDimitry Andric                                     SDTCisVT<2, i32>, SDTCisInt<3>]>;
488e8d8bef9SDimitry Andricdef ts1am     : SDNode<"VEISD::TS1AM", SDT_TS1AM,
489e8d8bef9SDimitry Andric                       [SDNPHasChain, SDNPMayStore, SDNPMayLoad,
490e8d8bef9SDimitry Andric                        SDNPMemOperand]>;
4915ffd83dbSDimitry Andric
492480093f4SDimitry Andric//===----------------------------------------------------------------------===//
493480093f4SDimitry Andric// VE Flag Conditions
494480093f4SDimitry Andric//===----------------------------------------------------------------------===//
495480093f4SDimitry Andric
496480093f4SDimitry Andric// Note that these values must be kept in sync with the CCOp::CondCode enum
497480093f4SDimitry Andric// values.
498480093f4SDimitry Andricclass CC_VAL<int N> : PatLeaf<(i32 N)>;
499480093f4SDimitry Andricdef CC_IG    : CC_VAL< 0>;  // Greater
500480093f4SDimitry Andricdef CC_IL    : CC_VAL< 1>;  // Less
501480093f4SDimitry Andricdef CC_INE   : CC_VAL< 2>;  // Not Equal
502480093f4SDimitry Andricdef CC_IEQ   : CC_VAL< 3>;  // Equal
503480093f4SDimitry Andricdef CC_IGE   : CC_VAL< 4>;  // Greater or Equal
504480093f4SDimitry Andricdef CC_ILE   : CC_VAL< 5>;  // Less or Equal
505480093f4SDimitry Andricdef CC_AF    : CC_VAL< 6>;  // Always false
506480093f4SDimitry Andricdef CC_G     : CC_VAL< 7>;  // Greater
507480093f4SDimitry Andricdef CC_L     : CC_VAL< 8>;  // Less
508480093f4SDimitry Andricdef CC_NE    : CC_VAL< 9>;  // Not Equal
509480093f4SDimitry Andricdef CC_EQ    : CC_VAL<10>;  // Equal
510480093f4SDimitry Andricdef CC_GE    : CC_VAL<11>;  // Greater or Equal
511480093f4SDimitry Andricdef CC_LE    : CC_VAL<12>;  // Less or Equal
512480093f4SDimitry Andricdef CC_NUM   : CC_VAL<13>;  // Number
513480093f4SDimitry Andricdef CC_NAN   : CC_VAL<14>;  // NaN
514480093f4SDimitry Andricdef CC_GNAN  : CC_VAL<15>;  // Greater or NaN
515480093f4SDimitry Andricdef CC_LNAN  : CC_VAL<16>;  // Less or NaN
516480093f4SDimitry Andricdef CC_NENAN : CC_VAL<17>;  // Not Equal or NaN
517480093f4SDimitry Andricdef CC_EQNAN : CC_VAL<18>;  // Equal or NaN
518480093f4SDimitry Andricdef CC_GENAN : CC_VAL<19>;  // Greater or Equal or NaN
519480093f4SDimitry Andricdef CC_LENAN : CC_VAL<20>;  // Less or Equal or NaN
520480093f4SDimitry Andricdef CC_AT    : CC_VAL<21>;  // Always true
521480093f4SDimitry Andric
522480093f4SDimitry Andric//===----------------------------------------------------------------------===//
5235ffd83dbSDimitry Andric// VE Rounding Mode
5245ffd83dbSDimitry Andric//===----------------------------------------------------------------------===//
5255ffd83dbSDimitry Andric
5265ffd83dbSDimitry Andric// Note that these values must be kept in sync with the VERD::RoundingMode enum
5275ffd83dbSDimitry Andric// values.
5285ffd83dbSDimitry Andricclass RD_VAL<int N> : PatLeaf<(i32 N)>;
5295ffd83dbSDimitry Andricdef RD_NONE  : RD_VAL< 0>;  // According to PSW
5305ffd83dbSDimitry Andricdef RD_RZ    : RD_VAL< 8>;  // Round toward Zero
5315ffd83dbSDimitry Andricdef RD_RP    : RD_VAL< 9>;  // Round toward Plus infinity
5325ffd83dbSDimitry Andricdef RD_RM    : RD_VAL<10>;  // Round toward Minus infinity
5335ffd83dbSDimitry Andricdef RD_RN    : RD_VAL<11>;  // Round to Nearest (ties to Even)
5345ffd83dbSDimitry Andricdef RD_RA    : RD_VAL<12>;  // Round to Nearest (ties to Away)
5355ffd83dbSDimitry Andric
5365ffd83dbSDimitry Andric//===----------------------------------------------------------------------===//
537480093f4SDimitry Andric// VE Multiclasses for common instruction formats
538480093f4SDimitry Andric//===----------------------------------------------------------------------===//
539480093f4SDimitry Andric
5405ffd83dbSDimitry Andric// Multiclass for generic RR type instructions
5415ffd83dbSDimitry Andriclet hasSideEffects = 0 in
5425ffd83dbSDimitry Andricmulticlass RRbm<string opcStr, bits<8>opc,
543480093f4SDimitry Andric                RegisterClass RCo, ValueType Tyo,
5445ffd83dbSDimitry Andric                RegisterClass RCi, ValueType Tyi,
5455ffd83dbSDimitry Andric                SDPatternOperator OpNode = null_frag,
546e8d8bef9SDimitry Andric                Operand immOp = simm7, Operand mOp = mimm,
547e8d8bef9SDimitry Andric                bit MoveImm = 0> {
548480093f4SDimitry Andric  def rr : RR<opc, (outs RCo:$sx), (ins RCi:$sy, RCi:$sz),
5495ffd83dbSDimitry Andric              !strconcat(opcStr, " $sx, $sy, $sz"),
5505ffd83dbSDimitry Andric              [(set Tyo:$sx, (OpNode Tyi:$sy, Tyi:$sz))]>;
551480093f4SDimitry Andric  // VE calculates (OpNode $sy, $sz), but llvm requires to have immediate
552480093f4SDimitry Andric  // in RHS, so we use following definition.
5535ffd83dbSDimitry Andric  let cy = 0 in
554480093f4SDimitry Andric  def ri : RR<opc, (outs RCo:$sx), (ins RCi:$sz, immOp:$sy),
5555ffd83dbSDimitry Andric              !strconcat(opcStr, " $sx, $sy, $sz"),
5565ffd83dbSDimitry Andric              [(set Tyo:$sx, (OpNode Tyi:$sz, (Tyi immOp:$sy)))]>;
5575ffd83dbSDimitry Andric  let cz = 0 in
5585ffd83dbSDimitry Andric  def rm : RR<opc, (outs RCo:$sx), (ins RCi:$sy, mOp:$sz),
5595ffd83dbSDimitry Andric              !strconcat(opcStr, " $sx, $sy, $sz"),
5605ffd83dbSDimitry Andric              [(set Tyo:$sx, (OpNode Tyi:$sy, (Tyi mOp:$sz)))]>;
5615ffd83dbSDimitry Andric  let cy = 0, cz = 0 in
5625ffd83dbSDimitry Andric  def im : RR<opc, (outs RCo:$sx), (ins immOp:$sy, mOp:$sz),
5635ffd83dbSDimitry Andric              !strconcat(opcStr, " $sx, $sy, $sz"),
564e8d8bef9SDimitry Andric              [(set Tyo:$sx, (OpNode (Tyi immOp:$sy), (Tyi mOp:$sz)))]> {
565e8d8bef9SDimitry Andric    // VE uses ORim as a move immediate instruction, so declare it here.
566e8d8bef9SDimitry Andric    // An instruction declared as MoveImm will be optimized in FoldImmediate
567e8d8bef9SDimitry Andric    // later.
568e8d8bef9SDimitry Andric    let isMoveImm = MoveImm;
569e8d8bef9SDimitry Andric  }
570480093f4SDimitry Andric}
571480093f4SDimitry Andric
5725ffd83dbSDimitry Andric// Multiclass for non-commutative RR type instructions
5735ffd83dbSDimitry Andriclet hasSideEffects = 0 in
5745ffd83dbSDimitry Andricmulticlass RRNCbm<string opcStr, bits<8>opc,
575480093f4SDimitry Andric                RegisterClass RCo, ValueType Tyo,
5765ffd83dbSDimitry Andric                RegisterClass RCi, ValueType Tyi,
5775ffd83dbSDimitry Andric                SDPatternOperator OpNode = null_frag,
5785ffd83dbSDimitry Andric                Operand immOp = simm7, Operand mOp = mimm> {
5795ffd83dbSDimitry Andric  def rr : RR<opc, (outs RCo:$sx), (ins RCi:$sy, RCi:$sz),
5805ffd83dbSDimitry Andric              !strconcat(opcStr, " $sx, $sy, $sz"),
5815ffd83dbSDimitry Andric              [(set Tyo:$sx, (OpNode Tyi:$sy, Tyi:$sz))]>;
5825ffd83dbSDimitry Andric  let cy = 0 in
5835ffd83dbSDimitry Andric  def ir : RR<opc, (outs RCo:$sx), (ins immOp:$sy, RCi:$sz),
5845ffd83dbSDimitry Andric              !strconcat(opcStr, " $sx, $sy, $sz"),
5855ffd83dbSDimitry Andric              [(set Tyo:$sx, (OpNode (Tyi immOp:$sy), Tyi:$sz))]>;
5865ffd83dbSDimitry Andric  let cz = 0 in
5875ffd83dbSDimitry Andric  def rm : RR<opc, (outs RCo:$sx), (ins RCi:$sy, mOp:$sz),
5885ffd83dbSDimitry Andric              !strconcat(opcStr, " $sx, $sy, $sz"),
5895ffd83dbSDimitry Andric              [(set Tyo:$sx, (OpNode Tyi:$sy, (Tyi mOp:$sz)))]>;
5905ffd83dbSDimitry Andric  let cy = 0, cz = 0 in
5915ffd83dbSDimitry Andric  def im : RR<opc, (outs RCo:$sx), (ins immOp:$sy, mOp:$sz),
5925ffd83dbSDimitry Andric              !strconcat(opcStr, " $sx, $sy, $sz"),
5935ffd83dbSDimitry Andric              [(set Tyo:$sx, (OpNode (Tyi immOp:$sy), (Tyi mOp:$sz)))]>;
594480093f4SDimitry Andric}
595480093f4SDimitry Andric
5965ffd83dbSDimitry Andric// Generic RR multiclass with 2 arguments.
5975ffd83dbSDimitry Andric//   e.g. ADDUL, ADDSWSX, ADDSWZX, and etc.
598480093f4SDimitry Andricmulticlass RRm<string opcStr, bits<8>opc,
5995ffd83dbSDimitry Andric               RegisterClass RC, ValueType Ty,
6005ffd83dbSDimitry Andric               SDPatternOperator OpNode = null_frag,
601e8d8bef9SDimitry Andric               Operand immOp = simm7, Operand mOp = mimm, bit MoveImm = 0> :
602e8d8bef9SDimitry Andric  RRbm<opcStr, opc, RC, Ty, RC, Ty, OpNode, immOp, mOp, MoveImm>;
603480093f4SDimitry Andric
6045ffd83dbSDimitry Andric// Generic RR multiclass for non-commutative instructions with 2 arguments.
6055ffd83dbSDimitry Andric//   e.g. SUBUL, SUBUW, SUBSWSX, and etc.
6065ffd83dbSDimitry Andricmulticlass RRNCm<string opcStr, bits<8>opc,
6075ffd83dbSDimitry Andric                 RegisterClass RC, ValueType Ty,
6085ffd83dbSDimitry Andric                 SDPatternOperator OpNode = null_frag,
6095ffd83dbSDimitry Andric                 Operand immOp = simm7, Operand mOp = mimm> :
6105ffd83dbSDimitry Andric  RRNCbm<opcStr, opc, RC, Ty, RC, Ty, OpNode, immOp, mOp>;
6115ffd83dbSDimitry Andric
6125ffd83dbSDimitry Andric// Generic RR multiclass for floating point instructions with 2 arguments.
6135ffd83dbSDimitry Andric//   e.g. FADDD, FADDS, FSUBD, and etc.
6145ffd83dbSDimitry Andricmulticlass RRFm<string opcStr, bits<8>opc,
6155ffd83dbSDimitry Andric                RegisterClass RC, ValueType Ty,
6165ffd83dbSDimitry Andric                SDPatternOperator OpNode = null_frag,
6175ffd83dbSDimitry Andric                Operand immOp = simm7fp, Operand mOp = mimmfp> :
6185ffd83dbSDimitry Andric  RRNCbm<opcStr, opc, RC, Ty, RC, Ty, OpNode, immOp, mOp>;
6195ffd83dbSDimitry Andric
6205ffd83dbSDimitry Andric// Generic RR multiclass for shift instructions with 2 arguments.
6215ffd83dbSDimitry Andric//   e.g. SLL, SRL, SLAWSX, and etc.
6225ffd83dbSDimitry Andriclet hasSideEffects = 0 in
6235ffd83dbSDimitry Andricmulticlass RRIm<string opcStr, bits<8>opc,
6245ffd83dbSDimitry Andric                RegisterClass RC, ValueType Ty,
6255ffd83dbSDimitry Andric                SDPatternOperator OpNode = null_frag> {
6265ffd83dbSDimitry Andric  def rr : RR<opc, (outs RC:$sx), (ins RC:$sz, I32:$sy),
6275ffd83dbSDimitry Andric              !strconcat(opcStr, " $sx, $sz, $sy"),
6285ffd83dbSDimitry Andric              [(set Ty:$sx, (OpNode Ty:$sz, i32:$sy))]>;
6295ffd83dbSDimitry Andric  let cz = 0 in
6305ffd83dbSDimitry Andric  def mr : RR<opc, (outs RC:$sx), (ins mimm:$sz, I32:$sy),
6315ffd83dbSDimitry Andric              !strconcat(opcStr, " $sx, $sz, $sy"),
6325ffd83dbSDimitry Andric              [(set Ty:$sx, (OpNode (Ty mimm:$sz), i32:$sy))]>;
6335ffd83dbSDimitry Andric  let cy = 0 in
6345ffd83dbSDimitry Andric  def ri : RR<opc, (outs RC:$sx), (ins RC:$sz, uimm7:$sy),
6355ffd83dbSDimitry Andric              !strconcat(opcStr, " $sx, $sz, $sy"),
6365ffd83dbSDimitry Andric              [(set Ty:$sx, (OpNode Ty:$sz, (i32 uimm7:$sy)))]>;
6375ffd83dbSDimitry Andric  let cy = 0, cz = 0 in
6385ffd83dbSDimitry Andric  def mi : RR<opc, (outs RC:$sx), (ins mimm:$sz, uimm7:$sy),
6395ffd83dbSDimitry Andric              !strconcat(opcStr, " $sx, $sz, $sy"),
6405ffd83dbSDimitry Andric              [(set Ty:$sx, (OpNode (Ty mimm:$sz), (i32 uimm7:$sy)))]>;
6415ffd83dbSDimitry Andric}
6425ffd83dbSDimitry Andric
6435ffd83dbSDimitry Andric// Special RR multiclass for 128 bits shift left instruction.
6445ffd83dbSDimitry Andric//   e.g. SLD
6455ffd83dbSDimitry Andriclet Constraints = "$hi = $sx", DisableEncoding = "$hi", hasSideEffects = 0 in
646349cc55cSDimitry Andricmulticlass RRILDm<string opcStr, bits<8>opc, RegisterClass RC> {
6475ffd83dbSDimitry Andric  def rrr : RR<opc, (outs RC:$sx), (ins RC:$hi, RC:$sz, I32:$sy),
6485ffd83dbSDimitry Andric              !strconcat(opcStr, " $sx, $sz, $sy")>;
6495ffd83dbSDimitry Andric  let cz = 0 in
6505ffd83dbSDimitry Andric  def rmr : RR<opc, (outs RC:$sx), (ins RC:$hi, mimm:$sz, I32:$sy),
6515ffd83dbSDimitry Andric              !strconcat(opcStr, " $sx, $sz, $sy")>;
6525ffd83dbSDimitry Andric  let cy = 0 in
6535ffd83dbSDimitry Andric  def rri : RR<opc, (outs RC:$sx), (ins RC:$hi, RC:$sz, uimm7:$sy),
6545ffd83dbSDimitry Andric              !strconcat(opcStr, " $sx, $sz, $sy")>;
6555ffd83dbSDimitry Andric  let cy = 0, cz = 0 in
6565ffd83dbSDimitry Andric  def rmi : RR<opc, (outs RC:$sx), (ins RC:$hi, mimm:$sz, uimm7:$sy),
6575ffd83dbSDimitry Andric              !strconcat(opcStr, " $sx, $sz, $sy")>;
6585ffd83dbSDimitry Andric}
6595ffd83dbSDimitry Andric
6605ffd83dbSDimitry Andric// Special RR multiclass for 128 bits shift right instruction.
6615ffd83dbSDimitry Andric//   e.g. SRD
6625ffd83dbSDimitry Andriclet Constraints = "$low = $sx", DisableEncoding = "$low", hasSideEffects = 0 in
663349cc55cSDimitry Andricmulticlass RRIRDm<string opcStr, bits<8>opc, RegisterClass RC> {
6645ffd83dbSDimitry Andric  def rrr : RR<opc, (outs RC:$sx), (ins RC:$sz, RC:$low, I32:$sy),
6655ffd83dbSDimitry Andric              !strconcat(opcStr, " $sx, $sz, $sy")>;
6665ffd83dbSDimitry Andric  let cz = 0 in
6675ffd83dbSDimitry Andric  def mrr : RR<opc, (outs RC:$sx), (ins mimm:$sz, RC:$low, I32:$sy),
6685ffd83dbSDimitry Andric              !strconcat(opcStr, " $sx, $sz, $sy")>;
6695ffd83dbSDimitry Andric  let cy = 0 in
6705ffd83dbSDimitry Andric  def rri : RR<opc, (outs RC:$sx), (ins RC:$sz, RC:$low, uimm7:$sy),
6715ffd83dbSDimitry Andric              !strconcat(opcStr, " $sx, $sz, $sy")>;
6725ffd83dbSDimitry Andric  let cy = 0, cz = 0 in
6735ffd83dbSDimitry Andric  def mri : RR<opc, (outs RC:$sx), (ins mimm:$sz, RC:$low, uimm7:$sy),
6745ffd83dbSDimitry Andric              !strconcat(opcStr, " $sx, $sz, $sy")>;
6755ffd83dbSDimitry Andric}
6765ffd83dbSDimitry Andric
6775ffd83dbSDimitry Andric// Generic RR multiclass with an argument.
6785ffd83dbSDimitry Andric//   e.g. LDZ, PCNT, and  BRV
6795ffd83dbSDimitry Andriclet cy = 0, sy = 0, hasSideEffects = 0 in
6805ffd83dbSDimitry Andricmulticlass RRI1m<string opcStr, bits<8>opc, RegisterClass RC, ValueType Ty,
6815ffd83dbSDimitry Andric                 SDPatternOperator OpNode = null_frag> {
6825ffd83dbSDimitry Andric  def r : RR<opc, (outs RC:$sx), (ins RC:$sz), !strconcat(opcStr, " $sx, $sz"),
6835ffd83dbSDimitry Andric             [(set Ty:$sx, (OpNode Ty:$sz))]>;
6845ffd83dbSDimitry Andric  let cz = 0 in
6855ffd83dbSDimitry Andric  def m : RR<opc, (outs RC:$sx), (ins mimm:$sz),
6865ffd83dbSDimitry Andric             !strconcat(opcStr, " $sx, $sz"),
6875ffd83dbSDimitry Andric             [(set Ty:$sx, (OpNode (Ty mimm:$sz)))]>;
6885ffd83dbSDimitry Andric}
6895ffd83dbSDimitry Andric
6905ffd83dbSDimitry Andric// Special RR multiclass for MRG instruction.
6915ffd83dbSDimitry Andric//   e.g. MRG
6925ffd83dbSDimitry Andriclet Constraints = "$sx = $sd", DisableEncoding = "$sd", hasSideEffects = 0 in
693349cc55cSDimitry Andricmulticlass RRMRGm<string opcStr, bits<8>opc, RegisterClass RC> {
6945ffd83dbSDimitry Andric  def rr : RR<opc, (outs RC:$sx), (ins RC:$sy, RC:$sz, RC:$sd),
6955ffd83dbSDimitry Andric              !strconcat(opcStr, " $sx, $sy, $sz")>;
6965ffd83dbSDimitry Andric  let cy = 0 in
6975ffd83dbSDimitry Andric  def ir : RR<opc, (outs RC:$sx), (ins simm7:$sy, RC:$sz, RC:$sd),
6985ffd83dbSDimitry Andric              !strconcat(opcStr, " $sx, $sy, $sz")>;
6995ffd83dbSDimitry Andric  let cz = 0 in
7005ffd83dbSDimitry Andric  def rm : RR<opc, (outs RC:$sx), (ins RC:$sy, mimm:$sz, RC:$sd),
7015ffd83dbSDimitry Andric              !strconcat(opcStr, " $sx, $sy, $sz")>;
7025ffd83dbSDimitry Andric  let cy = 0, cz = 0 in
7035ffd83dbSDimitry Andric  def im : RR<opc, (outs RC:$sx), (ins simm7:$sy, mimm:$sz, RC:$sd),
7045ffd83dbSDimitry Andric              !strconcat(opcStr, " $sx, $sy, $sz")>;
7055ffd83dbSDimitry Andric}
7065ffd83dbSDimitry Andric
7075ffd83dbSDimitry Andric// Special RR multiclass for BSWP instruction.
7085ffd83dbSDimitry Andric//   e.g. BSWP
7095ffd83dbSDimitry Andriclet hasSideEffects = 0 in
7105ffd83dbSDimitry Andricmulticlass RRSWPm<string opcStr, bits<8>opc,
7115ffd83dbSDimitry Andric                  RegisterClass RC, ValueType Ty,
7125ffd83dbSDimitry Andric                  SDPatternOperator OpNode = null_frag> {
7135ffd83dbSDimitry Andric  let cy = 0 in
7145ffd83dbSDimitry Andric  def ri : RR<opc, (outs RC:$sx), (ins RC:$sz, uimm1:$sy),
7155ffd83dbSDimitry Andric              !strconcat(opcStr, " $sx, $sz, $sy"),
7165ffd83dbSDimitry Andric              [(set Ty:$sx, (OpNode Ty:$sz, (i32 uimm1:$sy)))]>;
7175ffd83dbSDimitry Andric  let cy = 0, cz = 0 in
7185ffd83dbSDimitry Andric  def mi : RR<opc, (outs RC:$sx), (ins mimm:$sz, uimm1:$sy),
7195ffd83dbSDimitry Andric              !strconcat(opcStr, " $sx, $sz, $sy"),
7205ffd83dbSDimitry Andric              [(set Ty:$sx, (OpNode (Ty mimm:$sz), (i32 uimm1:$sy)))]>;
7215ffd83dbSDimitry Andric}
7225ffd83dbSDimitry Andric
7235ffd83dbSDimitry Andric// Multiclass for CMOV instructions.
7245ffd83dbSDimitry Andric//   e.g. CMOVL, CMOVW, CMOVD, and etc.
7255ffd83dbSDimitry Andriclet Constraints = "$sx = $sd", DisableEncoding = "$sd", hasSideEffects = 0,
7265ffd83dbSDimitry Andric    cfw = ? in
727bdd1243dSDimitry Andricmulticlass RRCMOVm<string opcStr, bits<8>opc, RegisterClass RC, ValueType Ty,
728bdd1243dSDimitry Andric                   SDPatternOperator OpNode = null_frag,
729bdd1243dSDimitry Andric                   Operand immOp = simm7> {
7305ffd83dbSDimitry Andric  def rr : RR<opc, (outs I64:$sx), (ins CCOp:$cfw, RC:$sy, I64:$sz, I64:$sd),
731bdd1243dSDimitry Andric              !strconcat(opcStr, " $sx, $sz, $sy"),
732bdd1243dSDimitry Andric              [(set i64:$sx, (OpNode Ty:$sy, i64:$sz, i64:$sd,
733bdd1243dSDimitry Andric                                     (i32 CCOp:$cfw)))]>;
7345ffd83dbSDimitry Andric  let cy = 0 in
7355ffd83dbSDimitry Andric  def ir : RR<opc, (outs I64:$sx),
736bdd1243dSDimitry Andric              (ins CCOp:$cfw, immOp:$sy, I64:$sz, I64:$sd),
737bdd1243dSDimitry Andric              !strconcat(opcStr, " $sx, $sz, $sy"),
738bdd1243dSDimitry Andric              [(set i64:$sx, (OpNode (Ty immOp:$sy), i64:$sz, i64:$sd,
739bdd1243dSDimitry Andric                                     (i32 CCOp:$cfw)))]>;
7405ffd83dbSDimitry Andric  let cz = 0 in
7415ffd83dbSDimitry Andric  def rm : RR<opc, (outs I64:$sx),
7425ffd83dbSDimitry Andric              (ins CCOp:$cfw, RC:$sy, mimm:$sz, I64:$sd),
743bdd1243dSDimitry Andric              !strconcat(opcStr, " $sx, $sz, $sy"),
744bdd1243dSDimitry Andric              [(set i64:$sx, (OpNode Ty:$sy, (i64 mimm:$sz), i64:$sd,
745bdd1243dSDimitry Andric                                     (i32 CCOp:$cfw)))]>;
7465ffd83dbSDimitry Andric  let cy = 0, cz = 0 in
7475ffd83dbSDimitry Andric  def im : RR<opc, (outs I64:$sx),
748bdd1243dSDimitry Andric              (ins CCOp:$cfw, immOp:$sy, mimm:$sz, I64:$sd),
749bdd1243dSDimitry Andric              !strconcat(opcStr, " $sx, $sz, $sy"),
750bdd1243dSDimitry Andric              [(set i64:$sx, (OpNode (Ty immOp:$sy), (i64 mimm:$sz), i64:$sd,
751bdd1243dSDimitry Andric                                     (i32 CCOp:$cfw)))]>;
7525ffd83dbSDimitry Andric}
7535ffd83dbSDimitry Andric
7545ffd83dbSDimitry Andric// Multiclass for floating point conversion instructions.
7555ffd83dbSDimitry Andric//   e.g. CVTWDSX, CVTWDZX, CVTWSSX, and etc.
7565ffd83dbSDimitry Andric// sz{3-0} = rounding mode
7575ffd83dbSDimitry Andriclet cz = 0, hasSideEffects = 0 in
758349cc55cSDimitry Andricmulticlass CVTRDm<string opcStr, bits<8> opc, RegisterClass RCo,
759349cc55cSDimitry Andric                  RegisterClass RCi> {
7605ffd83dbSDimitry Andric  def r : RR<opc, (outs RCo:$sx), (ins RDOp:$rd, RCi:$sy),
7615ffd83dbSDimitry Andric             !strconcat(opcStr, "${rd} $sx, $sy")> {
7625ffd83dbSDimitry Andric    bits<4> rd;
76306c3fb27SDimitry Andric    let sz{6-4} = 0;
7645ffd83dbSDimitry Andric    let sz{3-0} = rd;
7655ffd83dbSDimitry Andric  }
7665ffd83dbSDimitry Andric  let cy = 0 in
7675ffd83dbSDimitry Andric  def i : RR<opc, (outs RCo:$sx), (ins RDOp:$rd, simm7:$sy),
7685ffd83dbSDimitry Andric             !strconcat(opcStr, "${rd} $sx, $sy")> {
7695ffd83dbSDimitry Andric    bits<4> rd;
77006c3fb27SDimitry Andric    let sz{6-4} = 0;
7715ffd83dbSDimitry Andric    let sz{3-0} = rd;
772480093f4SDimitry Andric  }
773480093f4SDimitry Andric}
774480093f4SDimitry Andric
7755ffd83dbSDimitry Andric// Multiclass for floating point conversion instructions.
7765ffd83dbSDimitry Andric//   e.g. CVTDW, CVTSW, CVTDL, and etc.
7775ffd83dbSDimitry Andriclet cz = 0, sz = 0, hasSideEffects = 0 in
7785ffd83dbSDimitry Andricmulticlass CVTm<string opcStr, bits<8> opc, RegisterClass RCo, ValueType Tyo,
7795ffd83dbSDimitry Andric                RegisterClass RCi, ValueType Tyi,
7805ffd83dbSDimitry Andric                SDPatternOperator OpNode = null_frag> {
7815ffd83dbSDimitry Andric  def r : RR<opc, (outs RCo:$sx), (ins RCi:$sy),
7825ffd83dbSDimitry Andric             !strconcat(opcStr, " $sx, $sy"),
7835ffd83dbSDimitry Andric             [(set Tyo:$sx, (OpNode Tyi:$sy))]>;
7845ffd83dbSDimitry Andric  let cy = 0 in
7855ffd83dbSDimitry Andric  def i : RR<opc, (outs RCo:$sx), (ins simm7:$sy),
7865ffd83dbSDimitry Andric             !strconcat(opcStr, " $sx, $sy")>;
7875ffd83dbSDimitry Andric}
7885ffd83dbSDimitry Andric
7895ffd83dbSDimitry Andric// Multiclass for PFCH instructions.
7905ffd83dbSDimitry Andric//   e.g. PFCH
7915ffd83dbSDimitry Andriclet sx = 0, hasSideEffects = 0 in
7925ffd83dbSDimitry Andricmulticlass PFCHm<string opcStr, bits<8>opc> {
79306c3fb27SDimitry Andric  def rri : RM<opc, (outs), (ins (MEMrri $sz, $sy, $imm32):$addr), !strconcat(opcStr, " $addr"),
7945ffd83dbSDimitry Andric               [(prefetch ADDRrri:$addr, imm, imm, (i32 1))]>;
7955ffd83dbSDimitry Andric  let cy = 0 in
79606c3fb27SDimitry Andric  def rii : RM<opc, (outs), (ins (MEMrii $sz, $sy, $imm32):$addr), !strconcat(opcStr, " $addr"),
7975ffd83dbSDimitry Andric               [(prefetch ADDRrii:$addr, imm, imm, (i32 1))]>;
7985ffd83dbSDimitry Andric  let cz = 0 in
79906c3fb27SDimitry Andric  def zri : RM<opc, (outs), (ins (MEMzri $sz, $sy, $imm32):$addr), !strconcat(opcStr, " $addr"),
8005ffd83dbSDimitry Andric               [(prefetch ADDRzri:$addr, imm, imm, (i32 1))]>;
8015ffd83dbSDimitry Andric  let cy = 0, cz = 0 in
80206c3fb27SDimitry Andric  def zii : RM<opc, (outs), (ins (MEMzii $sz, $sy, $imm32):$addr), !strconcat(opcStr, " $addr"),
8035ffd83dbSDimitry Andric               [(prefetch ADDRzii:$addr, imm, imm, (i32 1))]>;
8045ffd83dbSDimitry Andric}
8055ffd83dbSDimitry Andric
8065ffd83dbSDimitry Andric// Multiclass for CAS instructions.
8075ffd83dbSDimitry Andric//   e.g. TS1AML, TS1AMW, TS2AM, and etc.
80806c3fb27SDimitry Andriclet Constraints = "$sx = $sd", DisableEncoding = "$sd",
8095ffd83dbSDimitry Andric    mayStore=1, mayLoad = 1, hasSideEffects = 0 in
8105ffd83dbSDimitry Andricmulticlass RRCAStgm<string opcStr, bits<8>opc, RegisterClass RC, ValueType Ty,
811fe6060f1SDimitry Andric                    Operand immOp, Operand MEM, ComplexPattern ADDR,
8125ffd83dbSDimitry Andric                    SDPatternOperator OpNode = null_frag> {
81306c3fb27SDimitry Andric  def r : RRM<opc, (outs RC:$sx), (ins (MEM $sz, $imm32):$addr, RC:$sy, RC:$sd),
81406c3fb27SDimitry Andric              !strconcat(opcStr, " $sx, $addr, $sy"),
81506c3fb27SDimitry Andric              [(set Ty:$sx, (OpNode ADDR:$addr, Ty:$sy, Ty:$sd))]>;
8165ffd83dbSDimitry Andric  let cy = 0 in
81706c3fb27SDimitry Andric  def i : RRM<opc, (outs RC:$sx), (ins (MEM $sz, $imm32):$addr, immOp:$sy, RC:$sd),
81806c3fb27SDimitry Andric              !strconcat(opcStr, " $sx, $addr, $sy"),
81906c3fb27SDimitry Andric              [(set Ty:$sx, (OpNode ADDR:$addr, (Ty immOp:$sy), Ty:$sd))]>;
8205ffd83dbSDimitry Andric}
8215ffd83dbSDimitry Andricmulticlass RRCASm<string opcStr, bits<8>opc, RegisterClass RC, ValueType Ty,
8225ffd83dbSDimitry Andric                  Operand immOp, SDPatternOperator OpNode = null_frag> {
8235ffd83dbSDimitry Andric  defm ri : RRCAStgm<opcStr, opc, RC, Ty, immOp, MEMriRRM, ADDRri, OpNode>;
8245ffd83dbSDimitry Andric  let cz = 0 in
8255ffd83dbSDimitry Andric  defm zi : RRCAStgm<opcStr, opc, RC, Ty, immOp, MEMziRRM, ADDRzi, OpNode>;
8265ffd83dbSDimitry Andric}
8275ffd83dbSDimitry Andric
8285ffd83dbSDimitry Andric// Multiclass for branch instructions
8295ffd83dbSDimitry Andric//   e.g. BCFL, BCFW, BCFD, and etc.
8305ffd83dbSDimitry Andriclet isBranch = 1, isTerminator = 1, isIndirectBranch = 1, hasSideEffects = 0 in
8315ffd83dbSDimitry Andricmulticlass BCbpfm<string opcStr, string cmpStr, bits<8> opc, dag cond,
8325ffd83dbSDimitry Andric                  Operand ADDR> {
8335ffd83dbSDimitry Andric  let bpf = 0 /* NONE */ in
83406c3fb27SDimitry Andric  def "" : CF<opc, (outs), !con(cond, (ins (ADDR $sz, $imm32):$addr)),
8355ffd83dbSDimitry Andric              !strconcat(opcStr, " ", cmpStr, "$addr")>;
836e8d8bef9SDimitry Andric  let bpf = 2 /* NOT TAKEN */ in
83706c3fb27SDimitry Andric  def _nt : CF<opc, (outs), !con(cond, (ins (ADDR $sz, $imm32):$addr)),
8385ffd83dbSDimitry Andric               !strconcat(opcStr, ".nt ", cmpStr, "$addr")>;
839e8d8bef9SDimitry Andric  let bpf = 3 /* TAKEN */ in
84006c3fb27SDimitry Andric  def _t : CF<opc, (outs), !con(cond, (ins (ADDR $sz, $imm32):$addr)),
8415ffd83dbSDimitry Andric              !strconcat(opcStr, ".t ", cmpStr, "$addr")>;
8425ffd83dbSDimitry Andric}
8435ffd83dbSDimitry Andricmulticlass BCtgm<string opcStr, string cmpStr, bits<8> opc, dag cond> {
8445ffd83dbSDimitry Andric  defm ri : BCbpfm<opcStr, cmpStr, opc, cond, MEMriASX>;
8455ffd83dbSDimitry Andric  let cz = 0 in defm zi : BCbpfm<opcStr, cmpStr, opc, cond, MEMziASX>;
8465ffd83dbSDimitry Andric}
8475ffd83dbSDimitry Andricmulticlass BCm<string opcStr, string opcStrAt, string opcStrAf, bits<8> opc,
8485ffd83dbSDimitry Andric               RegisterClass RC, Operand immOp> {
8495ffd83dbSDimitry Andric  let DecoderMethod = "DecodeBranchCondition" in
85006c3fb27SDimitry Andric  defm r : BCtgm<opcStr, "$sy, ", opc, (ins CCOp:$cond, RC:$sy)>;
8515ffd83dbSDimitry Andric  let DecoderMethod = "DecodeBranchCondition", cy = 0 in
85206c3fb27SDimitry Andric  defm i : BCtgm<opcStr, "$sy, ", opc, (ins CCOp:$cond, immOp:$sy)>;
8535ffd83dbSDimitry Andric  let DecoderMethod = "DecodeBranchConditionAlways", cy = 0, sy = 0,
85406c3fb27SDimitry Andric      cond = 15 /* AT */, isBarrier = 1 in
8555ffd83dbSDimitry Andric  defm a : BCtgm<opcStrAt, "", opc, (ins)>;
8565ffd83dbSDimitry Andric  let DecoderMethod = "DecodeBranchConditionAlways", cy = 0, sy = 0,
85706c3fb27SDimitry Andric      cond = 0 /* AF */ in
8585ffd83dbSDimitry Andric  defm na : BCtgm<opcStrAf, "", opc, (ins)>;
8595ffd83dbSDimitry Andric}
8605ffd83dbSDimitry Andric
8615ffd83dbSDimitry Andric// Multiclass for relative branch instructions
8625ffd83dbSDimitry Andric//   e.g. BRCFL, BRCFW, BRCFD, and etc.
8635ffd83dbSDimitry Andriclet isBranch = 1, isTerminator = 1, hasSideEffects = 0 in
8645ffd83dbSDimitry Andricmulticlass BCRbpfm<string opcStr, string cmpStr, bits<8> opc, dag cond> {
8655ffd83dbSDimitry Andric  let bpf = 0 /* NONE */ in
8665ffd83dbSDimitry Andric  def "" : CF<opc, (outs), !con(cond, (ins brtarget32:$imm32)),
8675ffd83dbSDimitry Andric              !strconcat(opcStr, " ", cmpStr, "$imm32")>;
868e8d8bef9SDimitry Andric  let bpf = 2 /* NOT TAKEN */ in
8695ffd83dbSDimitry Andric  def _nt : CF<opc, (outs), !con(cond, (ins brtarget32:$imm32)),
8705ffd83dbSDimitry Andric               !strconcat(opcStr, ".nt ", cmpStr, "$imm32")>;
871e8d8bef9SDimitry Andric  let bpf = 3 /* TAKEN */ in
8725ffd83dbSDimitry Andric  def _t : CF<opc, (outs), !con(cond, (ins brtarget32:$imm32)),
8735ffd83dbSDimitry Andric              !strconcat(opcStr, ".t ", cmpStr, "$imm32")>;
8745ffd83dbSDimitry Andric}
8755ffd83dbSDimitry Andricmulticlass BCRm<string opcStr, string opcStrAt, string opcStrAf, bits<8> opc,
876e8d8bef9SDimitry Andric               RegisterClass RC, Operand immOp, Operand zeroOp> {
87706c3fb27SDimitry Andric  defm rr : BCRbpfm<opcStr, "$sy, $sz, ", opc, (ins CCOp:$cond, RC:$sy, RC:$sz)>;
8785ffd83dbSDimitry Andric  let cy = 0 in
87906c3fb27SDimitry Andric  defm ir : BCRbpfm<opcStr, "$sy, $sz, ", opc, (ins CCOp:$cond, immOp:$sy,
880e8d8bef9SDimitry Andric                                                    RC:$sz)>;
881e8d8bef9SDimitry Andric  let cz = 0 in
88206c3fb27SDimitry Andric  defm rz : BCRbpfm<opcStr, "$sy, $sz, ", opc, (ins CCOp:$cond, RC:$sy,
883e8d8bef9SDimitry Andric                                                    zeroOp:$sz)>;
884e8d8bef9SDimitry Andric  let cy = 0, cz = 0 in
88506c3fb27SDimitry Andric  defm iz : BCRbpfm<opcStr, "$sy, $sz, ", opc, (ins CCOp:$cond, immOp:$sy,
886e8d8bef9SDimitry Andric                                                    zeroOp:$sz)>;
88706c3fb27SDimitry Andric  let cy = 0, sy = 0, cz = 0, sz = 0, cond = 15 /* AT */, isBarrier = 1 in
8885ffd83dbSDimitry Andric  defm a : BCRbpfm<opcStrAt, "", opc, (ins)>;
88906c3fb27SDimitry Andric  let cy = 0, sy = 0, cz = 0, sz = 0, cond = 0 /* AF */ in
8905ffd83dbSDimitry Andric  defm na : BCRbpfm<opcStrAf, "", opc, (ins)>;
8915ffd83dbSDimitry Andric}
8925ffd83dbSDimitry Andric
8935ffd83dbSDimitry Andric// Multiclass for communication register instructions.
8945ffd83dbSDimitry Andric//   e.g. LCR
8955ffd83dbSDimitry Andriclet hasSideEffects = 1 in
8965ffd83dbSDimitry Andricmulticlass LOADCRm<string opcStr, bits<8>opc, RegisterClass RC> {
89781ad6265SDimitry Andric  def rr : RR<opc, (outs RC:$sx), (ins RC:$sy, RC:$sz),
8985ffd83dbSDimitry Andric              !strconcat(opcStr, " $sx, $sy, $sz")>;
89981ad6265SDimitry Andric  let cy = 0 in def ir : RR<opc, (outs RC:$sx), (ins simm7:$sy, RC:$sz),
9005ffd83dbSDimitry Andric                            !strconcat(opcStr, " $sx, $sy, $sz")>;
90181ad6265SDimitry Andric  let cz = 0 in def rz : RR<opc, (outs RC:$sx), (ins RC:$sy, zero:$sz),
9025ffd83dbSDimitry Andric                            !strconcat(opcStr, " $sx, $sy, $sz")>;
9035ffd83dbSDimitry Andric  let cy = 0, cz = 0 in
90481ad6265SDimitry Andric  def iz : RR<opc, (outs RC:$sx), (ins simm7:$sy, zero:$sz),
9055ffd83dbSDimitry Andric              !strconcat(opcStr, " $sx, $sy, $sz")>;
9065ffd83dbSDimitry Andric}
9075ffd83dbSDimitry Andric
9085ffd83dbSDimitry Andric// Multiclass for communication register instructions.
9095ffd83dbSDimitry Andric//   e.g. SCR
9105ffd83dbSDimitry Andriclet hasSideEffects = 1 in
9115ffd83dbSDimitry Andricmulticlass STORECRm<string opcStr, bits<8>opc, RegisterClass RC> {
91281ad6265SDimitry Andric  def rrr : RR<opc, (outs), (ins RC:$sy, RC:$sz, RC:$sx),
9135ffd83dbSDimitry Andric              !strconcat(opcStr, " $sx, $sy, $sz")>;
91481ad6265SDimitry Andric  let cy = 0 in def irr : RR<opc, (outs), (ins simm7:$sy, RC:$sz, RC:$sx),
9155ffd83dbSDimitry Andric                             !strconcat(opcStr, " $sx, $sy, $sz")>;
91681ad6265SDimitry Andric  let cz = 0 in def rzr : RR<opc, (outs), (ins RC:$sy, zero:$sz, RC:$sx),
9175ffd83dbSDimitry Andric                             !strconcat(opcStr, " $sx, $sy, $sz")>;
9185ffd83dbSDimitry Andric  let cy = 0, cz = 0 in
91981ad6265SDimitry Andric  def izr : RR<opc, (outs), (ins simm7:$sy, zero:$sz, RC:$sx),
9205ffd83dbSDimitry Andric               !strconcat(opcStr, " $sx, $sy, $sz")>;
9215ffd83dbSDimitry Andric}
9225ffd83dbSDimitry Andric
92381ad6265SDimitry Andriclet hasSideEffects = 1, Constraints = "$sx = $sx_in", DisableEncoding = "$sx_in" in
92481ad6265SDimitry Andricmulticlass TSCRm<string opcStr, bits<8>opc, RegisterClass RC> {
92581ad6265SDimitry Andric  def rrr : RR<opc, (outs RC:$sx), (ins RC:$sy, RC:$sz, RC:$sx_in),
92681ad6265SDimitry Andric               !strconcat(opcStr, " $sx, $sy, $sz")>;
92781ad6265SDimitry Andric  let cy = 0 in def irr : RR<opc, (outs RC:$sx), (ins simm7:$sy, RC:$sz, RC:$sx_in),
92881ad6265SDimitry Andric                             !strconcat(opcStr, " $sx, $sy, $sz")>;
92981ad6265SDimitry Andric  let cz = 0 in def rzr : RR<opc, (outs RC:$sx), (ins RC:$sy, zero:$sz, RC:$sx_in),
93081ad6265SDimitry Andric                             !strconcat(opcStr, " $sx, $sy, $sz")>;
93181ad6265SDimitry Andric  let cy = 0, cz = 0 in
93281ad6265SDimitry Andric  def izr : RR<opc, (outs RC:$sx), (ins simm7:$sy, zero:$sz, RC:$sx_in),
93381ad6265SDimitry Andric               !strconcat(opcStr, " $sx, $sy, $sz")>;
93481ad6265SDimitry Andric}
93581ad6265SDimitry Andric
93681ad6265SDimitry Andric
9375ffd83dbSDimitry Andric// Multiclass for communication register instructions.
9385ffd83dbSDimitry Andric//   e.g. FIDCR
9395ffd83dbSDimitry Andriclet cz = 0, hasSideEffects = 1 in
9405ffd83dbSDimitry Andricmulticlass FIDCRm<string opcStr, bits<8>opc, RegisterClass RC> {
9415ffd83dbSDimitry Andric  def ri : RR<opc, (outs RC:$sx), (ins RC:$sy, uimm3:$sz),
9425ffd83dbSDimitry Andric              !strconcat(opcStr, " $sx, $sy, $sz")>;
9435ffd83dbSDimitry Andric  let cy = 0 in def ii : RR<opc, (outs RC:$sx), (ins simm7:$sy, uimm3:$sz),
9445ffd83dbSDimitry Andric                            !strconcat(opcStr, " $sx, $sy, $sz")>;
9455ffd83dbSDimitry Andric}
9465ffd83dbSDimitry Andric
9475ffd83dbSDimitry Andric// Multiclass for LHM instruction.
9485ffd83dbSDimitry Andriclet mayLoad = 1, hasSideEffects = 0 in
9495ffd83dbSDimitry Andricmulticlass LHMm<string opcStr, bits<8> opc, RegisterClass RC> {
95006c3fb27SDimitry Andric  def ri : RRMHM<opc, (outs RC:$sx), (ins (MEMriHM $sz, $imm32):$addr),
95106c3fb27SDimitry Andric                 !strconcat(opcStr, " $sx, $addr")>;
9525ffd83dbSDimitry Andric  let cz = 0 in
95306c3fb27SDimitry Andric  def zi : RRMHM<opc, (outs RC:$sx), (ins (MEMziHM $sz, $imm32):$addr),
95406c3fb27SDimitry Andric                 !strconcat(opcStr, " $sx, $addr")>;
9555ffd83dbSDimitry Andric}
9565ffd83dbSDimitry Andric
9575ffd83dbSDimitry Andric// Multiclass for SHM instruction.
9585ffd83dbSDimitry Andriclet mayStore = 1, hasSideEffects = 0 in
9595ffd83dbSDimitry Andricmulticlass SHMm<string opcStr, bits<8> opc, RegisterClass RC> {
96006c3fb27SDimitry Andric  def ri : RRMHM<opc, (outs), (ins (MEMriHM $sz, $imm32):$addr, RC:$sx),
9615ffd83dbSDimitry Andric                 !strconcat(opcStr, " $sx, $addr")>;
9625ffd83dbSDimitry Andric  let cz = 0 in
96306c3fb27SDimitry Andric  def zi : RRMHM<opc, (outs), (ins (MEMziHM $sz, $imm32):$addr, RC:$sx),
9645ffd83dbSDimitry Andric                 !strconcat(opcStr, " $sx, $addr")>;
9655ffd83dbSDimitry Andric}
966480093f4SDimitry Andric
967480093f4SDimitry Andric//===----------------------------------------------------------------------===//
968480093f4SDimitry Andric// Instructions
9695ffd83dbSDimitry Andric//
9705ffd83dbSDimitry Andric// Define all scalar instructions defined in SX-Aurora TSUBASA Architecture
9715ffd83dbSDimitry Andric// Guide here.  As those mnemonics, we use mnemonics defined in Vector Engine
9725ffd83dbSDimitry Andric// Assembly Language Reference Manual.
973480093f4SDimitry Andric//===----------------------------------------------------------------------===//
974480093f4SDimitry Andric
9755ffd83dbSDimitry Andric//-----------------------------------------------------------------------------
9765ffd83dbSDimitry Andric// Section 8.2 - Load/Store instructions
9775ffd83dbSDimitry Andric//-----------------------------------------------------------------------------
9785ffd83dbSDimitry Andric
9795ffd83dbSDimitry Andric// Multiclass for generic RM instructions
980e8d8bef9SDimitry Andricmulticlass RMm<string opcStr, bits<8>opc, RegisterClass RC, bit MoveImm = 0> {
98106c3fb27SDimitry Andric  def rri : RM<opc, (outs RC:$sx), (ins (MEMrri $sz, $sy, $imm32):$addr),
98206c3fb27SDimitry Andric               !strconcat(opcStr, " $sx, $addr"), []>;
9835ffd83dbSDimitry Andric  let cy = 0 in
98406c3fb27SDimitry Andric  def rii : RM<opc, (outs RC:$sx), (ins (MEMrii $sz, $sy, $imm32):$addr),
98506c3fb27SDimitry Andric               !strconcat(opcStr, " $sx, $addr"), []>;
9865ffd83dbSDimitry Andric  let cz = 0 in
98706c3fb27SDimitry Andric  def zri : RM<opc, (outs RC:$sx), (ins (MEMzri $sz, $sy, $imm32):$addr),
98806c3fb27SDimitry Andric               !strconcat(opcStr, " $sx, $addr"), []>;
9895ffd83dbSDimitry Andric  let cy = 0, cz = 0 in
99006c3fb27SDimitry Andric  def zii : RM<opc, (outs RC:$sx), (ins (MEMzii $sz, $sy, $imm32):$addr),
99106c3fb27SDimitry Andric               !strconcat(opcStr, " $sx, $addr"), []> {
992e8d8bef9SDimitry Andric    // VE uses LEAzii and LEASLzii as a move immediate instruction, so declare
993e8d8bef9SDimitry Andric    // it here.  An instruction declared as MoveImm will be optimized in
994e8d8bef9SDimitry Andric    // FoldImmediate later.
995e8d8bef9SDimitry Andric    let isMoveImm = MoveImm;
996e8d8bef9SDimitry Andric  }
9975ffd83dbSDimitry Andric}
9985ffd83dbSDimitry Andric
9995ffd83dbSDimitry Andric// Section 8.2.1 - LEA
1000e8d8bef9SDimitry Andriclet isReMaterializable = 1, isAsCheapAsAMove = 1,
1001e8d8bef9SDimitry Andric    DecoderMethod = "DecodeLoadI64" in {
1002e8d8bef9SDimitry Andric  let cx = 0 in defm LEA : RMm<"lea", 0x06, I64, /* MoveImm */ 1>;
1003e8d8bef9SDimitry Andric  let cx = 1 in defm LEASL : RMm<"lea.sl", 0x06, I64, /* MoveImm */ 1>;
1004e8d8bef9SDimitry Andric}
10055ffd83dbSDimitry Andric
1006e8d8bef9SDimitry Andric// LEA basic patterns.
1007e8d8bef9SDimitry Andric//   Need to be defined here to prioritize LEA over ADX.
10085ffd83dbSDimitry Andricdef : Pat<(iPTR ADDRrri:$addr), (LEArri MEMrri:$addr)>;
10095ffd83dbSDimitry Andricdef : Pat<(iPTR ADDRrii:$addr), (LEArii MEMrii:$addr)>;
10105ffd83dbSDimitry Andricdef : Pat<(add I64:$base, simm32:$disp), (LEArii $base, 0, (LO32 $disp))>;
10115ffd83dbSDimitry Andricdef : Pat<(add I64:$base, lozero:$disp), (LEASLrii $base, 0, (HI32 $disp))>;
10125ffd83dbSDimitry Andric
10135ffd83dbSDimitry Andric// Multiclass for load instructions.
10145ffd83dbSDimitry Andriclet mayLoad = 1, hasSideEffects = 0 in
10155ffd83dbSDimitry Andricmulticlass LOADm<string opcStr, bits<8> opc, RegisterClass RC, ValueType Ty,
10165ffd83dbSDimitry Andric                 SDPatternOperator OpNode = null_frag> {
101706c3fb27SDimitry Andric  def rri : RM<opc, (outs RC:$sx), (ins (MEMrri $sz, $sy, $imm32):$addr),
101806c3fb27SDimitry Andric               !strconcat(opcStr, " $sx, $addr"),
101906c3fb27SDimitry Andric               [(set Ty:$sx, (OpNode ADDRrri:$addr))]>;
10205ffd83dbSDimitry Andric  let cy = 0 in
102106c3fb27SDimitry Andric  def rii : RM<opc, (outs RC:$sx), (ins (MEMrii $sz, $sy, $imm32):$addr),
102206c3fb27SDimitry Andric               !strconcat(opcStr, " $sx, $addr"),
102306c3fb27SDimitry Andric               [(set Ty:$sx, (OpNode ADDRrii:$addr))]>;
10245ffd83dbSDimitry Andric  let cz = 0 in
102506c3fb27SDimitry Andric  def zri : RM<opc, (outs RC:$sx), (ins (MEMzri $sz, $sy, $imm32):$addr),
102606c3fb27SDimitry Andric               !strconcat(opcStr, " $sx, $addr"),
102706c3fb27SDimitry Andric               [(set Ty:$sx, (OpNode ADDRzri:$addr))]>;
10285ffd83dbSDimitry Andric  let cy = 0, cz = 0 in
102906c3fb27SDimitry Andric  def zii : RM<opc, (outs RC:$sx), (ins (MEMzii $sz, $sy, $imm32):$addr),
103006c3fb27SDimitry Andric               !strconcat(opcStr, " $sx, $addr"),
103106c3fb27SDimitry Andric               [(set Ty:$sx, (OpNode ADDRzii:$addr))]>;
10325ffd83dbSDimitry Andric}
10335ffd83dbSDimitry Andric
10345ffd83dbSDimitry Andric// Section 8.2.2 - LDS
10355ffd83dbSDimitry Andriclet DecoderMethod = "DecodeLoadI64" in
10365ffd83dbSDimitry Andricdefm LD : LOADm<"ld", 0x01, I64, i64, load>;
10375ffd83dbSDimitry Andricdef : Pat<(f64 (load ADDRrri:$addr)), (LDrri MEMrri:$addr)>;
10385ffd83dbSDimitry Andricdef : Pat<(f64 (load ADDRrii:$addr)), (LDrii MEMrii:$addr)>;
10395ffd83dbSDimitry Andricdef : Pat<(f64 (load ADDRzri:$addr)), (LDzri MEMzri:$addr)>;
10405ffd83dbSDimitry Andricdef : Pat<(f64 (load ADDRzii:$addr)), (LDzii MEMzii:$addr)>;
10415ffd83dbSDimitry Andric
10425ffd83dbSDimitry Andric// Section 8.2.3 - LDU
10435ffd83dbSDimitry Andriclet DecoderMethod = "DecodeLoadF32" in
10445ffd83dbSDimitry Andricdefm LDU : LOADm<"ldu", 0x02, F32, f32, load>;
10455ffd83dbSDimitry Andric
10465ffd83dbSDimitry Andric// Section 8.2.4 - LDL
10475ffd83dbSDimitry Andriclet DecoderMethod = "DecodeLoadI32" in
10485ffd83dbSDimitry Andricdefm LDLSX : LOADm<"ldl.sx", 0x03, I32, i32, load>;
10495ffd83dbSDimitry Andriclet cx = 1, DecoderMethod = "DecodeLoadI32" in
10505ffd83dbSDimitry Andricdefm LDLZX : LOADm<"ldl.zx", 0x03, I32, i32, load>;
10515ffd83dbSDimitry Andric
10525ffd83dbSDimitry Andric// Section 8.2.5 - LD2B
10535ffd83dbSDimitry Andriclet DecoderMethod = "DecodeLoadI32" in
10545ffd83dbSDimitry Andricdefm LD2BSX : LOADm<"ld2b.sx", 0x04, I32, i32, sextloadi16>;
10555ffd83dbSDimitry Andriclet cx = 1, DecoderMethod = "DecodeLoadI32" in
10565ffd83dbSDimitry Andricdefm LD2BZX : LOADm<"ld2b.zx", 0x04, I32, i32, zextloadi16>;
10575ffd83dbSDimitry Andric
10585ffd83dbSDimitry Andric// Section 8.2.6 - LD1B
10595ffd83dbSDimitry Andriclet DecoderMethod = "DecodeLoadI32" in
10605ffd83dbSDimitry Andricdefm LD1BSX : LOADm<"ld1b.sx", 0x05, I32, i32, sextloadi8>;
10615ffd83dbSDimitry Andriclet cx = 1, DecoderMethod = "DecodeLoadI32" in
10625ffd83dbSDimitry Andricdefm LD1BZX : LOADm<"ld1b.zx", 0x05, I32, i32, zextloadi8>;
10635ffd83dbSDimitry Andric
1064e8d8bef9SDimitry Andric// LDQ pseudo instructions
1065e8d8bef9SDimitry Andriclet mayLoad = 1, hasSideEffects = 0 in {
1066e8d8bef9SDimitry Andric  def LDQrii : Pseudo<(outs F128:$dest), (ins MEMrii:$addr),
1067e8d8bef9SDimitry Andric                      "# pseudo ldq $dest, $addr",
1068e8d8bef9SDimitry Andric                      [(set f128:$dest, (load ADDRrii:$addr))]>;
1069e8d8bef9SDimitry Andric}
1070e8d8bef9SDimitry Andric
10715ffd83dbSDimitry Andric// Multiclass for store instructions.
10725ffd83dbSDimitry Andriclet mayStore = 1 in
10735ffd83dbSDimitry Andricmulticlass STOREm<string opcStr, bits<8> opc, RegisterClass RC, ValueType Ty,
10745ffd83dbSDimitry Andric                  SDPatternOperator OpNode = null_frag> {
107506c3fb27SDimitry Andric  def rri : RM<opc, (outs), (ins (MEMrri $sz, $sy, $imm32):$addr, RC:$sx),
10765ffd83dbSDimitry Andric               !strconcat(opcStr, " $sx, $addr"),
10775ffd83dbSDimitry Andric               [(OpNode Ty:$sx, ADDRrri:$addr)]>;
10785ffd83dbSDimitry Andric  let cy = 0 in
107906c3fb27SDimitry Andric  def rii : RM<opc, (outs), (ins (MEMrii $sz, $sy, $imm32):$addr, RC:$sx),
10805ffd83dbSDimitry Andric               !strconcat(opcStr, " $sx, $addr"),
10815ffd83dbSDimitry Andric               [(OpNode Ty:$sx, ADDRrii:$addr)]>;
10825ffd83dbSDimitry Andric  let cz = 0 in
108306c3fb27SDimitry Andric  def zri : RM<opc, (outs), (ins (MEMzri $sz, $sy, $imm32):$addr, RC:$sx),
10845ffd83dbSDimitry Andric               !strconcat(opcStr, " $sx, $addr"),
10855ffd83dbSDimitry Andric               [(OpNode Ty:$sx, ADDRzri:$addr)]>;
10865ffd83dbSDimitry Andric  let cy = 0, cz = 0 in
108706c3fb27SDimitry Andric  def zii : RM<opc, (outs), (ins (MEMzii $sz, $sy, $imm32):$addr, RC:$sx),
10885ffd83dbSDimitry Andric               !strconcat(opcStr, " $sx, $addr"),
10895ffd83dbSDimitry Andric               [(OpNode Ty:$sx, ADDRzii:$addr)]>;
10905ffd83dbSDimitry Andric}
10915ffd83dbSDimitry Andric
10925ffd83dbSDimitry Andric// Section 8.2.7 - STS
10935ffd83dbSDimitry Andriclet DecoderMethod = "DecodeStoreI64" in
10945ffd83dbSDimitry Andricdefm ST : STOREm<"st", 0x11, I64, i64, store>;
10955ffd83dbSDimitry Andricdef : Pat<(store f64:$src, ADDRrri:$addr), (STrri MEMrri:$addr, $src)>;
10965ffd83dbSDimitry Andricdef : Pat<(store f64:$src, ADDRrii:$addr), (STrii MEMrii:$addr, $src)>;
10975ffd83dbSDimitry Andricdef : Pat<(store f64:$src, ADDRzri:$addr), (STzri MEMzri:$addr, $src)>;
10985ffd83dbSDimitry Andricdef : Pat<(store f64:$src, ADDRzii:$addr), (STzii MEMzii:$addr, $src)>;
10995ffd83dbSDimitry Andric
11005ffd83dbSDimitry Andric// Section 8.2.8 - STU
11015ffd83dbSDimitry Andriclet DecoderMethod = "DecodeStoreF32" in
11025ffd83dbSDimitry Andricdefm STU : STOREm<"stu", 0x12, F32, f32, store>;
11035ffd83dbSDimitry Andric
11045ffd83dbSDimitry Andric// Section 8.2.9 - STL
11055ffd83dbSDimitry Andriclet DecoderMethod = "DecodeStoreI32" in
11065ffd83dbSDimitry Andricdefm STL : STOREm<"stl", 0x13, I32, i32, store>;
11075ffd83dbSDimitry Andric
11085ffd83dbSDimitry Andric// Section 8.2.10 - ST2B
11095ffd83dbSDimitry Andriclet DecoderMethod = "DecodeStoreI32" in
11105ffd83dbSDimitry Andricdefm ST2B : STOREm<"st2b", 0x14, I32, i32, truncstorei16>;
11115ffd83dbSDimitry Andric
11125ffd83dbSDimitry Andric// Section 8.2.11 - ST1B
11135ffd83dbSDimitry Andriclet DecoderMethod = "DecodeStoreI32" in
11145ffd83dbSDimitry Andricdefm ST1B : STOREm<"st1b", 0x15, I32, i32, truncstorei8>;
11155ffd83dbSDimitry Andric
1116e8d8bef9SDimitry Andric// STQ pseudo instructions
1117e8d8bef9SDimitry Andriclet mayStore = 1, hasSideEffects = 0 in {
1118e8d8bef9SDimitry Andric  def STQrii : Pseudo<(outs), (ins MEMrii:$addr, F128:$sx),
1119e8d8bef9SDimitry Andric                      "# pseudo stq $sx, $addr",
1120e8d8bef9SDimitry Andric                      [(store f128:$sx, ADDRrii:$addr)]>;
1121e8d8bef9SDimitry Andric}
1122e8d8bef9SDimitry Andric
11235ffd83dbSDimitry Andric// Section 8.2.12 - DLDS
11245ffd83dbSDimitry Andriclet DecoderMethod = "DecodeLoadI64" in
11255ffd83dbSDimitry Andricdefm DLD : LOADm<"dld", 0x09, I64, i64, load>;
11265ffd83dbSDimitry Andric
11275ffd83dbSDimitry Andric// Section 8.2.13 - DLDU
11285ffd83dbSDimitry Andriclet DecoderMethod = "DecodeLoadF32" in
11295ffd83dbSDimitry Andricdefm DLDU : LOADm<"dldu", 0x0a, F32, f32, load>;
11305ffd83dbSDimitry Andric
11315ffd83dbSDimitry Andric// Section 8.2.14 - DLDL
11325ffd83dbSDimitry Andriclet DecoderMethod = "DecodeLoadI32" in
11335ffd83dbSDimitry Andricdefm DLDLSX : LOADm<"dldl.sx", 0x0b, I32, i32, load>;
11345ffd83dbSDimitry Andriclet cx = 1, DecoderMethod = "DecodeLoadI32" in
11355ffd83dbSDimitry Andricdefm DLDLZX : LOADm<"dldl.zx", 0x0b, I32, i32, load>;
11365ffd83dbSDimitry Andric
11375ffd83dbSDimitry Andric// Section 8.2.15 - PFCH
11385ffd83dbSDimitry Andriclet DecoderMethod = "DecodeASX" in
11395ffd83dbSDimitry Andricdefm PFCH : PFCHm<"pfch", 0x0c>;
11405ffd83dbSDimitry Andric
11415ffd83dbSDimitry Andric// Section 8.2.16 - TS1AM (Test and Set 1 AM)
11425ffd83dbSDimitry Andriclet DecoderMethod = "DecodeTS1AMI64" in
11435ffd83dbSDimitry Andricdefm TS1AML : RRCASm<"ts1am.l", 0x42, I64, i64, uimm7>;
11445ffd83dbSDimitry Andriclet DecoderMethod = "DecodeTS1AMI32", cx = 1 in
11455ffd83dbSDimitry Andricdefm TS1AMW : RRCASm<"ts1am.w", 0x42, I32, i32, uimm7>;
11465ffd83dbSDimitry Andric
11475ffd83dbSDimitry Andric// Section 8.2.17 - TS2AM (Test and Set 2 AM)
11485ffd83dbSDimitry Andriclet DecoderMethod = "DecodeTS1AMI64" in
11495ffd83dbSDimitry Andricdefm TS2AM : RRCASm<"ts2am", 0x43, I64, i64, uimm7>;
11505ffd83dbSDimitry Andric
11515ffd83dbSDimitry Andric// Section 8.2.18 - TS3AM (Test and Set 3 AM)
11525ffd83dbSDimitry Andriclet DecoderMethod = "DecodeTS1AMI64" in
11535ffd83dbSDimitry Andricdefm TS3AM : RRCASm<"ts3am", 0x52, I64, i64, uimm1>;
11545ffd83dbSDimitry Andric
11555ffd83dbSDimitry Andric// Section 8.2.19 - ATMAM (Atomic AM)
11565ffd83dbSDimitry Andriclet DecoderMethod = "DecodeTS1AMI64" in
11575ffd83dbSDimitry Andricdefm ATMAM : RRCASm<"atmam", 0x53, I64, i64, uimm0to2>;
11585ffd83dbSDimitry Andric
11595ffd83dbSDimitry Andric// Section 8.2.20 - CAS (Compare and Swap)
11605ffd83dbSDimitry Andriclet DecoderMethod = "DecodeCASI64" in
1161*0fca6ea1SDimitry Andricdefm CASL : RRCASm<"cas.l", 0x62, I64, i64, simm7, atomic_cmp_swap_i64>;
11625ffd83dbSDimitry Andriclet DecoderMethod = "DecodeCASI32", cx = 1 in
1163*0fca6ea1SDimitry Andricdefm CASW : RRCASm<"cas.w", 0x62, I32, i32, simm7, atomic_cmp_swap_i32>;
11645ffd83dbSDimitry Andric
11655ffd83dbSDimitry Andric//-----------------------------------------------------------------------------
11665ffd83dbSDimitry Andric// Section 8.3 - Transfer Control Instructions
11675ffd83dbSDimitry Andric//-----------------------------------------------------------------------------
11685ffd83dbSDimitry Andric
11695ffd83dbSDimitry Andric// Section 8.3.1 - FENCE (Fence)
11705ffd83dbSDimitry Andriclet hasSideEffects = 1 in {
11715ffd83dbSDimitry Andric  let avo = 1 in def FENCEI : RRFENCE<0x20, (outs), (ins), "fencei">;
11725ffd83dbSDimitry Andric  def FENCEM : RRFENCE<0x20, (outs), (ins uimm2:$kind), "fencem $kind"> {
11735ffd83dbSDimitry Andric    bits<2> kind;
11745ffd83dbSDimitry Andric    let lf = kind{1};
11755ffd83dbSDimitry Andric    let sf = kind{0};
11765ffd83dbSDimitry Andric  }
11775ffd83dbSDimitry Andric  def FENCEC : RRFENCE<0x20, (outs), (ins uimm3:$kind), "fencec $kind"> {
11785ffd83dbSDimitry Andric    bits<3> kind;
11795ffd83dbSDimitry Andric    let c2 = kind{2};
11805ffd83dbSDimitry Andric    let c1 = kind{1};
11815ffd83dbSDimitry Andric    let c0 = kind{0};
11825ffd83dbSDimitry Andric  }
11835ffd83dbSDimitry Andric}
11845ffd83dbSDimitry Andric
11855ffd83dbSDimitry Andric// Section 8.3.2 - SVOB (Set Vector Out-of-order memory access Boundary)
11865ffd83dbSDimitry Andriclet sx = 0, cy = 0, sy = 0, cz = 0, sz = 0, hasSideEffects = 1 in
11875ffd83dbSDimitry Andricdef SVOB : RR<0x30, (outs), (ins), "svob">;
11885ffd83dbSDimitry Andric
11895ffd83dbSDimitry Andric//-----------------------------------------------------------------------------
11905ffd83dbSDimitry Andric// Section 8.4 - Fixed-point Operation Instructions
11915ffd83dbSDimitry Andric//-----------------------------------------------------------------------------
11925ffd83dbSDimitry Andric
11935ffd83dbSDimitry Andric// Section 8.4.1 - ADD (Add)
11945ffd83dbSDimitry Andricdefm ADDUL : RRm<"addu.l", 0x48, I64, i64>;
11955ffd83dbSDimitry Andriclet cx = 1 in defm ADDUW : RRm<"addu.w", 0x48, I32, i32>;
11965ffd83dbSDimitry Andric
11975ffd83dbSDimitry Andric// Section 8.4.2 - ADS (Add Single)
11985ffd83dbSDimitry Andricdefm ADDSWSX : RRm<"adds.w.sx", 0x4A, I32, i32, add>;
11995ffd83dbSDimitry Andriclet cx = 1 in defm ADDSWZX : RRm<"adds.w.zx", 0x4A, I32, i32>;
12005ffd83dbSDimitry Andric
12015ffd83dbSDimitry Andric// Section 8.4.3 - ADX (Add)
12025ffd83dbSDimitry Andricdefm ADDSL : RRm<"adds.l", 0x59, I64, i64, add>;
12035ffd83dbSDimitry Andric
12045ffd83dbSDimitry Andric// Section 8.4.4 - SUB (Subtract)
12055ffd83dbSDimitry Andricdefm SUBUL : RRNCm<"subu.l", 0x58, I64, i64>;
12065ffd83dbSDimitry Andriclet cx = 1 in defm SUBUW : RRNCm<"subu.w", 0x58, I32, i32>;
12075ffd83dbSDimitry Andric
12085ffd83dbSDimitry Andric// Section 8.4.5 - SBS (Subtract Single)
12095ffd83dbSDimitry Andricdefm SUBSWSX : RRNCm<"subs.w.sx", 0x5A, I32, i32, sub>;
12105ffd83dbSDimitry Andriclet cx = 1 in defm SUBSWZX : RRNCm<"subs.w.zx", 0x5A, I32, i32>;
12115ffd83dbSDimitry Andric
12125ffd83dbSDimitry Andric// Section 8.4.6 - SBX (Subtract)
12135ffd83dbSDimitry Andricdefm SUBSL : RRNCm<"subs.l", 0x5B, I64, i64, sub>;
12145ffd83dbSDimitry Andric
12155ffd83dbSDimitry Andric// Section 8.4.7 - MPY (Multiply)
12165ffd83dbSDimitry Andricdefm MULUL : RRm<"mulu.l", 0x49, I64, i64>;
12175ffd83dbSDimitry Andriclet cx = 1 in defm MULUW : RRm<"mulu.w", 0x49, I32, i32>;
12185ffd83dbSDimitry Andric
12195ffd83dbSDimitry Andric// Section 8.4.8 - MPS (Multiply Single)
12205ffd83dbSDimitry Andricdefm MULSWSX : RRm<"muls.w.sx", 0x4B, I32, i32, mul>;
12215ffd83dbSDimitry Andriclet cx = 1 in defm MULSWZX : RRm<"muls.w.zx", 0x4B, I32, i32>;
12225ffd83dbSDimitry Andric
12235ffd83dbSDimitry Andric// Section 8.4.9 - MPX (Multiply)
12245ffd83dbSDimitry Andricdefm MULSL : RRm<"muls.l", 0x6E, I64, i64, mul>;
12255ffd83dbSDimitry Andric
12265ffd83dbSDimitry Andric// Section 8.4.10 - MPD (Multiply)
12275ffd83dbSDimitry Andricdefm MULSLW : RRbm<"muls.l.w", 0x6B, I64, i64, I32, i32>;
12285ffd83dbSDimitry Andric
12295ffd83dbSDimitry Andric// Section 8.4.11 - DIV (Divide)
12305ffd83dbSDimitry Andricdefm DIVUL : RRNCm<"divu.l", 0x6F, I64, i64, udiv>;
12315ffd83dbSDimitry Andriclet cx = 1 in defm DIVUW : RRNCm<"divu.w", 0x6F, I32, i32, udiv>;
12325ffd83dbSDimitry Andric
12335ffd83dbSDimitry Andric// Section 8.4.12 - DVS (Divide Single)
12345ffd83dbSDimitry Andricdefm DIVSWSX : RRNCm<"divs.w.sx", 0x7B, I32, i32, sdiv>;
12355ffd83dbSDimitry Andriclet cx = 1 in defm DIVSWZX : RRNCm<"divs.w.zx", 0x7B, I32, i32>;
12365ffd83dbSDimitry Andric
12375ffd83dbSDimitry Andric// Section 8.4.13 - DVX (Divide)
12385ffd83dbSDimitry Andricdefm DIVSL : RRNCm<"divs.l", 0x7F, I64, i64, sdiv>;
12395ffd83dbSDimitry Andric
12405ffd83dbSDimitry Andric// Section 8.4.14 - CMP (Compare)
1241bdd1243dSDimitry Andricdefm CMPUL : RRNCm<"cmpu.l", 0x55, I64, i64, cmpu>;
1242bdd1243dSDimitry Andriclet cx = 1 in defm CMPUW : RRNCm<"cmpu.w", 0x55, I32, i32, cmpu>;
12435ffd83dbSDimitry Andric
12445ffd83dbSDimitry Andric// Section 8.4.15 - CPS (Compare Single)
12455ffd83dbSDimitry Andricdefm CMPSWSX : RRNCm<"cmps.w.sx", 0x7A, I32, i32>;
1246bdd1243dSDimitry Andriclet cx = 1 in defm CMPSWZX : RRNCm<"cmps.w.zx", 0x7A, I32, i32, cmpi>;
12475ffd83dbSDimitry Andric
12485ffd83dbSDimitry Andric// Section 8.4.16 - CPX (Compare)
1249bdd1243dSDimitry Andricdefm CMPSL : RRNCm<"cmps.l", 0x6A, I64, i64, cmpi>;
12505ffd83dbSDimitry Andric
12515ffd83dbSDimitry Andric// Section 8.4.17 - CMS (Compare and Select Maximum/Minimum Single)
12525ffd83dbSDimitry Andric// cx: sx/zx, cw: max/min
1253bdd1243dSDimitry Andricdefm MAXSWSX : RRm<"maxs.w.sx", 0x78, I32, i32, smax>;
12545ffd83dbSDimitry Andriclet cx = 1 in defm MAXSWZX : RRm<"maxs.w.zx", 0x78, I32, i32>;
1255bdd1243dSDimitry Andriclet cw = 1 in defm MINSWSX : RRm<"mins.w.sx", 0x78, I32, i32, smin>;
12565ffd83dbSDimitry Andriclet cx = 1, cw = 1 in defm MINSWZX : RRm<"mins.w.zx", 0x78, I32, i32>;
12575ffd83dbSDimitry Andric
12585ffd83dbSDimitry Andric// Section 8.4.18 - CMX (Compare and Select Maximum/Minimum)
1259bdd1243dSDimitry Andricdefm MAXSL : RRm<"maxs.l", 0x68, I64, i64, smax>;
1260bdd1243dSDimitry Andriclet cw = 1 in defm MINSL : RRm<"mins.l", 0x68, I64, i64, smin>;
1261e8d8bef9SDimitry Andric
12625ffd83dbSDimitry Andric//-----------------------------------------------------------------------------
12635ffd83dbSDimitry Andric// Section 8.5 - Logical Operation Instructions
12645ffd83dbSDimitry Andric//-----------------------------------------------------------------------------
12655ffd83dbSDimitry Andric
12665ffd83dbSDimitry Andric// Section 8.5.1 - AND (AND)
12675ffd83dbSDimitry Andricdefm AND : RRm<"and", 0x44, I64, i64, and>;
12685ffd83dbSDimitry Andric
12695ffd83dbSDimitry Andric// Section 8.5.2 - OR (OR)
1270bdd1243dSDimitry Andriclet isReMaterializable = 1, isAsCheapAsAMove = 1 in
1271e8d8bef9SDimitry Andricdefm OR : RRm<"or", 0x45, I64, i64, or, simm7, mimm, /* MoveImm */ 1>;
12725ffd83dbSDimitry Andric
12735ffd83dbSDimitry Andric// Section 8.5.3 - XOR (Exclusive OR)
12745ffd83dbSDimitry Andricdefm XOR : RRm<"xor", 0x46, I64, i64, xor>;
12755ffd83dbSDimitry Andric
12765ffd83dbSDimitry Andric// Section 8.5.4 - EQV (Equivalence)
12775ffd83dbSDimitry Andricdefm EQV : RRm<"eqv", 0x47, I64, i64>;
12785ffd83dbSDimitry Andric
12795ffd83dbSDimitry Andric// Section 8.5.5 - NND (Negate AND)
12805ffd83dbSDimitry Andricdef and_not : PatFrags<(ops node:$x, node:$y),
12815ffd83dbSDimitry Andric                       [(and (not node:$x), node:$y)]>;
12825ffd83dbSDimitry Andricdefm NND : RRNCm<"nnd", 0x54, I64, i64, and_not>;
12835ffd83dbSDimitry Andric
12845ffd83dbSDimitry Andric// Section 8.5.6 - MRG (Merge)
1285349cc55cSDimitry Andricdefm MRG : RRMRGm<"mrg", 0x56, I64>;
12865ffd83dbSDimitry Andric
12875ffd83dbSDimitry Andric// Section 8.5.7 - LDZ (Leading Zero Count)
1288e8d8bef9SDimitry Andricdef ctlz_pat : PatFrags<(ops node:$src),
1289e8d8bef9SDimitry Andric                        [(ctlz node:$src),
1290e8d8bef9SDimitry Andric                         (ctlz_zero_undef node:$src)]>;
1291e8d8bef9SDimitry Andricdefm LDZ : RRI1m<"ldz", 0x67, I64, i64, ctlz_pat>;
12925ffd83dbSDimitry Andric
12935ffd83dbSDimitry Andric// Section 8.5.8 - PCNT (Population Count)
12945ffd83dbSDimitry Andricdefm PCNT : RRI1m<"pcnt", 0x38, I64, i64, ctpop>;
12955ffd83dbSDimitry Andric
12965ffd83dbSDimitry Andric// Section 8.5.9 - BRV (Bit Reverse)
12975ffd83dbSDimitry Andricdefm BRV : RRI1m<"brv", 0x39, I64, i64, bitreverse>;
12985ffd83dbSDimitry Andric
12995ffd83dbSDimitry Andric// Section 8.5.10 - BSWP (Byte Swap)
13005ffd83dbSDimitry Andricdefm BSWP : RRSWPm<"bswp", 0x2B, I64, i64>;
13015ffd83dbSDimitry Andric
1302e8d8bef9SDimitry Andricdef : Pat<(i64 (bswap i64:$src)),
1303e8d8bef9SDimitry Andric          (BSWPri $src, 0)>;
1304e8d8bef9SDimitry Andricdef : Pat<(i64 (bswap (i64 mimm:$src))),
1305e8d8bef9SDimitry Andric          (BSWPmi (MIMM $src), 0)>;
1306e8d8bef9SDimitry Andricdef : Pat<(i32 (bswap i32:$src)),
1307e8d8bef9SDimitry Andric          (EXTRACT_SUBREG
1308e8d8bef9SDimitry Andric              (BSWPri (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $src, sub_i32), 1),
1309e8d8bef9SDimitry Andric              sub_i32)>;
1310e8d8bef9SDimitry Andricdef : Pat<(i32 (bswap (i32 mimm:$src))),
1311e8d8bef9SDimitry Andric          (EXTRACT_SUBREG (BSWPmi (MIMM $src), 1), sub_i32)>;
1312e8d8bef9SDimitry Andric
13135ffd83dbSDimitry Andric// Section 8.5.11 - CMOV (Conditional Move)
1314bdd1243dSDimitry Andriclet cw = 0, cw2 = 0 in
1315bdd1243dSDimitry Andricdefm CMOVL : RRCMOVm<"cmov.l.${cfw}", 0x3B, I64, i64, cmov>;
1316bdd1243dSDimitry Andriclet cw = 1, cw2 = 0 in
1317bdd1243dSDimitry Andricdefm CMOVW : RRCMOVm<"cmov.w.${cfw}", 0x3B, I32, i32, cmov>;
1318bdd1243dSDimitry Andriclet cw = 0, cw2 = 1 in
1319bdd1243dSDimitry Andricdefm CMOVD : RRCMOVm<"cmov.d.${cfw}", 0x3B, I64, f64, cmov, simm7fp>;
1320bdd1243dSDimitry Andriclet cw = 1, cw2 = 1 in
1321bdd1243dSDimitry Andricdefm CMOVS : RRCMOVm<"cmov.s.${cfw}", 0x3B, F32, f32, cmov, simm7fp>;
13225ffd83dbSDimitry Andricdef : MnemonicAlias<"cmov.l", "cmov.l.at">;
13235ffd83dbSDimitry Andricdef : MnemonicAlias<"cmov.w", "cmov.w.at">;
13245ffd83dbSDimitry Andricdef : MnemonicAlias<"cmov.d", "cmov.d.at">;
13255ffd83dbSDimitry Andricdef : MnemonicAlias<"cmov.s", "cmov.s.at">;
13265ffd83dbSDimitry Andric
13275ffd83dbSDimitry Andric//-----------------------------------------------------------------------------
13285ffd83dbSDimitry Andric// Section 8.6 - Shift Operation Instructions
13295ffd83dbSDimitry Andric//-----------------------------------------------------------------------------
13305ffd83dbSDimitry Andric
13315ffd83dbSDimitry Andric// Section 8.6.1 - SLL (Shift Left Logical)
13325ffd83dbSDimitry Andricdefm SLL : RRIm<"sll", 0x65, I64, i64, shl>;
13335ffd83dbSDimitry Andric
13345ffd83dbSDimitry Andric// Section 8.6.2 - SLD (Shift Left Double)
1335349cc55cSDimitry Andricdefm SLD : RRILDm<"sld", 0x64, I64>;
13365ffd83dbSDimitry Andric
13375ffd83dbSDimitry Andric// Section 8.6.3 - SRL (Shift Right Logical)
13385ffd83dbSDimitry Andricdefm SRL : RRIm<"srl", 0x75, I64, i64, srl>;
13395ffd83dbSDimitry Andric
13405ffd83dbSDimitry Andric// Section 8.6.4 - SRD (Shift Right Double)
1341349cc55cSDimitry Andricdefm SRD : RRIRDm<"srd", 0x74, I64>;
13425ffd83dbSDimitry Andric
13435ffd83dbSDimitry Andric// Section 8.6.5 - SLA (Shift Left Arithmetic)
13445ffd83dbSDimitry Andricdefm SLAWSX : RRIm<"sla.w.sx", 0x66, I32, i32, shl>;
13455ffd83dbSDimitry Andriclet cx = 1 in defm SLAWZX : RRIm<"sla.w.zx", 0x66, I32, i32>;
13465ffd83dbSDimitry Andric
13475ffd83dbSDimitry Andric// Section 8.6.6 - SLAX (Shift Left Arithmetic)
13485ffd83dbSDimitry Andricdefm SLAL : RRIm<"sla.l", 0x57, I64, i64>;
13495ffd83dbSDimitry Andric
13505ffd83dbSDimitry Andric// Section 8.6.7 - SRA (Shift Right Arithmetic)
13515ffd83dbSDimitry Andricdefm SRAWSX : RRIm<"sra.w.sx", 0x76, I32, i32, sra>;
13525ffd83dbSDimitry Andriclet cx = 1 in defm SRAWZX : RRIm<"sra.w.zx", 0x76, I32, i32>;
13535ffd83dbSDimitry Andric
13545ffd83dbSDimitry Andric// Section 8.6.8 - SRAX (Shift Right Arithmetic)
13555ffd83dbSDimitry Andricdefm SRAL : RRIm<"sra.l", 0x77, I64, i64, sra>;
13565ffd83dbSDimitry Andric
13575ffd83dbSDimitry Andricdef : Pat<(i32 (srl i32:$src, (i32 simm7:$val))),
13585ffd83dbSDimitry Andric          (EXTRACT_SUBREG (SRLri (ANDrm (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
13595ffd83dbSDimitry Andric            $src, sub_i32), !add(32, 64)), imm:$val), sub_i32)>;
13605ffd83dbSDimitry Andricdef : Pat<(i32 (srl i32:$src, i32:$val)),
13615ffd83dbSDimitry Andric          (EXTRACT_SUBREG (SRLrr (ANDrm (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
13625ffd83dbSDimitry Andric            $src, sub_i32), !add(32, 64)), $val), sub_i32)>;
13635ffd83dbSDimitry Andric
13645ffd83dbSDimitry Andric//-----------------------------------------------------------------------------
13655ffd83dbSDimitry Andric// Section 8.7 - Floating-point Arithmetic Instructions
13665ffd83dbSDimitry Andric//-----------------------------------------------------------------------------
13675ffd83dbSDimitry Andric
13685ffd83dbSDimitry Andric// Section 8.7.1 - FAD (Floating Add)
13695ffd83dbSDimitry Andricdefm FADDD : RRFm<"fadd.d", 0x4C, I64, f64, fadd>;
1370480093f4SDimitry Andriclet cx = 1 in
13715ffd83dbSDimitry Andricdefm FADDS : RRFm<"fadd.s", 0x4C, F32, f32, fadd, simm7fp, mimmfp32>;
1372480093f4SDimitry Andric
13735ffd83dbSDimitry Andric// Section 8.7.2 - FSB (Floating Subtract)
13745ffd83dbSDimitry Andricdefm FSUBD : RRFm<"fsub.d", 0x5C, I64, f64, fsub>;
13755ffd83dbSDimitry Andriclet cx = 1 in
13765ffd83dbSDimitry Andricdefm FSUBS : RRFm<"fsub.s", 0x5C, F32, f32, fsub, simm7fp, mimmfp32>;
1377480093f4SDimitry Andric
13785ffd83dbSDimitry Andric// Section 8.7.3 - FMP (Floating Multiply)
13795ffd83dbSDimitry Andricdefm FMULD : RRFm<"fmul.d", 0x4D, I64, f64, fmul>;
13805ffd83dbSDimitry Andriclet cx = 1 in
13815ffd83dbSDimitry Andricdefm FMULS : RRFm<"fmul.s", 0x4D, F32, f32, fmul, simm7fp, mimmfp32>;
1382480093f4SDimitry Andric
13835ffd83dbSDimitry Andric// Section 8.7.4 - FDV (Floating Divide)
13845ffd83dbSDimitry Andricdefm FDIVD : RRFm<"fdiv.d", 0x5D, I64, f64, fdiv>;
13855ffd83dbSDimitry Andriclet cx = 1 in
13865ffd83dbSDimitry Andricdefm FDIVS : RRFm<"fdiv.s", 0x5D, F32, f32, fdiv, simm7fp, mimmfp32>;
1387480093f4SDimitry Andric
13885ffd83dbSDimitry Andric// Section 8.7.5 - FCP (Floating Compare)
1389bdd1243dSDimitry Andricdefm FCMPD : RRFm<"fcmp.d", 0x7E, I64, f64, cmpf>;
13905ffd83dbSDimitry Andriclet cx = 1 in
1391bdd1243dSDimitry Andricdefm FCMPS : RRFm<"fcmp.s", 0x7E, F32, f32, cmpf, simm7fp, mimmfp32>;
13925ffd83dbSDimitry Andric
13935ffd83dbSDimitry Andric// Section 8.7.6 - CMS (Compare and Select Maximum/Minimum Single)
13945ffd83dbSDimitry Andric// cx: double/float, cw: max/min
13955ffd83dbSDimitry Andriclet cw = 0, cx = 0 in
13965ffd83dbSDimitry Andricdefm FMAXD : RRFm<"fmax.d", 0x3E, I64, f64, fmaxnum>;
13975ffd83dbSDimitry Andriclet cw = 0, cx = 1 in
13985ffd83dbSDimitry Andricdefm FMAXS : RRFm<"fmax.s", 0x3E, F32, f32, fmaxnum, simm7fp, mimmfp32>;
13995ffd83dbSDimitry Andriclet cw = 1, cx = 0 in
14005ffd83dbSDimitry Andricdefm FMIND : RRFm<"fmin.d", 0x3E, I64, f64, fminnum>;
14015ffd83dbSDimitry Andriclet cw = 1, cx = 1 in
14025ffd83dbSDimitry Andricdefm FMINS : RRFm<"fmin.s", 0x3E, F32, f32, fminnum, simm7fp, mimmfp32>;
14035ffd83dbSDimitry Andric
14045ffd83dbSDimitry Andric// Section 8.7.7 - FAQ (Floating Add Quadruple)
1405e8d8bef9SDimitry Andricdefm FADDQ : RRFm<"fadd.q", 0x6C, F128, f128, fadd>;
14065ffd83dbSDimitry Andric
14075ffd83dbSDimitry Andric// Section 8.7.8 - FSQ (Floating Subtract Quadruple)
1408e8d8bef9SDimitry Andricdefm FSUBQ : RRFm<"fsub.q", 0x7C, F128, f128, fsub>;
14095ffd83dbSDimitry Andric
14105ffd83dbSDimitry Andric// Section 8.7.9 - FMQ (Floating Subtract Quadruple)
1411e8d8bef9SDimitry Andricdefm FMULQ : RRFm<"fmul.q", 0x6D, F128, f128, fmul>;
14125ffd83dbSDimitry Andric
14135ffd83dbSDimitry Andric// Section 8.7.10 - FCQ (Floating Compare Quadruple)
1414bdd1243dSDimitry Andricdefm FCMPQ : RRNCbm<"fcmp.q", 0x7D, I64, f64, F128, f128, cmpq, simm7fp,
14155ffd83dbSDimitry Andric                    mimmfp>;
14165ffd83dbSDimitry Andric
14175ffd83dbSDimitry Andric// Section 8.7.11 - FIX (Convert to Fixed Point)
14185ffd83dbSDimitry Andric// cx: double/float, cw: sx/zx, sz{0-3} = round
14195ffd83dbSDimitry Andriclet cx = 0, cw = 0 /* sign extend */ in
1420349cc55cSDimitry Andricdefm CVTWDSX : CVTRDm<"cvt.w.d.sx", 0x4E, I32, I64>;
14215ffd83dbSDimitry Andriclet cx = 0, cw = 1 /* zero extend */ in
1422349cc55cSDimitry Andricdefm CVTWDZX : CVTRDm<"cvt.w.d.zx", 0x4E, I32, I64>;
14235ffd83dbSDimitry Andriclet cx = 1, cw = 0 /* sign extend */ in
1424349cc55cSDimitry Andricdefm CVTWSSX : CVTRDm<"cvt.w.s.sx", 0x4E, I32, F32>;
14255ffd83dbSDimitry Andriclet cx = 1, cw = 1 /* zero extend */ in
1426349cc55cSDimitry Andricdefm CVTWSZX : CVTRDm<"cvt.w.s.zx", 0x4E, I32, F32>;
14275ffd83dbSDimitry Andric
14285ffd83dbSDimitry Andric// Section 8.7.12 - FIXX (Convert to Fixed Point)
1429349cc55cSDimitry Andricdefm CVTLD : CVTRDm<"cvt.l.d", 0x4F, I64, I64>;
14305ffd83dbSDimitry Andric
14315ffd83dbSDimitry Andric// Section 8.7.13 - FLT (Convert to Floating Point)
14325ffd83dbSDimitry Andricdefm CVTDW : CVTm<"cvt.d.w", 0x5E, I64, f64, I32, i32, sint_to_fp>;
14335ffd83dbSDimitry Andriclet cx = 1 in
14345ffd83dbSDimitry Andricdefm CVTSW : CVTm<"cvt.s.w", 0x5E, F32, f32, I32, i32, sint_to_fp>;
14355ffd83dbSDimitry Andric
14365ffd83dbSDimitry Andric// Section 8.7.14 - FLTX (Convert to Floating Point)
14375ffd83dbSDimitry Andricdefm CVTDL : CVTm<"cvt.d.l", 0x5F, I64, f64, I64, i64, sint_to_fp>;
14385ffd83dbSDimitry Andric
14395ffd83dbSDimitry Andric// Section 8.7.15 - CVS (Convert to Single-format)
14405ffd83dbSDimitry Andricdefm CVTSD : CVTm<"cvt.s.d", 0x1F, F32, f32, I64, f64, fpround>;
14415ffd83dbSDimitry Andriclet cx = 1 in
1442e8d8bef9SDimitry Andricdefm CVTSQ : CVTm<"cvt.s.q", 0x1F, F32, f32, F128, f128, fpround>;
14435ffd83dbSDimitry Andric
14445ffd83dbSDimitry Andric// Section 8.7.16 - CVD (Convert to Double-format)
14455ffd83dbSDimitry Andricdefm CVTDS : CVTm<"cvt.d.s", 0x0F, I64, f64, F32, f32, fpextend>;
14465ffd83dbSDimitry Andriclet cx = 1 in
1447e8d8bef9SDimitry Andricdefm CVTDQ : CVTm<"cvt.d.q", 0x0F, I64, f64, F128, f128, fpround>;
14485ffd83dbSDimitry Andric
14495ffd83dbSDimitry Andric// Section 8.7.17 - CVQ (Convert to Single-format)
1450e8d8bef9SDimitry Andricdefm CVTQD : CVTm<"cvt.q.d", 0x2D, F128, f128, I64, f64, fpextend>;
14515ffd83dbSDimitry Andriclet cx = 1 in
1452e8d8bef9SDimitry Andricdefm CVTQS : CVTm<"cvt.q.s", 0x2D, F128, f128, F32, f32, fpextend>;
14535ffd83dbSDimitry Andric
14545ffd83dbSDimitry Andric//-----------------------------------------------------------------------------
14555ffd83dbSDimitry Andric// Section 8.8 - Branch instructions
14565ffd83dbSDimitry Andric//-----------------------------------------------------------------------------
14575ffd83dbSDimitry Andric
14585ffd83dbSDimitry Andric// Section 8.8.1 - BC (Branch on Codition)
14595ffd83dbSDimitry Andricdefm BCFL : BCm<"b${cond}.l", "b.l", "baf.l", 0x19, I64, simm7>;
14605ffd83dbSDimitry Andric
14615ffd83dbSDimitry Andric// Indirect branch aliases
14625ffd83dbSDimitry Andricdef : Pat<(brind I64:$reg), (BCFLari_t $reg, 0)>;
14635ffd83dbSDimitry Andricdef : Pat<(brind tblockaddress:$imm), (BCFLazi_t 0, $imm)>;
14645ffd83dbSDimitry Andric
14655ffd83dbSDimitry Andric// Return instruction is a special case of jump.
146606c3fb27SDimitry Andriclet Uses = [SX10], bpf = 3 /* TAKEN */, cond = 15 /* AT */, cy = 0, sy = 0,
14675ffd83dbSDimitry Andric    sz = 10 /* SX10 */, imm32 = 0, isReturn = 1, isTerminator = 1,
14685ffd83dbSDimitry Andric    isBarrier = 1, isCodeGenOnly = 1, hasSideEffects = 0 in
146906c3fb27SDimitry Andricdef RET : CF<0x19, (outs), (ins), "b.l.t (, %s10)", [(retglue)]>;
14705ffd83dbSDimitry Andric
14715ffd83dbSDimitry Andric// Section 8.8.2 - BCS (Branch on Condition Single)
14725ffd83dbSDimitry Andricdefm BCFW : BCm<"b${cond}.w", "b.w", "baf.w", 0x1B, I32, simm7>;
14735ffd83dbSDimitry Andric
14745ffd83dbSDimitry Andric// Section 8.8.3 - BCF (Branch on Condition Floating Point)
14755ffd83dbSDimitry Andricdefm BCFD : BCm<"b${cond}.d", "b.d", "baf.d", 0x1C, I64, simm7fp>;
14765ffd83dbSDimitry Andriclet cx = 1 in
14775ffd83dbSDimitry Andricdefm BCFS : BCm<"b${cond}.s", "b.s", "baf.s", 0x1C, F32, simm7fp>;
14785ffd83dbSDimitry Andric
14795ffd83dbSDimitry Andric// Section 8.8.4 - BCR (Branch on Condition Relative)
14805ffd83dbSDimitry Andriclet cx = 0, cx2 = 0 in
148106c3fb27SDimitry Andricdefm BRCFL : BCRm<"br${cond}.l", "br.l", "braf.l", 0x18, I64, simm7, zero>;
14825ffd83dbSDimitry Andriclet cx = 1, cx2 = 0 in
148306c3fb27SDimitry Andricdefm BRCFW : BCRm<"br${cond}.w", "br.w", "braf.w", 0x18, I32, simm7, zero>;
14845ffd83dbSDimitry Andriclet cx = 0, cx2 = 1 in
148506c3fb27SDimitry Andricdefm BRCFD : BCRm<"br${cond}.d", "br.d", "braf.d", 0x18, I64, simm7fp, zerofp>;
14865ffd83dbSDimitry Andriclet cx = 1, cx2 = 1 in
148706c3fb27SDimitry Andricdefm BRCFS : BCRm<"br${cond}.s", "br.s", "braf.s", 0x18, F32, simm7fp, zerofp>;
14885ffd83dbSDimitry Andric
14895ffd83dbSDimitry Andric// Section 8.8.5 - BSIC (Branch and Save IC)
14905ffd83dbSDimitry Andriclet isCall = 1, hasSideEffects = 0, DecoderMethod = "DecodeCall" in
14915ffd83dbSDimitry Andricdefm BSIC : RMm<"bsic", 0x08, I64>;
14925ffd83dbSDimitry Andric
14935ffd83dbSDimitry Andric// Call instruction is a special case of BSIC.
14945ffd83dbSDimitry Andriclet Defs = [SX10], sx = 10 /* SX10 */, cy = 0, sy = 0, imm32 = 0,
14955ffd83dbSDimitry Andric    isCall = 1, isCodeGenOnly = 1, hasSideEffects = 0 in
14965ffd83dbSDimitry Andricdef CALLr : RM<0x08, (outs), (ins I64:$sz, variable_ops),
14975ffd83dbSDimitry Andric               "bsic %s10, (, $sz)", [(call i64:$sz)]>;
14985ffd83dbSDimitry Andric
14995ffd83dbSDimitry Andric//-----------------------------------------------------------------------------
15005ffd83dbSDimitry Andric// Section 8.19 - Control Instructions
15015ffd83dbSDimitry Andric//-----------------------------------------------------------------------------
15025ffd83dbSDimitry Andric
15035ffd83dbSDimitry Andric// Section 8.19.1 - SIC (Save Instruction Counter)
15045ffd83dbSDimitry Andriclet cy = 0, sy = 0, cz = 0, sz = 0, hasSideEffects = 1, Uses = [IC] in
15055ffd83dbSDimitry Andricdef SIC : RR<0x28, (outs I32:$sx), (ins), "sic $sx">;
15065ffd83dbSDimitry Andric
15075ffd83dbSDimitry Andric// Section 8.19.2 - LPM (Load Program Mode Flags)
15085ffd83dbSDimitry Andriclet sx = 0, cz = 0, sz = 0, hasSideEffects = 1, Defs = [PSW] in
15095ffd83dbSDimitry Andricdef LPM : RR<0x3a, (outs), (ins I64:$sy), "lpm $sy">;
15105ffd83dbSDimitry Andric
15115ffd83dbSDimitry Andric// Section 8.19.3 - SPM (Save Program Mode Flags)
15125ffd83dbSDimitry Andriclet cy = 0, sy = 0, cz = 0, sz = 0, hasSideEffects = 1, Uses = [PSW] in
15135ffd83dbSDimitry Andricdef SPM : RR<0x2a, (outs I64:$sx), (ins), "spm $sx">;
15145ffd83dbSDimitry Andric
15155ffd83dbSDimitry Andric// Section 8.19.4 - LFR (Load Flag Register)
15165ffd83dbSDimitry Andriclet sx = 0, cz = 0, sz = 0, hasSideEffects = 1, Defs = [PSW] in {
15175ffd83dbSDimitry Andric  def LFRr : RR<0x69, (outs), (ins I64:$sy), "lfr $sy">;
15185ffd83dbSDimitry Andric  let cy = 0 in def LFRi : RR<0x69, (outs), (ins uimm6:$sy), "lfr $sy">;
1519480093f4SDimitry Andric}
1520480093f4SDimitry Andric
15215ffd83dbSDimitry Andric// Section 8.19.5 - SFR (Save Flag Register)
15225ffd83dbSDimitry Andriclet cy = 0, sy = 0, cz = 0, sz = 0, hasSideEffects = 1, Uses = [PSW] in
15235ffd83dbSDimitry Andricdef SFR : RR<0x29, (outs I64:$sx), (ins), "sfr $sx">;
15245ffd83dbSDimitry Andric
15255ffd83dbSDimitry Andric// Section 8.19.6 - SMIR (Save Miscellaneous Register)
15265ffd83dbSDimitry Andriclet cy = 0, cz = 0, sz = 0, hasSideEffects = 1 in {
15275ffd83dbSDimitry Andric  def SMIR : RR<0x22, (outs I64:$sx), (ins MISC:$sy), "smir $sx, $sy">;
1528480093f4SDimitry Andric}
1529480093f4SDimitry Andric
15305ffd83dbSDimitry Andric// Section 8.19.7 - NOP (No Operation)
15315ffd83dbSDimitry Andriclet sx = 0, cy = 0, sy = 0, cz = 0, sz = 0, hasSideEffects = 0 in
15325ffd83dbSDimitry Andricdef NOP : RR<0x79, (outs), (ins), "nop">;
15335ffd83dbSDimitry Andric
15345ffd83dbSDimitry Andric// Section 8.19.8 - MONC (Monitor Call)
15355ffd83dbSDimitry Andriclet sx = 0, cy = 0, sy = 0, cz = 0, sz = 0, hasSideEffects = 1 in {
15365ffd83dbSDimitry Andric  def MONC : RR<0x3F, (outs), (ins), "monc">;
15375ffd83dbSDimitry Andric  let cx = 1, isTrap = 1 in def MONCHDB : RR<0x3F, (outs), (ins), "monc.hdb">;
1538480093f4SDimitry Andric}
1539480093f4SDimitry Andric
15405ffd83dbSDimitry Andric// Section 8.19.9 - LCR (Load Communication Register)
15415ffd83dbSDimitry Andricdefm LCR : LOADCRm<"lcr", 0x40, I64>;
1542480093f4SDimitry Andric
15435ffd83dbSDimitry Andric// Section 8.19.10 - SCR (Save Communication Register)
15445ffd83dbSDimitry Andricdefm SCR : STORECRm<"scr", 0x50, I64>;
1545480093f4SDimitry Andric
15465ffd83dbSDimitry Andric// Section 8.19.11 - TSCR (Test & Set Communication Register)
154781ad6265SDimitry Andricdefm TSCR : TSCRm<"tscr", 0x41, I64>;
15485ffd83dbSDimitry Andric
15495ffd83dbSDimitry Andric// Section 8.19.12 - FIDCR (Fetch & Increment/Decrement CR)
15505ffd83dbSDimitry Andricdefm FIDCR : FIDCRm<"fidcr", 0x51, I64>;
15515ffd83dbSDimitry Andric
15525ffd83dbSDimitry Andric//-----------------------------------------------------------------------------
15535ffd83dbSDimitry Andric// Section 8.20 - Host Memory Access Instructions
15545ffd83dbSDimitry Andric//-----------------------------------------------------------------------------
15555ffd83dbSDimitry Andric
15565ffd83dbSDimitry Andric// Section 8.20.1 - LHM (Load Host Memory)
15575ffd83dbSDimitry Andriclet ry = 3, DecoderMethod = "DecodeLoadASI64" in
15585ffd83dbSDimitry Andricdefm LHML : LHMm<"lhm.l", 0x21, I64>;
15595ffd83dbSDimitry Andriclet ry = 2, DecoderMethod = "DecodeLoadASI64" in
15605ffd83dbSDimitry Andricdefm LHMW : LHMm<"lhm.w", 0x21, I64>;
15615ffd83dbSDimitry Andriclet ry = 1, DecoderMethod = "DecodeLoadASI64" in
15625ffd83dbSDimitry Andricdefm LHMH : LHMm<"lhm.h", 0x21, I64>;
15635ffd83dbSDimitry Andriclet ry = 0, DecoderMethod = "DecodeLoadASI64" in
15645ffd83dbSDimitry Andricdefm LHMB : LHMm<"lhm.b", 0x21, I64>;
15655ffd83dbSDimitry Andric
15665ffd83dbSDimitry Andric// Section 8.20.2 - SHM (Store Host Memory)
15675ffd83dbSDimitry Andriclet ry = 3, DecoderMethod = "DecodeStoreASI64" in
15685ffd83dbSDimitry Andricdefm SHML : SHMm<"shm.l", 0x31, I64>;
15695ffd83dbSDimitry Andriclet ry = 2, DecoderMethod = "DecodeStoreASI64" in
15705ffd83dbSDimitry Andricdefm SHMW : SHMm<"shm.w", 0x31, I64>;
15715ffd83dbSDimitry Andriclet ry = 1, DecoderMethod = "DecodeStoreASI64" in
15725ffd83dbSDimitry Andricdefm SHMH : SHMm<"shm.h", 0x31, I64>;
15735ffd83dbSDimitry Andriclet ry = 0, DecoderMethod = "DecodeStoreASI64" in
15745ffd83dbSDimitry Andricdefm SHMB : SHMm<"shm.b", 0x31, I64>;
15755ffd83dbSDimitry Andric
15765ffd83dbSDimitry Andric//===----------------------------------------------------------------------===//
15775ffd83dbSDimitry Andric// Instructions for CodeGenOnly
15785ffd83dbSDimitry Andric//===----------------------------------------------------------------------===//
15795ffd83dbSDimitry Andric
15805ffd83dbSDimitry Andric//===----------------------------------------------------------------------===//
15815ffd83dbSDimitry Andric// Pattern Matchings
15825ffd83dbSDimitry Andric//===----------------------------------------------------------------------===//
15835ffd83dbSDimitry Andric
1584e8d8bef9SDimitry Andric// Basic cast between registers.  This is often used in ISel patterns, so make
1585e8d8bef9SDimitry Andric// them as OutPatFrag.
1586e8d8bef9SDimitry Andricdef i2l : OutPatFrag<(ops node:$exp),
1587e8d8bef9SDimitry Andric                     (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $exp, sub_i32)>;
1588e8d8bef9SDimitry Andricdef l2i : OutPatFrag<(ops node:$exp),
1589e8d8bef9SDimitry Andric                     (EXTRACT_SUBREG $exp, sub_i32)>;
1590e8d8bef9SDimitry Andricdef f2l : OutPatFrag<(ops node:$exp),
1591e8d8bef9SDimitry Andric                     (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $exp, sub_f32)>;
1592e8d8bef9SDimitry Andricdef l2f : OutPatFrag<(ops node:$exp),
1593e8d8bef9SDimitry Andric                     (EXTRACT_SUBREG $exp, sub_f32)>;
1594e8d8bef9SDimitry Andric
159504eeddc0SDimitry Andric// Zero out subregisters.
159604eeddc0SDimitry Andricdef zero_i32 : OutPatFrag<(ops node:$expr),
159704eeddc0SDimitry Andric                          (ANDrm $expr, 32)>;
159804eeddc0SDimitry Andricdef zero_f32 : OutPatFrag<(ops node:$expr),
159904eeddc0SDimitry Andric                          (ANDrm $expr, !add(32, 64))>;
160004eeddc0SDimitry Andric
16015ffd83dbSDimitry Andric// Small immediates.
1602bdd1243dSDimitry Andricdef : Pat<(i32 simm7:$val), (l2i (ORim (LO7 $val), 0))>;
16035ffd83dbSDimitry Andricdef : Pat<(i64 simm7:$val), (ORim (LO7 $val), 0)>;
16045ffd83dbSDimitry Andric// Medium immediates.
1605bdd1243dSDimitry Andricdef : Pat<(i32 simm32:$val), (l2i (LEAzii 0, 0, (LO32 $val)))>;
16065ffd83dbSDimitry Andricdef : Pat<(i64 simm32:$val), (LEAzii 0, 0, (LO32 $val))>;
1607bdd1243dSDimitry Andricdef : Pat<(i64 uimm32:$val), (zero_f32 (LEAzii 0, 0, (LO32 $val)))>;
16085ffd83dbSDimitry Andric// Arbitrary immediates.
16095ffd83dbSDimitry Andricdef : Pat<(i64 lozero:$val),
16105ffd83dbSDimitry Andric          (LEASLzii 0, 0, (HI32 imm:$val))>;
16115ffd83dbSDimitry Andricdef : Pat<(i64 lomsbzero:$val),
16125ffd83dbSDimitry Andric          (LEASLrii (LEAzii 0, 0, (LO32 imm:$val)), 0, (HI32 imm:$val))>;
16135ffd83dbSDimitry Andricdef : Pat<(i64 imm:$val),
16145ffd83dbSDimitry Andric          (LEASLrii (ANDrm (LEAzii 0, 0, (LO32 imm:$val)), !add(32, 64)), 0,
16155ffd83dbSDimitry Andric                    (HI32 imm:$val))>;
16165ffd83dbSDimitry Andric
1617e8d8bef9SDimitry Andric// LEA patterns
1618e8d8bef9SDimitry Andricdef lea_add : PatFrags<(ops node:$base, node:$idx, node:$disp),
1619e8d8bef9SDimitry Andric                       [(add (add node:$base, node:$idx), node:$disp),
1620e8d8bef9SDimitry Andric                        (add (add node:$base, node:$disp), node:$idx),
1621e8d8bef9SDimitry Andric                        (add node:$base, (add $idx, $disp))]>;
1622e8d8bef9SDimitry Andricdef : Pat<(lea_add I64:$base, simm7:$idx, simm32:$disp),
1623e8d8bef9SDimitry Andric          (LEArii $base, (LO7 $idx), (LO32 $disp))>;
1624e8d8bef9SDimitry Andricdef : Pat<(lea_add I64:$base, I64:$idx, simm32:$disp),
1625e8d8bef9SDimitry Andric          (LEArri $base, $idx, (LO32 $disp))>;
1626e8d8bef9SDimitry Andricdef : Pat<(lea_add I64:$base, simm7:$idx, lozero:$disp),
1627e8d8bef9SDimitry Andric          (LEASLrii $base, (LO7 $idx), (HI32 $disp))>;
1628e8d8bef9SDimitry Andricdef : Pat<(lea_add I64:$base, I64:$idx, lozero:$disp),
1629e8d8bef9SDimitry Andric          (LEASLrri $base, $idx, (HI32 $disp))>;
1630e8d8bef9SDimitry Andric
1631e8d8bef9SDimitry Andric// Address calculation patterns and optimizations
1632e8d8bef9SDimitry Andric//
1633e8d8bef9SDimitry Andric// Generate following instructions:
1634e8d8bef9SDimitry Andric//   1. LEA %reg, label@LO32
1635e8d8bef9SDimitry Andric//      AND %reg, %reg, (32)0
1636e8d8bef9SDimitry Andric//   2. LEASL %reg, label@HI32
1637e8d8bef9SDimitry Andric//   3. (LEA %reg, label@LO32)
1638e8d8bef9SDimitry Andric//      (AND %reg, %reg, (32)0)
1639e8d8bef9SDimitry Andric//      LEASL %reg, label@HI32(, %reg)
1640e8d8bef9SDimitry Andric//   4. (LEA %reg, label@LO32)
1641e8d8bef9SDimitry Andric//      (AND %reg, %reg, (32)0)
1642e8d8bef9SDimitry Andric//      LEASL %reg, label@HI32(%reg, %got)
1643e8d8bef9SDimitry Andric//
1644e8d8bef9SDimitry Andricdef velo_only : OutPatFrag<(ops node:$lo),
1645e8d8bef9SDimitry Andric                           (ANDrm (LEAzii 0, 0, $lo), !add(32, 64))>;
1646e8d8bef9SDimitry Andricdef vehi_only : OutPatFrag<(ops node:$hi),
1647e8d8bef9SDimitry Andric                           (LEASLzii 0, 0, $hi)>;
1648e8d8bef9SDimitry Andricdef vehi_lo : OutPatFrag<(ops node:$hi, node:$lo),
1649e8d8bef9SDimitry Andric                         (LEASLrii $lo, 0, $hi)>;
1650e8d8bef9SDimitry Andricdef vehi_lo_imm : OutPatFrag<(ops node:$hi, node:$lo, node:$idx),
1651e8d8bef9SDimitry Andric                             (LEASLrii $lo, $idx, $hi)>;
1652e8d8bef9SDimitry Andricdef vehi_baselo : OutPatFrag<(ops node:$base, node:$hi, node:$lo),
1653e8d8bef9SDimitry Andric                             (LEASLrri $base, $lo, $hi)>;
1654e8d8bef9SDimitry Andricforeach type = [ "tblockaddress", "tconstpool", "texternalsym", "tglobaladdr",
1655e8d8bef9SDimitry Andric                 "tglobaltlsaddr", "tjumptable" ] in {
1656e8d8bef9SDimitry Andric  def : Pat<(VElo !cast<SDNode>(type):$lo), (velo_only $lo)>;
1657e8d8bef9SDimitry Andric  def : Pat<(VEhi !cast<SDNode>(type):$hi), (vehi_only $hi)>;
1658e8d8bef9SDimitry Andric  def : Pat<(add (VEhi !cast<SDNode>(type):$hi), I64:$lo), (vehi_lo $hi, $lo)>;
1659e8d8bef9SDimitry Andric  def : Pat<(add (add (VEhi !cast<SDNode>(type):$hi), I64:$lo), simm7:$val),
1660e8d8bef9SDimitry Andric            (vehi_lo_imm $hi, $lo, (LO7 $val))>;
1661e8d8bef9SDimitry Andric  def : Pat<(add I64:$base, (add (VEhi !cast<SDNode>(type):$hi), I64:$lo)),
1662e8d8bef9SDimitry Andric            (vehi_baselo $base, $hi, $lo)>;
1663e8d8bef9SDimitry Andric}
1664e8d8bef9SDimitry Andric
16655ffd83dbSDimitry Andric// floating point
16665ffd83dbSDimitry Andricdef : Pat<(f32 fpimm:$val),
16675ffd83dbSDimitry Andric          (EXTRACT_SUBREG (LEASLzii 0, 0, (HIFP32 $val)), sub_f32)>;
16685ffd83dbSDimitry Andricdef : Pat<(f64 fplozero:$val),
16695ffd83dbSDimitry Andric          (LEASLzii 0, 0, (HIFP32 $val))>;
16705ffd83dbSDimitry Andricdef : Pat<(f64 fplomsbzero:$val),
16715ffd83dbSDimitry Andric          (LEASLrii (LEAzii 0, 0, (LOFP32 $val)), 0, (HIFP32 $val))>;
16725ffd83dbSDimitry Andricdef : Pat<(f64 fpimm:$val),
16735ffd83dbSDimitry Andric          (LEASLrii (ANDrm (LEAzii 0, 0, (LOFP32 $val)), !add(32, 64)), 0,
16745ffd83dbSDimitry Andric                    (HIFP32 $val))>;
16755ffd83dbSDimitry Andric
16765ffd83dbSDimitry Andric// The same integer registers are used for i32 and i64 values.
16775ffd83dbSDimitry Andric// When registers hold i32 values, the high bits are unused.
16785ffd83dbSDimitry Andric
16795ffd83dbSDimitry Andric// TODO Use standard expansion for shift-based lowering of sext_inreg
16805ffd83dbSDimitry Andric
16815ffd83dbSDimitry Andric// Cast to i1
16825ffd83dbSDimitry Andricdef : Pat<(sext_inreg I32:$src, i1),
16835ffd83dbSDimitry Andric          (SRAWSXri (SLAWSXri $src, 31), 31)>;
16845ffd83dbSDimitry Andricdef : Pat<(sext_inreg I64:$src, i1),
16855ffd83dbSDimitry Andric          (SRALri (SLLri $src, 63), 63)>;
16865ffd83dbSDimitry Andric
16875ffd83dbSDimitry Andric// Cast to i8
16885ffd83dbSDimitry Andricdef : Pat<(sext_inreg I32:$src, i8),
16895ffd83dbSDimitry Andric          (SRAWSXri (SLAWSXri $src, 24), 24)>;
16905ffd83dbSDimitry Andricdef : Pat<(sext_inreg I64:$src, i8),
16915ffd83dbSDimitry Andric          (SRALri (SLLri $src, 56), 56)>;
16925ffd83dbSDimitry Andricdef : Pat<(sext_inreg (i32 (trunc i64:$src)), i8),
16935ffd83dbSDimitry Andric          (EXTRACT_SUBREG (SRALri (SLLri $src, 56), 56), sub_i32)>;
1694e8d8bef9SDimitry Andricdef : Pat<(i32 (and (trunc i64:$src), 0xff)),
1695e8d8bef9SDimitry Andric          (EXTRACT_SUBREG (ANDrm $src, !add(56, 64)), sub_i32)>;
16965ffd83dbSDimitry Andric
16975ffd83dbSDimitry Andric// Cast to i16
16985ffd83dbSDimitry Andricdef : Pat<(sext_inreg I32:$src, i16),
16995ffd83dbSDimitry Andric          (SRAWSXri (SLAWSXri $src, 16), 16)>;
17005ffd83dbSDimitry Andricdef : Pat<(sext_inreg I64:$src, i16),
17015ffd83dbSDimitry Andric          (SRALri (SLLri $src, 48), 48)>;
17025ffd83dbSDimitry Andricdef : Pat<(sext_inreg (i32 (trunc i64:$src)), i16),
17035ffd83dbSDimitry Andric          (EXTRACT_SUBREG (SRALri (SLLri $src, 48), 48), sub_i32)>;
1704e8d8bef9SDimitry Andricdef : Pat<(i32 (and (trunc i64:$src), 0xffff)),
1705e8d8bef9SDimitry Andric          (EXTRACT_SUBREG (ANDrm $src, !add(48, 64)), sub_i32)>;
17065ffd83dbSDimitry Andric
17075ffd83dbSDimitry Andric// Cast to i32
1708bdd1243dSDimitry Andricdef : Pat<(i32 (trunc i64:$src)), (l2i (zero_f32 $src))>;
1709e8d8bef9SDimitry Andricdef : Pat<(i32 (fp_to_sint f32:$src)), (CVTWSSXr RD_RZ, $src)>;
1710e8d8bef9SDimitry Andricdef : Pat<(i32 (fp_to_sint f64:$src)), (CVTWDSXr RD_RZ, $src)>;
1711e8d8bef9SDimitry Andricdef : Pat<(i32 (fp_to_sint f128:$src)), (CVTWDSXr RD_RZ, (CVTDQr $src))>;
17125ffd83dbSDimitry Andric
17135ffd83dbSDimitry Andric// Cast to i64
1714bdd1243dSDimitry Andricdef : Pat<(sext_inreg i64:$src, i32), (i2l (ADDSWSXrm (l2i $src), 0))>;
1715bdd1243dSDimitry Andricdef : Pat<(i64 (sext i32:$src)), (i2l (ADDSWSXrm $src, 0))>;
1716bdd1243dSDimitry Andricdef : Pat<(i64 (zext i32:$src)), (i2l (ADDSWZXrm $src, 0))>;
1717bdd1243dSDimitry Andricdef : Pat<(i64 (anyext i32:$sy)), (i2l $sy)>;
1718e8d8bef9SDimitry Andricdef : Pat<(i64 (fp_to_sint f32:$src)), (CVTLDr RD_RZ, (CVTDSr $src))>;
1719e8d8bef9SDimitry Andricdef : Pat<(i64 (fp_to_sint f64:$src)), (CVTLDr RD_RZ, $src)>;
1720e8d8bef9SDimitry Andricdef : Pat<(i64 (fp_to_sint f128:$src)), (CVTLDr RD_RZ, (CVTDQr $src))>;
17215ffd83dbSDimitry Andric
17225ffd83dbSDimitry Andric// Cast to f32
1723e8d8bef9SDimitry Andricdef : Pat<(f32 (sint_to_fp i64:$src)), (CVTSDr (CVTDLr i64:$src))>;
1724e8d8bef9SDimitry Andric
1725e8d8bef9SDimitry Andric// Cast to f128
1726e8d8bef9SDimitry Andricdef : Pat<(f128 (sint_to_fp i32:$src)), (CVTQDr (CVTDWr $src))>;
1727e8d8bef9SDimitry Andricdef : Pat<(f128 (sint_to_fp i64:$src)), (CVTQDr (CVTDLr $src))>;
17285ffd83dbSDimitry Andric
17295ffd83dbSDimitry Andric
17305ffd83dbSDimitry Andric// extload, sextload and zextload stuff
17315ffd83dbSDimitry Andricmulticlass EXT64m<SDPatternOperator from,
1732fe6060f1SDimitry Andric                  RM torri,
1733fe6060f1SDimitry Andric                  RM torii,
1734fe6060f1SDimitry Andric                  RM tozri,
1735fe6060f1SDimitry Andric                  RM tozii> {
17365ffd83dbSDimitry Andric  def : Pat<(i64 (from ADDRrri:$addr)),
1737bdd1243dSDimitry Andric            (i2l (torri MEMrri:$addr))>;
17385ffd83dbSDimitry Andric  def : Pat<(i64 (from ADDRrii:$addr)),
1739bdd1243dSDimitry Andric            (i2l (torii MEMrii:$addr))>;
17405ffd83dbSDimitry Andric  def : Pat<(i64 (from ADDRzri:$addr)),
1741bdd1243dSDimitry Andric            (i2l (tozri MEMzri:$addr))>;
17425ffd83dbSDimitry Andric  def : Pat<(i64 (from ADDRzii:$addr)),
1743bdd1243dSDimitry Andric            (i2l (tozii MEMzii:$addr))>;
1744480093f4SDimitry Andric}
17455ffd83dbSDimitry Andricdefm : EXT64m<sextloadi8, LD1BSXrri, LD1BSXrii, LD1BSXzri, LD1BSXzii>;
17465ffd83dbSDimitry Andricdefm : EXT64m<zextloadi8, LD1BZXrri, LD1BZXrii, LD1BZXzri, LD1BZXzii>;
17475ffd83dbSDimitry Andricdefm : EXT64m<extloadi8, LD1BZXrri, LD1BZXrii, LD1BZXzri, LD1BZXzii>;
17485ffd83dbSDimitry Andricdefm : EXT64m<sextloadi16, LD2BSXrri, LD2BSXrii, LD2BSXzri, LD2BSXzii>;
17495ffd83dbSDimitry Andricdefm : EXT64m<zextloadi16, LD2BZXrri, LD2BZXrii, LD2BZXzri, LD2BZXzii>;
17505ffd83dbSDimitry Andricdefm : EXT64m<extloadi16, LD2BZXrri, LD2BZXrii, LD2BZXzri, LD2BZXzii>;
17515ffd83dbSDimitry Andricdefm : EXT64m<sextloadi32, LDLSXrri, LDLSXrii, LDLSXzri, LDLSXzii>;
17525ffd83dbSDimitry Andricdefm : EXT64m<zextloadi32, LDLZXrri, LDLZXrii, LDLZXzri, LDLZXzii>;
17535ffd83dbSDimitry Andricdefm : EXT64m<extloadi32, LDLSXrri, LDLSXrii, LDLSXzri, LDLSXzii>;
1754480093f4SDimitry Andric
17555ffd83dbSDimitry Andric// anyextload
17565ffd83dbSDimitry Andricmulticlass EXT32m<SDPatternOperator from,
1757fe6060f1SDimitry Andric                  RM torri,
1758fe6060f1SDimitry Andric                  RM torii,
1759fe6060f1SDimitry Andric                  RM tozri,
1760fe6060f1SDimitry Andric                  RM tozii> {
17615ffd83dbSDimitry Andric  def : Pat<(from ADDRrri:$addr), (torri MEMrri:$addr)>;
17625ffd83dbSDimitry Andric  def : Pat<(from ADDRrii:$addr), (torii MEMrii:$addr)>;
17635ffd83dbSDimitry Andric  def : Pat<(from ADDRzri:$addr), (tozri MEMzri:$addr)>;
17645ffd83dbSDimitry Andric  def : Pat<(from ADDRzii:$addr), (tozii MEMzii:$addr)>;
17655ffd83dbSDimitry Andric}
17665ffd83dbSDimitry Andricdefm : EXT32m<extloadi8, LD1BZXrri, LD1BZXrii, LD1BZXzri, LD1BZXzii>;
17675ffd83dbSDimitry Andricdefm : EXT32m<extloadi16, LD2BZXrri, LD2BZXrii, LD2BZXzri, LD2BZXzii>;
17685ffd83dbSDimitry Andric
17695ffd83dbSDimitry Andric// truncstore
17705ffd83dbSDimitry Andricmulticlass TRUNC64m<SDPatternOperator from,
1771fe6060f1SDimitry Andric                    RM torri,
1772fe6060f1SDimitry Andric                    RM torii,
1773fe6060f1SDimitry Andric                    RM tozri,
1774fe6060f1SDimitry Andric                    RM tozii> {
17755ffd83dbSDimitry Andric  def : Pat<(from i64:$src, ADDRrri:$addr),
1776bdd1243dSDimitry Andric            (torri MEMrri:$addr, (l2i $src))>;
17775ffd83dbSDimitry Andric  def : Pat<(from i64:$src, ADDRrii:$addr),
1778bdd1243dSDimitry Andric            (torii MEMrii:$addr, (l2i $src))>;
17795ffd83dbSDimitry Andric  def : Pat<(from i64:$src, ADDRzri:$addr),
1780bdd1243dSDimitry Andric            (tozri MEMzri:$addr, (l2i $src))>;
17815ffd83dbSDimitry Andric  def : Pat<(from i64:$src, ADDRzii:$addr),
1782bdd1243dSDimitry Andric            (tozii MEMzii:$addr, (l2i $src))>;
17835ffd83dbSDimitry Andric}
17845ffd83dbSDimitry Andricdefm : TRUNC64m<truncstorei8, ST1Brri, ST1Brii, ST1Bzri, ST1Bzii>;
17855ffd83dbSDimitry Andricdefm : TRUNC64m<truncstorei16, ST2Brri, ST2Brii, ST2Bzri, ST2Bzii>;
17865ffd83dbSDimitry Andricdefm : TRUNC64m<truncstorei32, STLrri, STLrii, STLzri, ST1Bzii>;
17875ffd83dbSDimitry Andric
1788*0fca6ea1SDimitry Andric// Atomic loads (FIXME: replace iAny with the correct integer VT:)
1789e8d8bef9SDimitry Andricmulticlass ATMLDm<SDPatternOperator from,
1790fe6060f1SDimitry Andric                  RM torri, RM torii,
1791fe6060f1SDimitry Andric                  RM tozri, RM tozii> {
1792*0fca6ea1SDimitry Andric  def : Pat<(iAny (from ADDRrri:$addr)), (torri MEMrri:$addr)>;
1793*0fca6ea1SDimitry Andric  def : Pat<(iAny (from ADDRrii:$addr)), (torii MEMrii:$addr)>;
1794*0fca6ea1SDimitry Andric  def : Pat<(iAny (from ADDRzri:$addr)), (tozri MEMzri:$addr)>;
1795*0fca6ea1SDimitry Andric  def : Pat<(iAny (from ADDRzii:$addr)), (tozii MEMzii:$addr)>;
1796e8d8bef9SDimitry Andric}
1797e8d8bef9SDimitry Andricdefm : ATMLDm<atomic_load_8, LD1BZXrri, LD1BZXrii, LD1BZXzri, LD1BZXzii>;
1798e8d8bef9SDimitry Andricdefm : ATMLDm<atomic_load_16, LD2BZXrri, LD2BZXrii, LD2BZXzri, LD2BZXzii>;
1799e8d8bef9SDimitry Andricdefm : ATMLDm<atomic_load_32, LDLZXrri, LDLZXrii, LDLZXzri, LDLZXzii>;
1800e8d8bef9SDimitry Andricdefm : ATMLDm<atomic_load_64, LDrri, LDrii, LDzri, LDzii>;
18015ffd83dbSDimitry Andric
1802e8d8bef9SDimitry Andric// Optimized atomic loads with sext
1803fe6060f1SDimitry Andricmulticlass SXATMLDm<SDPatternOperator from, ValueType TY,
1804fe6060f1SDimitry Andric                    RM torri, RM torii,
1805fe6060f1SDimitry Andric                    RM tozri, RM tozii> {
1806e8d8bef9SDimitry Andric  def : Pat<(i64 (sext_inreg (i64 (anyext (from ADDRrri:$addr))), TY)),
1807e8d8bef9SDimitry Andric            (i2l (torri MEMrri:$addr))>;
1808e8d8bef9SDimitry Andric  def : Pat<(i64 (sext_inreg (i64 (anyext (from ADDRrii:$addr))), TY)),
1809e8d8bef9SDimitry Andric            (i2l (torii MEMrii:$addr))>;
1810e8d8bef9SDimitry Andric  def : Pat<(i64 (sext_inreg (i64 (anyext (from ADDRzri:$addr))), TY)),
1811e8d8bef9SDimitry Andric            (i2l (tozri MEMzri:$addr))>;
1812e8d8bef9SDimitry Andric  def : Pat<(i64 (sext_inreg (i64 (anyext (from ADDRzii:$addr))), TY)),
1813e8d8bef9SDimitry Andric            (i2l (tozii MEMzii:$addr))>;
1814e8d8bef9SDimitry Andric}
1815e8d8bef9SDimitry Andricmulticlass SXATMLD32m<SDPatternOperator from,
1816fe6060f1SDimitry Andric                      RM torri, RM torii,
1817fe6060f1SDimitry Andric                      RM tozri, RM tozii> {
1818e8d8bef9SDimitry Andric  def : Pat<(i64 (sext (from ADDRrri:$addr))),
1819e8d8bef9SDimitry Andric            (i2l (torri MEMrri:$addr))>;
1820e8d8bef9SDimitry Andric  def : Pat<(i64 (sext (from ADDRrii:$addr))),
1821e8d8bef9SDimitry Andric            (i2l (torii MEMrii:$addr))>;
1822e8d8bef9SDimitry Andric  def : Pat<(i64 (sext (from ADDRzri:$addr))),
1823e8d8bef9SDimitry Andric            (i2l (tozri MEMzri:$addr))>;
1824e8d8bef9SDimitry Andric  def : Pat<(i64 (sext (from ADDRzii:$addr))),
1825e8d8bef9SDimitry Andric            (i2l (tozii MEMzii:$addr))>;
1826e8d8bef9SDimitry Andric}
1827e8d8bef9SDimitry Andricdefm : SXATMLDm<atomic_load_8, i8, LD1BSXrri, LD1BSXrii, LD1BSXzri, LD1BSXzii>;
1828e8d8bef9SDimitry Andricdefm : SXATMLDm<atomic_load_16, i16, LD2BSXrri, LD2BSXrii, LD2BSXzri,
1829e8d8bef9SDimitry Andric                LD2BSXzii>;
1830e8d8bef9SDimitry Andricdefm : SXATMLD32m<atomic_load_32, LDLSXrri, LDLSXrii, LDLSXzri, LDLSXzii>;
18315ffd83dbSDimitry Andric
1832e8d8bef9SDimitry Andric// Optimized atomic loads with zext
1833fe6060f1SDimitry Andricmulticlass ZXATMLDm<SDPatternOperator from, int VAL,
1834fe6060f1SDimitry Andric                    RM torri, RM torii,
1835fe6060f1SDimitry Andric                    RM tozri, RM tozii> {
1836e8d8bef9SDimitry Andric  def : Pat<(i64 (and (anyext (from ADDRrri:$addr)), VAL)),
1837e8d8bef9SDimitry Andric            (i2l (torri MEMrri:$addr))>;
1838e8d8bef9SDimitry Andric  def : Pat<(i64 (and (anyext (from ADDRrii:$addr)), VAL)),
1839e8d8bef9SDimitry Andric            (i2l (torii MEMrii:$addr))>;
1840e8d8bef9SDimitry Andric  def : Pat<(i64 (and (anyext (from ADDRzri:$addr)), VAL)),
1841e8d8bef9SDimitry Andric            (i2l (tozri MEMzri:$addr))>;
1842e8d8bef9SDimitry Andric  def : Pat<(i64 (and (anyext (from ADDRzii:$addr)), VAL)),
1843e8d8bef9SDimitry Andric            (i2l (tozii MEMzii:$addr))>;
1844e8d8bef9SDimitry Andric}
1845349cc55cSDimitry Andricmulticlass ZXATMLD32m<SDPatternOperator from,
1846fe6060f1SDimitry Andric                      RM torri, RM torii,
1847fe6060f1SDimitry Andric                      RM tozri, RM tozii> {
1848e8d8bef9SDimitry Andric  def : Pat<(i64 (zext (from ADDRrri:$addr))),
1849e8d8bef9SDimitry Andric            (i2l (torri MEMrri:$addr))>;
1850e8d8bef9SDimitry Andric  def : Pat<(i64 (zext (from ADDRrii:$addr))),
1851e8d8bef9SDimitry Andric            (i2l (torii MEMrii:$addr))>;
1852e8d8bef9SDimitry Andric  def : Pat<(i64 (zext (from ADDRzri:$addr))),
1853e8d8bef9SDimitry Andric            (i2l (tozri MEMzri:$addr))>;
1854e8d8bef9SDimitry Andric  def : Pat<(i64 (zext (from ADDRzii:$addr))),
1855e8d8bef9SDimitry Andric            (i2l (tozii MEMzii:$addr))>;
1856e8d8bef9SDimitry Andric}
1857e8d8bef9SDimitry Andricdefm : ZXATMLDm<atomic_load_8, 0xFF, LD1BZXrri, LD1BZXrii, LD1BZXzri,
1858e8d8bef9SDimitry Andric                LD1BZXzii>;
1859e8d8bef9SDimitry Andricdefm : ZXATMLDm<atomic_load_16, 0xFFFF, LD2BZXrri, LD2BZXrii, LD2BZXzri,
1860e8d8bef9SDimitry Andric                LD2BZXzii>;
1861349cc55cSDimitry Andricdefm : ZXATMLD32m<atomic_load_32, LDLZXrri, LDLZXrii, LDLZXzri, LDLZXzii>;
1862e8d8bef9SDimitry Andric
1863e8d8bef9SDimitry Andric// Atomic stores
1864e8d8bef9SDimitry Andricmulticlass ATMSTm<SDPatternOperator from, ValueType ty,
1865fe6060f1SDimitry Andric                  RM torri, RM torii,
1866fe6060f1SDimitry Andric                  RM tozri, RM tozii> {
18675f757f3fSDimitry Andric  def : Pat<(from ty:$src, ADDRrri:$addr), (torri MEMrri:$addr, $src)>;
18685f757f3fSDimitry Andric  def : Pat<(from ty:$src, ADDRrii:$addr), (torii MEMrii:$addr, $src)>;
18695f757f3fSDimitry Andric  def : Pat<(from ty:$src, ADDRzri:$addr), (tozri MEMzri:$addr, $src)>;
18705f757f3fSDimitry Andric  def : Pat<(from ty:$src, ADDRzii:$addr), (tozii MEMzii:$addr, $src)>;
1871e8d8bef9SDimitry Andric}
1872e8d8bef9SDimitry Andricdefm : ATMSTm<atomic_store_8, i32, ST1Brri, ST1Brii, ST1Bzri, ST1Bzii>;
1873e8d8bef9SDimitry Andricdefm : ATMSTm<atomic_store_16, i32, ST2Brri, ST2Brii, ST2Bzri, ST2Bzii>;
1874e8d8bef9SDimitry Andricdefm : ATMSTm<atomic_store_32, i32, STLrri, STLrii, STLzri, STLzii>;
1875e8d8bef9SDimitry Andricdefm : ATMSTm<atomic_store_64, i64, STrri, STrii, STzri, STzii>;
1876e8d8bef9SDimitry Andric
1877e8d8bef9SDimitry Andric// Optimized atomic stores with truncate
1878e8d8bef9SDimitry Andricmulticlass TRATMSTm<SDPatternOperator from,
1879fe6060f1SDimitry Andric                  RM torri,
1880fe6060f1SDimitry Andric                  RM torii,
1881fe6060f1SDimitry Andric                  RM tozri,
1882fe6060f1SDimitry Andric                  RM tozii> {
18835f757f3fSDimitry Andric  def : Pat<(from (i32 (trunc i64:$src)), ADDRrri:$addr),
18845f757f3fSDimitry Andric            (torri MEMrri:$addr, (EXTRACT_SUBREG $src, sub_i32))>;
18855f757f3fSDimitry Andric  def : Pat<(from (i32 (trunc i64:$src)), ADDRrii:$addr),
18865f757f3fSDimitry Andric            (torii MEMrii:$addr, (EXTRACT_SUBREG $src, sub_i32))>;
18875f757f3fSDimitry Andric  def : Pat<(from (i32 (trunc i64:$src)), ADDRzri:$addr),
18885f757f3fSDimitry Andric            (tozri MEMzri:$addr, (EXTRACT_SUBREG $src, sub_i32))>;
18895f757f3fSDimitry Andric  def : Pat<(from (i32 (trunc i64:$src)), ADDRzii:$addr),
18905f757f3fSDimitry Andric            (tozii MEMzii:$addr, (EXTRACT_SUBREG $src, sub_i32))>;
1891e8d8bef9SDimitry Andric}
1892349cc55cSDimitry Andricdefm : TRATMSTm<atomic_store_8, ST1Brri, ST1Brii, ST1Bzri, ST1Bzii>;
1893349cc55cSDimitry Andricdefm : TRATMSTm<atomic_store_16, ST2Brri, ST2Brii, ST2Bzri, ST2Bzii>;
1894349cc55cSDimitry Andricdefm : TRATMSTm<atomic_store_32, STLrri, STLrii, STLzri, STLzii>;
1895e8d8bef9SDimitry Andric
1896e8d8bef9SDimitry Andric// Atomic swaps
1897e8d8bef9SDimitry Andricdef : Pat<(i32 (ts1am i64:$src, i32:$flag, i32:$new)),
1898e8d8bef9SDimitry Andric          (TS1AMWrir $src, 0, $flag, $new)>;
1899*0fca6ea1SDimitry Andricdef : Pat<(i32 (atomic_swap_i32 ADDRri:$src, i32:$new)),
1900e8d8bef9SDimitry Andric          (TS1AMWrii MEMriRRM:$src, 15, $new)>;
1901*0fca6ea1SDimitry Andricdef : Pat<(i64 (atomic_swap_i64 ADDRri:$src, i64:$new)),
1902e8d8bef9SDimitry Andric          (TS1AMLrir MEMriRRM:$src, (LEAzii 0, 0, 255), i64:$new)>;
1903e8d8bef9SDimitry Andric
1904e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===//
1905e8d8bef9SDimitry Andric// SJLJ Exception handling patterns
1906e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===//
1907e8d8bef9SDimitry Andric
1908e8d8bef9SDimitry Andriclet hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1,
1909e8d8bef9SDimitry Andric    usesCustomInserter = 1 in {
1910e8d8bef9SDimitry Andric  let isTerminator = 1 in
1911e8d8bef9SDimitry Andric  def EH_SjLj_LongJmp : Pseudo<(outs), (ins I64:$buf),
1912e8d8bef9SDimitry Andric                               "# EH_SJLJ_LONGJMP",
1913e8d8bef9SDimitry Andric                               [(VEeh_sjlj_longjmp I64:$buf)]>;
1914e8d8bef9SDimitry Andric
1915e8d8bef9SDimitry Andric  def EH_SjLj_SetJmp  : Pseudo<(outs I32:$dst), (ins I64:$buf),
1916e8d8bef9SDimitry Andric                               "# EH_SJLJ_SETJMP",
1917e8d8bef9SDimitry Andric                               [(set I32:$dst, (VEeh_sjlj_setjmp I64:$buf))]>;
1918e8d8bef9SDimitry Andric
1919e8d8bef9SDimitry Andric  def EH_SjLj_Setup_Dispatch : Pseudo<(outs), (ins), "# EH_SJLJ_SETUP_DISPATCH",
1920e8d8bef9SDimitry Andric                                      [(VEeh_sjlj_setup_dispatch)]>;
1921e8d8bef9SDimitry Andric}
1922e8d8bef9SDimitry Andric
1923e8d8bef9SDimitry Andriclet isTerminator = 1, isBranch = 1, isCodeGenOnly = 1 in
1924e8d8bef9SDimitry Andric  def EH_SjLj_Setup : Pseudo<(outs), (ins brtarget32:$dst),
1925e8d8bef9SDimitry Andric                             "# EH_SJlJ_SETUP $dst">;
1926e8d8bef9SDimitry Andric
1927e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===//
1928e8d8bef9SDimitry Andric// Branch related patterns
1929e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===//
19305ffd83dbSDimitry Andric
19315ffd83dbSDimitry Andric// Branches
19325ffd83dbSDimitry Andricdef : Pat<(br bb:$addr), (BRCFLa bb:$addr)>;
19335ffd83dbSDimitry Andric
19345ffd83dbSDimitry Andric// brcc
19355ffd83dbSDimitry Andric// integer brcc
1936fe6060f1SDimitry Andricmulticlass BRCCIm<ValueType ty, CF BrOpNode1,
1937fe6060f1SDimitry Andric                 CF BrOpNode2,
1938fe6060f1SDimitry Andric                 RR CmpOpNode1,
1939fe6060f1SDimitry Andric                 RR CmpOpNode2> {
19405ffd83dbSDimitry Andric  def : Pat<(brcc CCSIOp:$cond, ty:$l, simm7:$r, bb:$addr),
19415ffd83dbSDimitry Andric            (BrOpNode2 (icond2ccSwap $cond), (LO7 $r), $l, bb:$addr)>;
19425ffd83dbSDimitry Andric  def : Pat<(brcc CCSIOp:$cond, ty:$l, ty:$r, bb:$addr),
19435ffd83dbSDimitry Andric            (BrOpNode1 (icond2cc $cond), $l, $r, bb:$addr)>;
19445ffd83dbSDimitry Andric  def : Pat<(brcc CCUIOp:$cond, ty:$l, simm7:$r, bb:$addr),
19455ffd83dbSDimitry Andric            (BrOpNode2 (icond2cc $cond), 0, (CmpOpNode2 (LO7 $r), $l),
19465ffd83dbSDimitry Andric                       bb:$addr)>;
19475ffd83dbSDimitry Andric  def : Pat<(brcc CCUIOp:$cond, ty:$l, ty:$r, bb:$addr),
19485ffd83dbSDimitry Andric            (BrOpNode2 (icond2cc $cond), 0, (CmpOpNode1 $r, $l), bb:$addr)>;
19495ffd83dbSDimitry Andric}
19505ffd83dbSDimitry Andricdefm : BRCCIm<i32, BRCFWrr, BRCFWir, CMPUWrr, CMPUWir>;
19515ffd83dbSDimitry Andricdefm : BRCCIm<i64, BRCFLrr, BRCFLir, CMPULrr, CMPULir>;
19525ffd83dbSDimitry Andric
19535ffd83dbSDimitry Andric// floating point brcc
1954fe6060f1SDimitry Andricmulticlass BRCCFm<ValueType ty, CF BrOpNode1, CF BrOpNode2> {
19555ffd83dbSDimitry Andric  def : Pat<(brcc cond:$cond, ty:$l, simm7fp:$r, bb:$addr),
19565ffd83dbSDimitry Andric            (BrOpNode2 (fcond2ccSwap $cond), (LO7FP $r), $l, bb:$addr)>;
19575ffd83dbSDimitry Andric  def : Pat<(brcc cond:$cond, ty:$l, ty:$r, bb:$addr),
19585ffd83dbSDimitry Andric            (BrOpNode1 (fcond2cc $cond), $l, $r, bb:$addr)>;
19595ffd83dbSDimitry Andric}
19605ffd83dbSDimitry Andricdefm : BRCCFm<f32, BRCFSrr, BRCFSir>;
19615ffd83dbSDimitry Andricdefm : BRCCFm<f64, BRCFDrr, BRCFDir>;
1962e8d8bef9SDimitry Andricdef : Pat<(brcc cond:$cond, f128:$l, f128:$r, bb:$addr),
1963e8d8bef9SDimitry Andric          (BRCFDir (fcond2cc $cond), 0, (FCMPQrr $r, $l), bb:$addr)>;
1964480093f4SDimitry Andric
1965480093f4SDimitry Andric//===----------------------------------------------------------------------===//
1966480093f4SDimitry Andric// Pseudo Instructions
1967480093f4SDimitry Andric//===----------------------------------------------------------------------===//
1968480093f4SDimitry Andric
19695ffd83dbSDimitry Andric// GETGOT for PIC
19705ffd83dbSDimitry Andriclet Defs = [SX15 /* %got */, SX16 /* %plt */], hasSideEffects = 0 in {
19715ffd83dbSDimitry Andric  def GETGOT : Pseudo<(outs getGOT:$getpcseq), (ins), "$getpcseq">;
19725ffd83dbSDimitry Andric}
19735ffd83dbSDimitry Andric
19745ffd83dbSDimitry Andric// GETFUNPLT for PIC
19755ffd83dbSDimitry Andriclet hasSideEffects = 0 in
19765ffd83dbSDimitry Andricdef GETFUNPLT : Pseudo<(outs I64:$dst), (ins i64imm:$addr),
19775ffd83dbSDimitry Andric                       "$dst, $addr",
19785ffd83dbSDimitry Andric                       [(set iPTR:$dst, (GetFunPLT tglobaladdr:$addr))] >;
19795ffd83dbSDimitry Andric
19805ffd83dbSDimitry Andricdef : Pat<(GetFunPLT tglobaladdr:$dst),
19815ffd83dbSDimitry Andric          (GETFUNPLT tglobaladdr:$dst)>;
19825ffd83dbSDimitry Andricdef : Pat<(GetFunPLT texternalsym:$dst),
19835ffd83dbSDimitry Andric          (GETFUNPLT texternalsym:$dst)>;
19845ffd83dbSDimitry Andric
19855ffd83dbSDimitry Andric// GETTLSADDR for TLS
19865ffd83dbSDimitry Andriclet Defs = [SX0, SX10, SX12], hasSideEffects = 0 in
19875ffd83dbSDimitry Andricdef GETTLSADDR : Pseudo<(outs), (ins i64imm:$addr),
19885ffd83dbSDimitry Andric                        "# GETTLSADDR $addr",
19895ffd83dbSDimitry Andric                        [(GetTLSAddr tglobaltlsaddr:$addr)] >;
19905ffd83dbSDimitry Andric
19915ffd83dbSDimitry Andricdef : Pat<(GetTLSAddr tglobaltlsaddr:$dst),
19925ffd83dbSDimitry Andric          (GETTLSADDR tglobaltlsaddr:$dst)>;
19935ffd83dbSDimitry Andric
1994480093f4SDimitry Andriclet Defs = [SX11], Uses = [SX11], hasSideEffects = 0 in {
1995480093f4SDimitry Andricdef ADJCALLSTACKDOWN : Pseudo<(outs), (ins i64imm:$amt, i64imm:$amt2),
1996480093f4SDimitry Andric                              "# ADJCALLSTACKDOWN $amt, $amt2",
1997480093f4SDimitry Andric                              [(callseq_start timm:$amt, timm:$amt2)]>;
1998480093f4SDimitry Andricdef ADJCALLSTACKUP : Pseudo<(outs), (ins i64imm:$amt1, i64imm:$amt2),
1999480093f4SDimitry Andric                            "# ADJCALLSTACKUP $amt1",
2000480093f4SDimitry Andric                            [(callseq_end timm:$amt1, timm:$amt2)]>;
2001480093f4SDimitry Andric}
2002480093f4SDimitry Andric
2003480093f4SDimitry Andriclet Defs = [SX8], Uses = [SX8, SX11], hasSideEffects = 0 in
2004480093f4SDimitry Andricdef EXTEND_STACK : Pseudo<(outs), (ins),
2005480093f4SDimitry Andric                          "# EXTEND STACK",
2006480093f4SDimitry Andric                          []>;
2007480093f4SDimitry Andriclet  hasSideEffects = 0 in
2008480093f4SDimitry Andricdef EXTEND_STACK_GUARD : Pseudo<(outs), (ins),
2009480093f4SDimitry Andric                                "# EXTEND STACK GUARD",
2010480093f4SDimitry Andric                                []>;
20115ffd83dbSDimitry Andric
20125ffd83dbSDimitry Andric// Dynamic stack allocation yields a __llvm_grow_stack for VE targets.
20135ffd83dbSDimitry Andric// These calls are needed to probe the stack when allocating more over
20145ffd83dbSDimitry Andric// %s8 (%sl - stack limit).
20155ffd83dbSDimitry Andric
20165ffd83dbSDimitry Andriclet Uses = [SX11], hasSideEffects = 1 in
20175ffd83dbSDimitry Andricdef GETSTACKTOP : Pseudo<(outs I64:$dst), (ins),
20185ffd83dbSDimitry Andric                         "# GET STACK TOP",
20195ffd83dbSDimitry Andric                         [(set iPTR:$dst, (GetStackTop))]>;
2020e8d8bef9SDimitry Andric
2021e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===//
2022e8d8bef9SDimitry Andric// Other patterns
2023e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===//
2024e8d8bef9SDimitry Andric
20255ffd83dbSDimitry Andric// SETCC pattern matches
20265ffd83dbSDimitry Andric//
20275ffd83dbSDimitry Andric//   CMP  %tmp, lhs, rhs     ; compare lhs and rhs
20285ffd83dbSDimitry Andric//   or   %res, 0, (0)1      ; initialize by 0
20295ffd83dbSDimitry Andric//   CMOV %res, (63)0, %tmp  ; set 1 if %tmp is true
20305ffd83dbSDimitry Andric
2031e8d8bef9SDimitry Andricclass setccrr<Instruction INSN> :
2032e8d8bef9SDimitry Andric    OutPatFrag<(ops node:$cond, node:$comp),
20335ffd83dbSDimitry Andric               (EXTRACT_SUBREG
2034e8d8bef9SDimitry Andric                   (INSN $cond, $comp,
2035e8d8bef9SDimitry Andric                         !add(63, 64), // means (63)0 == 1
20365ffd83dbSDimitry Andric                         (ORim 0, 0)), sub_i32)>;
20375ffd83dbSDimitry Andric
2038e8d8bef9SDimitry Andricdef : Pat<(i32 (setcc i32:$l, i32:$r, CCSIOp:$cond)),
2039e8d8bef9SDimitry Andric          (setccrr<CMOVWrm> (icond2cc $cond), (CMPSWSXrr $l, $r))>;
2040e8d8bef9SDimitry Andricdef : Pat<(i32 (setcc i32:$l, i32:$r, CCUIOp:$cond)),
2041e8d8bef9SDimitry Andric          (setccrr<CMOVWrm> (icond2cc $cond), (CMPUWrr $l, $r))>;
2042e8d8bef9SDimitry Andricdef : Pat<(i32 (setcc i64:$l, i64:$r, CCSIOp:$cond)),
2043e8d8bef9SDimitry Andric          (setccrr<CMOVLrm> (icond2cc $cond), (CMPSLrr $l, $r))>;
2044e8d8bef9SDimitry Andricdef : Pat<(i32 (setcc i64:$l, i64:$r, CCUIOp:$cond)),
2045e8d8bef9SDimitry Andric          (setccrr<CMOVLrm> (icond2cc $cond), (CMPULrr $l, $r))>;
2046e8d8bef9SDimitry Andricdef : Pat<(i32 (setcc f32:$l, f32:$r, cond:$cond)),
2047e8d8bef9SDimitry Andric          (setccrr<CMOVSrm> (fcond2cc $cond), (FCMPSrr $l, $r))>;
2048e8d8bef9SDimitry Andricdef : Pat<(i32 (setcc f64:$l, f64:$r, cond:$cond)),
2049e8d8bef9SDimitry Andric          (setccrr<CMOVDrm> (fcond2cc $cond), (FCMPDrr $l, $r))>;
2050e8d8bef9SDimitry Andricdef : Pat<(i32 (setcc f128:$l, f128:$r, cond:$cond)),
2051e8d8bef9SDimitry Andric          (setccrr<CMOVDrm> (fcond2cc $cond), (FCMPQrr $l, $r))>;
20525ffd83dbSDimitry Andric
2053bdd1243dSDimitry Andric// Generic CMOV pattern matches
2054bdd1243dSDimitry Andric//   CMOV accepts i64 $t, $f, and result.  So, we extend it to support
2055bdd1243dSDimitry Andric//   i32/f32/f64/f128 $t, $f, and result.
20565ffd83dbSDimitry Andric
2057bdd1243dSDimitry Andric// CMOV for i32
2058bdd1243dSDimitry Andricmulticlass CMOVI32m<ValueType TY, string Insn> {
2059bdd1243dSDimitry Andric  def : Pat<(i32 (cmov TY:$cmp, i32:$t, i32:$f, (i32 CCOp:$cond))),
2060e8d8bef9SDimitry Andric            (EXTRACT_SUBREG
2061bdd1243dSDimitry Andric                (!cast<Instruction>(Insn#"rr") (CCOP $cond), $cmp,
2062bdd1243dSDimitry Andric                           (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $t, sub_i32),
2063bdd1243dSDimitry Andric                           (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $f, sub_i32)),
2064bdd1243dSDimitry Andric                sub_i32)>;
2065bdd1243dSDimitry Andric  def : Pat<(i32 (cmov TY:$cmp, (i32 mimm:$t), i32:$f, (i32 CCOp:$cond))),
2066e8d8bef9SDimitry Andric            (EXTRACT_SUBREG
2067bdd1243dSDimitry Andric                (!cast<Instruction>(Insn#"rm") (CCOP $cond), $cmp,
2068bdd1243dSDimitry Andric                           (MIMM $t),
2069bdd1243dSDimitry Andric                           (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $f, sub_i32)),
2070bdd1243dSDimitry Andric                sub_i32)>;
2071bdd1243dSDimitry Andric}
2072bdd1243dSDimitry Andricdefm : CMOVI32m<i64, "CMOVL">;
2073bdd1243dSDimitry Andricdefm : CMOVI32m<i32, "CMOVW">;
2074bdd1243dSDimitry Andricdefm : CMOVI32m<f64, "CMOVD">;
2075bdd1243dSDimitry Andricdefm : CMOVI32m<f32, "CMOVS">;
2076bdd1243dSDimitry Andric
2077bdd1243dSDimitry Andric// CMOV for f32
2078bdd1243dSDimitry Andricmulticlass CMOVF32m<ValueType TY, string Insn> {
2079bdd1243dSDimitry Andric  def : Pat<(f32 (cmov TY:$cmp, f32:$t, f32:$f, (i32 CCOp:$cond))),
2080bdd1243dSDimitry Andric            (EXTRACT_SUBREG
2081bdd1243dSDimitry Andric                (!cast<Instruction>(Insn#"rr")
2082bdd1243dSDimitry Andric                    (CCOP $cond), $cmp,
2083bdd1243dSDimitry Andric                    (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $t, sub_f32),
2084bdd1243dSDimitry Andric                    (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $f, sub_f32)),
2085bdd1243dSDimitry Andric                sub_f32)>;
2086bdd1243dSDimitry Andric  def : Pat<(f32 (cmov TY:$cmp, (f32 mimmfp:$t), f32:$f, (i32 CCOp:$cond))),
2087bdd1243dSDimitry Andric            (EXTRACT_SUBREG
2088bdd1243dSDimitry Andric                (!cast<Instruction>(Insn#"rm")
2089bdd1243dSDimitry Andric                    (CCOP $cond), $cmp, (MIMMFP $t),
2090bdd1243dSDimitry Andric                    (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $f, sub_f32)),
2091bdd1243dSDimitry Andric                sub_f32)>;
2092bdd1243dSDimitry Andric}
2093bdd1243dSDimitry Andricdefm : CMOVF32m<i64, "CMOVL">;
2094bdd1243dSDimitry Andricdefm : CMOVF32m<i32, "CMOVW">;
2095bdd1243dSDimitry Andricdefm : CMOVF32m<f64, "CMOVD">;
2096bdd1243dSDimitry Andricdefm : CMOVF32m<f32, "CMOVS">;
2097bdd1243dSDimitry Andric
2098bdd1243dSDimitry Andric// CMOV for f64
2099bdd1243dSDimitry Andricmulticlass CMOVF64m<ValueType TY, string Insn> {
2100bdd1243dSDimitry Andric  def : Pat<(f64 (cmov TY:$cmp, f64:$t, f64:$f, (i32 CCOp:$cond))),
2101bdd1243dSDimitry Andric            (!cast<Instruction>(Insn#"rr") (CCOP $cond), $cmp, $t, $f)>;
2102bdd1243dSDimitry Andric  def : Pat<(f64 (cmov TY:$cmp, (f64 mimmfp:$t), f64:$f, (i32 CCOp:$cond))),
2103bdd1243dSDimitry Andric            (!cast<Instruction>(Insn#"rm") (CCOP $cond), $cmp, (MIMMFP $t),
2104bdd1243dSDimitry Andric                                           $f)>;
2105bdd1243dSDimitry Andric}
2106bdd1243dSDimitry Andricdefm : CMOVF64m<i64, "CMOVL">;
2107bdd1243dSDimitry Andricdefm : CMOVF64m<i32, "CMOVW">;
2108bdd1243dSDimitry Andricdefm : CMOVF64m<f64, "CMOVD">;
2109bdd1243dSDimitry Andricdefm : CMOVF64m<f32, "CMOVS">;
2110bdd1243dSDimitry Andric
2111bdd1243dSDimitry Andric// CMOV for f128
2112bdd1243dSDimitry Andricmulticlass CMOVF128m<ValueType TY, string Insn> {
2113bdd1243dSDimitry Andric  def : Pat<(f128 (cmov TY:$cmp, f128:$t, f128:$f, (i32 CCOp:$cond))),
2114e8d8bef9SDimitry Andric            (INSERT_SUBREG
2115e8d8bef9SDimitry Andric              (INSERT_SUBREG (f128 (IMPLICIT_DEF)),
2116bdd1243dSDimitry Andric                (!cast<Instruction>(Insn#"rr") (CCOP $cond), $cmp,
2117e8d8bef9SDimitry Andric                  (EXTRACT_SUBREG $t, sub_odd),
2118e8d8bef9SDimitry Andric                  (EXTRACT_SUBREG $f, sub_odd)), sub_odd),
2119bdd1243dSDimitry Andric              (!cast<Instruction>(Insn#"rr") (CCOP $cond), $cmp,
2120e8d8bef9SDimitry Andric                (EXTRACT_SUBREG $t, sub_even),
2121e8d8bef9SDimitry Andric                (EXTRACT_SUBREG $f, sub_even)), sub_even)>;
2122bdd1243dSDimitry Andric}
2123bdd1243dSDimitry Andricdefm : CMOVF128m<i64, "CMOVL">;
2124bdd1243dSDimitry Andricdefm : CMOVF128m<i32, "CMOVW">;
2125bdd1243dSDimitry Andricdefm : CMOVF128m<f64, "CMOVD">;
2126bdd1243dSDimitry Andricdefm : CMOVF128m<f32, "CMOVS">;
21275ffd83dbSDimitry Andric
21285ffd83dbSDimitry Andric// bitconvert
21295ffd83dbSDimitry Andricdef : Pat<(f64 (bitconvert i64:$src)), (COPY_TO_REGCLASS $src, I64)>;
21305ffd83dbSDimitry Andricdef : Pat<(i64 (bitconvert f64:$src)), (COPY_TO_REGCLASS $src, I64)>;
21315ffd83dbSDimitry Andric
2132bdd1243dSDimitry Andricdef : Pat<(i32 (bitconvert f32:$op)), (l2i (SRALri (f2l $op), 32))>;
2133bdd1243dSDimitry Andricdef : Pat<(f32 (bitconvert i32:$op)), (l2f (SLLri (i2l $op), 32))>;
21345ffd83dbSDimitry Andric
2135e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===//
2136e8d8bef9SDimitry Andric// Vector Instruction Pattern Stuff
2137e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===//
2138e8d8bef9SDimitry Andric
2139e8d8bef9SDimitry Andric// Custom intermediate ISDs.
2140e8d8bef9SDimitry Andricclass IsVLVT<int OpIdx> : SDTCisVT<OpIdx,i32>;
2141e8d8bef9SDimitry Andricdef vec_broadcast       : SDNode<"VEISD::VEC_BROADCAST", SDTypeProfile<1, 2,
2142e8d8bef9SDimitry Andric                                 [SDTCisVec<0>, IsVLVT<2>]>>;
2143e8d8bef9SDimitry Andric
214481ad6265SDimitry Andric///// Packed mode Support /////
214581ad6265SDimitry Andric// unpack the lo part of this vector
214681ad6265SDimitry Andricdef vec_unpack_lo   : SDNode<"VEISD::VEC_UNPACK_LO", SDTypeProfile<1, 2,
214781ad6265SDimitry Andric                             [SDTCisVec<0>, SDTCisVec<1>, IsVLVT<2>]>>;
214881ad6265SDimitry Andric// unpack the hipart of this vector
214981ad6265SDimitry Andricdef vec_unpack_hi   : SDNode<"VEISD::VEC_UNPACK_HI", SDTypeProfile<1, 2,
215081ad6265SDimitry Andric                             [SDTCisVec<0>, SDTCisVec<1>, IsVLVT<2>]>>;
215181ad6265SDimitry Andric// re-pack v256i32, v256f32 back into tone v512.32
215281ad6265SDimitry Andricdef vec_pack        : SDNode<"VEISD::VEC_PACK", SDTypeProfile<1, 3,
215381ad6265SDimitry Andric                             [SDTCisVec<0>, SDTCisVec<1>, SDTCisVec<2>,
215481ad6265SDimitry Andric                              SDTCisSameNumEltsAs<1,2>, IsVLVT<3>]>>;
215581ad6265SDimitry Andric
215604eeddc0SDimitry Andric// replicate lower 32bit to upper 32bit (f32 scalar replication).
215704eeddc0SDimitry Andricdef repl_f32            : SDNode<"VEISD::REPL_F32",
215804eeddc0SDimitry Andric                            SDTypeProfile<1, 1,
215904eeddc0SDimitry Andric                              [SDTCisInt<0>, SDTCisFP<1>]>>;
216004eeddc0SDimitry Andric// replicate upper 32bit to lower 32 bit (i32 scalar replication).
216104eeddc0SDimitry Andricdef repl_i32            : SDNode<"VEISD::REPL_I32",
216204eeddc0SDimitry Andric                            SDTypeProfile<1, 1,
216304eeddc0SDimitry Andric                              [SDTCisInt<0>, SDTCisInt<1>]>>;
216404eeddc0SDimitry Andric
216504eeddc0SDimitry Andric
2166e8d8bef9SDimitry Andric// Whether this is an all-true mask (assuming undef-bits above VL are all-true).
2167e8d8bef9SDimitry Andricdef true_mask           : PatLeaf<
2168e8d8bef9SDimitry Andric                            (vec_broadcast (i32 nonzero), (i32 srcvalue))>;
2169e8d8bef9SDimitry Andric// Match any broadcast (ignoring VL).
2170e8d8bef9SDimitry Andricdef any_broadcast       : PatFrag<(ops node:$sx),
2171e8d8bef9SDimitry Andric                                  (vec_broadcast node:$sx, (i32 srcvalue))>;
2172e8d8bef9SDimitry Andric
2173e8d8bef9SDimitry Andric// Vector instructions.
2174e8d8bef9SDimitry Andricinclude "VEInstrVec.td"
2175e8d8bef9SDimitry Andric
2176e8d8bef9SDimitry Andric// The vevlintrin
2177e8d8bef9SDimitry Andricinclude "VEInstrIntrinsicVL.td"
2178e8d8bef9SDimitry Andric
2179e8d8bef9SDimitry Andric// Patterns and intermediate SD nodes (VEC_*).
2180e8d8bef9SDimitry Andricinclude "VEInstrPatternsVec.td"
2181e8d8bef9SDimitry Andric
2182e8d8bef9SDimitry Andric// Patterns and intermediate SD nodes (VVP_*).
2183e8d8bef9SDimitry Andricinclude "VVPInstrPatternsVec.td"
2184