xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Lanai/LanaiInstrInfo.td (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
10b57cec5SDimitry Andric//===-- LanaiInstrInfo.td - Target Description for Lanai Target -----------===//
20b57cec5SDimitry Andric//
30b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric//
70b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric//
90b57cec5SDimitry Andric// This file describes the Lanai instructions in TableGen format.
100b57cec5SDimitry Andric//
110b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
140b57cec5SDimitry Andric// Instruction format superclass
150b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
160b57cec5SDimitry Andric
170b57cec5SDimitry Andricinclude "LanaiInstrFormats.td"
180b57cec5SDimitry Andric
190b57cec5SDimitry Andric// -------------------------------------------------- //
200b57cec5SDimitry Andric// Instruction Operands and Patterns
210b57cec5SDimitry Andric// -------------------------------------------------- //
220b57cec5SDimitry Andric
230b57cec5SDimitry Andric//  These are target-independent nodes, but have target-specific formats.
240b57cec5SDimitry Andricdef SDT_LanaiCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>,
250b57cec5SDimitry Andric                                            SDTCisVT<1, i32>]>;
260b57cec5SDimitry Andricdef SDT_LanaiCallSeqEnd   : SDCallSeqEnd<[SDTCisVT<0, i32>,
270b57cec5SDimitry Andric                                          SDTCisVT<1, i32>]>;
280b57cec5SDimitry Andricdef SDT_LanaiCall         : SDTypeProfile<0, -1, [SDTCisVT<0, i32>]>;
290b57cec5SDimitry Andricdef SDT_LanaiSetFlag      : SDTypeProfile<0,  2, [SDTCisSameAs<0, 1>]>;
300b57cec5SDimitry Andricdef SDT_LanaiSelectCC     : SDTypeProfile<1,  3, [SDTCisSameAs<0, 1>,
310b57cec5SDimitry Andric                                                  SDTCisSameAs<1, 2>]>;
320b57cec5SDimitry Andricdef SDT_LanaiSetCC        : SDTypeProfile<1,  1, [SDTCisVT<0, i32>,
330b57cec5SDimitry Andric                                                  SDTCisVT<1, i32>]>;
340b57cec5SDimitry Andricdef SDT_LanaiBrCC         : SDTypeProfile<0,  2, [SDTCisVT<0, OtherVT>,
350b57cec5SDimitry Andric                                                  SDTCisVT<1, i32>]>;
360b57cec5SDimitry Andricdef SDT_LanaiAdjDynAlloc  : SDTypeProfile<1,  1, [SDTCisVT<0, i32>,
370b57cec5SDimitry Andric                                                  SDTCisVT<1, i32>]>;
380b57cec5SDimitry Andric
390b57cec5SDimitry Andricdef Call             : SDNode<"LanaiISD::CALL", SDT_LanaiCall,
400b57cec5SDimitry Andric                              [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
410b57cec5SDimitry Andric                               SDNPVariadic]>;
42*06c3fb27SDimitry Andricdef RetGlue          : SDNode<"LanaiISD::RET_GLUE", SDTNone,
430b57cec5SDimitry Andric                              [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
440b57cec5SDimitry Andricdef CallSeqStart     : SDNode<"ISD::CALLSEQ_START", SDT_LanaiCallSeqStart,
450b57cec5SDimitry Andric                              [SDNPHasChain, SDNPOutGlue]>;
460b57cec5SDimitry Andricdef CallSeqEnd       : SDNode<"ISD::CALLSEQ_END", SDT_LanaiCallSeqEnd,
470b57cec5SDimitry Andric                              [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
480b57cec5SDimitry Andricdef LanaiSetFlag     : SDNode<"LanaiISD::SET_FLAG", SDT_LanaiSetFlag,
490b57cec5SDimitry Andric                              [SDNPOutGlue]>;
500b57cec5SDimitry Andricdef LanaiSubbF       : SDNode<"LanaiISD::SUBBF", SDT_LanaiSetFlag,
510b57cec5SDimitry Andric                              [SDNPOutGlue, SDNPInGlue]>;
520b57cec5SDimitry Andricdef LanaiBrCC        : SDNode<"LanaiISD::BR_CC", SDT_LanaiBrCC,
530b57cec5SDimitry Andric                              [SDNPHasChain, SDNPInGlue]>;
540b57cec5SDimitry Andricdef LanaiSelectCC    : SDNode<"LanaiISD::SELECT_CC", SDT_LanaiSelectCC,
550b57cec5SDimitry Andric                              [SDNPInGlue]>;
560b57cec5SDimitry Andricdef LanaiSetCC       : SDNode<"LanaiISD::SETCC", SDT_LanaiSetCC,
570b57cec5SDimitry Andric                              [SDNPInGlue]>;
580b57cec5SDimitry Andricdef LanaiHi          : SDNode<"LanaiISD::HI", SDTIntUnaryOp>;
590b57cec5SDimitry Andricdef LanaiLo          : SDNode<"LanaiISD::LO", SDTIntUnaryOp>;
600b57cec5SDimitry Andricdef LanaiSmall       : SDNode<"LanaiISD::SMALL", SDTIntUnaryOp>;
610b57cec5SDimitry Andricdef LanaiAdjDynAlloc : SDNode<"LanaiISD::ADJDYNALLOC", SDT_LanaiAdjDynAlloc>;
620b57cec5SDimitry Andric
630b57cec5SDimitry Andric// Extract bits 0-15 (low-end) of an immediate value.
640b57cec5SDimitry Andricdef LO16 : SDNodeXForm<imm, [{
650b57cec5SDimitry Andric  return CurDAG->getTargetConstant((uint64_t)N->getZExtValue() & 0xffff,
660b57cec5SDimitry Andric                                   SDLoc(N), MVT::i32);
670b57cec5SDimitry Andric}]>;
680b57cec5SDimitry Andric
690b57cec5SDimitry Andric// Extract bits 16-31 (high-end) of an immediate value.
700b57cec5SDimitry Andric// Transformation function: shift the immediate value down into the low bits.
710b57cec5SDimitry Andricdef HI16 : SDNodeXForm<imm, [{
720b57cec5SDimitry Andric  return CurDAG->getTargetConstant((uint64_t)N->getZExtValue() >> 16, SDLoc(N),
730b57cec5SDimitry Andric                                   MVT::i32);
740b57cec5SDimitry Andric}]>;
750b57cec5SDimitry Andric
760b57cec5SDimitry Andricdef NEG : SDNodeXForm<imm, [{
770b57cec5SDimitry Andric  return CurDAG->getTargetConstant(-N->getSExtValue(), SDLoc(N), MVT::i32);
780b57cec5SDimitry Andric}]>;
790b57cec5SDimitry Andric
800b57cec5SDimitry Andricdef LO21 : SDNodeXForm<imm, [{
810b57cec5SDimitry Andric  return CurDAG->getTargetConstant((uint64_t)N->getZExtValue() & 0x1fffff,
820b57cec5SDimitry Andric                                   SDLoc(N), MVT::i32);
830b57cec5SDimitry Andric}]>;
840b57cec5SDimitry Andric
850b57cec5SDimitry Andric// Branch targets
860b57cec5SDimitry Andricdef BrTargetAsmOperand : AsmOperandClass {
870b57cec5SDimitry Andric  let Name = "BrTarget";
880b57cec5SDimitry Andric}
890b57cec5SDimitry Andricdef BrTarget   : Operand<OtherVT> {
900b57cec5SDimitry Andric  let ParserMatchClass = BrTargetAsmOperand;
910b57cec5SDimitry Andric  let EncoderMethod = "getBranchTargetOpValue";
920b57cec5SDimitry Andric  let DecoderMethod = "decodeBranch";
930b57cec5SDimitry Andric}
940b57cec5SDimitry Andric
950b57cec5SDimitry Andricdef CallTargetAsmOperand : AsmOperandClass {
960b57cec5SDimitry Andric  let Name = "CallTarget";
970b57cec5SDimitry Andric}
980b57cec5SDimitry Andricdef CallTarget : Operand<i32> {
990b57cec5SDimitry Andric  let ParserMatchClass = CallTargetAsmOperand;
1000b57cec5SDimitry Andric  let EncoderMethod = "getBranchTargetOpValue";
1010b57cec5SDimitry Andric  let DecoderMethod = "decodeBranch";
1020b57cec5SDimitry Andric}
1030b57cec5SDimitry Andric
1040b57cec5SDimitry Andricdef ImmShiftAsmOperand : AsmOperandClass { let Name = "ImmShift"; }
1050b57cec5SDimitry Andricdef immShift : Operand<i32>, PatLeaf<(imm), [{
1060b57cec5SDimitry Andric    int Imm = N->getSExtValue();
1070b57cec5SDimitry Andric    return Imm >= -31 && Imm <= 31;}]> {
1080b57cec5SDimitry Andric  let ParserMatchClass = ImmShiftAsmOperand;
1090b57cec5SDimitry Andric  let DecoderMethod = "decodeShiftImm";
1100b57cec5SDimitry Andric}
1110b57cec5SDimitry Andric
1120b57cec5SDimitry Andricdef Imm10AsmOperand : AsmOperandClass { let Name = "Imm10"; }
1130b57cec5SDimitry Andricdef imm10 : Operand<i32>, PatLeaf<(imm), [{
1140b57cec5SDimitry Andric    return isInt<10>(N->getSExtValue()); }]> {
1150b57cec5SDimitry Andric  let ParserMatchClass = Imm10AsmOperand;
1160b57cec5SDimitry Andric}
1170b57cec5SDimitry Andric
1180b57cec5SDimitry Andricdef LoImm16AsmOperand : AsmOperandClass { let Name = "LoImm16"; }
1190b57cec5SDimitry Andricdef i32lo16z : Operand<i32>, PatLeaf<(i32 imm), [{
1200b57cec5SDimitry Andric    // i32lo16 predicate - true if the 32-bit immediate has only rightmost 16
1210b57cec5SDimitry Andric    // bits set.
1220b57cec5SDimitry Andric    return ((N->getZExtValue() & 0xFFFFUL) == N->getZExtValue());}], LO16> {
1230b57cec5SDimitry Andric  let ParserMatchClass = LoImm16AsmOperand;
1240b57cec5SDimitry Andric}
1250b57cec5SDimitry Andricdef i32neg16 : Operand<i32>, PatLeaf<(i32 imm), [{
1260b57cec5SDimitry Andric    // i32neg16 predicate - true if the 32-bit immediate is negative and can
1270b57cec5SDimitry Andric    // be represented by a 16 bit integer.
1280b57cec5SDimitry Andric    int Imm = N->getSExtValue();
1290b57cec5SDimitry Andric    return (Imm < 0) && (isInt<16>(Imm));}], LO16> {
1300b57cec5SDimitry Andric  let ParserMatchClass = LoImm16AsmOperand;
1310b57cec5SDimitry Andric}
1320b57cec5SDimitry Andricdef i32lo16s : Operand<i32>, PatLeaf<(i32 imm), [{
1330b57cec5SDimitry Andric    // i32lo16 predicate - true if the 32-bit immediate has only rightmost 16
1340b57cec5SDimitry Andric    // bits set.
1350b57cec5SDimitry Andric    return ((int64_t)(N->getSExtValue() & 0xFFFFUL) == N->getSExtValue());}], LO16> {
1360b57cec5SDimitry Andric  let ParserMatchClass = LoImm16AsmOperand;
1370b57cec5SDimitry Andric}
1380b57cec5SDimitry Andric
1390b57cec5SDimitry Andricdef LoImm16AndAsmOperand : AsmOperandClass { let Name = "LoImm16And"; }
1400b57cec5SDimitry Andricdef i32lo16and : Operand<i32>, PatLeaf<(i32 imm), [{
1410b57cec5SDimitry Andric    // i32lo16 predicate - true if the 32-bit immediate has the rightmost 16
1420b57cec5SDimitry Andric    // bits set and the leftmost 16 bits 1's.
1430b57cec5SDimitry Andric    return (N->getZExtValue() >= 0xFFFF0000UL);}], LO16> {
1440b57cec5SDimitry Andric  let ParserMatchClass = LoImm16AndAsmOperand;
1450b57cec5SDimitry Andric  let PrintMethod = "printLo16AndImmOperand";
1460b57cec5SDimitry Andric}
1470b57cec5SDimitry Andric
1480b57cec5SDimitry Andricdef HiImm16AsmOperand : AsmOperandClass { let Name = "HiImm16"; }
1490b57cec5SDimitry Andricdef i32hi16 : Operand<i32>, PatLeaf<(i32 imm), [{
1500b57cec5SDimitry Andric    // i32hi16 predicate - true if the 32-bit immediate has only leftmost 16
1510b57cec5SDimitry Andric    // bits set.
1520b57cec5SDimitry Andric    return ((N->getZExtValue() & 0xFFFF0000UL) == N->getZExtValue());}], HI16> {
1530b57cec5SDimitry Andric  let ParserMatchClass = HiImm16AsmOperand;
1540b57cec5SDimitry Andric  let PrintMethod = "printHi16ImmOperand";
1550b57cec5SDimitry Andric}
1560b57cec5SDimitry Andric
1570b57cec5SDimitry Andricdef HiImm16AndAsmOperand : AsmOperandClass { let Name = "HiImm16And"; }
1580b57cec5SDimitry Andricdef i32hi16and : Operand<i32>, PatLeaf<(i32 imm), [{
1590b57cec5SDimitry Andric    // i32lo16 predicate - true if the 32-bit immediate has the leftmost 16
1600b57cec5SDimitry Andric    // bits set and the rightmost 16 bits 1's.
1610b57cec5SDimitry Andric    return ((N->getZExtValue() & 0xFFFFUL) == 0xFFFFUL);}], HI16> {
1620b57cec5SDimitry Andric  let ParserMatchClass = HiImm16AndAsmOperand;
1630b57cec5SDimitry Andric  let PrintMethod = "printHi16AndImmOperand";
1640b57cec5SDimitry Andric}
1650b57cec5SDimitry Andric
1660b57cec5SDimitry Andricdef LoImm21AsmOperand : AsmOperandClass { let Name = "LoImm21"; }
1670b57cec5SDimitry Andricdef i32lo21 : Operand<i32>, PatLeaf<(i32 imm), [{
1680b57cec5SDimitry Andric    // i32lo21 predicate - true if the 32-bit immediate has only rightmost 21
1690b57cec5SDimitry Andric    // bits set.
1700b57cec5SDimitry Andric    return ((N->getZExtValue() & 0x1FFFFFUL) == N->getZExtValue());}], LO21> {
1710b57cec5SDimitry Andric  let ParserMatchClass = LoImm21AsmOperand;
1720b57cec5SDimitry Andric}
1730b57cec5SDimitry Andric
1740b57cec5SDimitry Andricdef AluOp : Operand<i32> {
1750b57cec5SDimitry Andric  let PrintMethod = "printAluOperand";
1760b57cec5SDimitry Andric}
1770b57cec5SDimitry Andric
1780b57cec5SDimitry Andric// Addressing modes.
1790b57cec5SDimitry Andricdef ADDRrr : ComplexPattern<i32, 3, "selectAddrRr", [], []>;
1800b57cec5SDimitry Andricdef ADDRri : ComplexPattern<i32, 3, "selectAddrRi", [frameindex], []>;
1810b57cec5SDimitry Andricdef ADDRsls : ComplexPattern<i32, 1, "selectAddrSls", [frameindex], []>;
1820b57cec5SDimitry Andricdef ADDRspls : ComplexPattern<i32, 3, "selectAddrSpls", [frameindex], []>;
1830b57cec5SDimitry Andric
1840b57cec5SDimitry Andric// Address operands
1850b57cec5SDimitry Andricdef MemRegImmAsmOperand : AsmOperandClass {
1860b57cec5SDimitry Andric  let Name = "MemRegImm";
1870b57cec5SDimitry Andric  let ParserMethod  = "parseMemoryOperand";
1880b57cec5SDimitry Andric}
1890b57cec5SDimitry Andricdef MEMri : Operand<i32> {
1900b57cec5SDimitry Andric  let DecoderMethod = "decodeRiMemoryValue";
1910b57cec5SDimitry Andric  let EncoderMethod = "getRiMemoryOpValue";
1920b57cec5SDimitry Andric  let MIOperandInfo = (ops GPR:$base, i32lo16s:$offset, AluOp:$Opcode);
1930b57cec5SDimitry Andric  let ParserMatchClass = MemRegImmAsmOperand;
1940b57cec5SDimitry Andric  let PrintMethod   = "printMemRiOperand";
1950b57cec5SDimitry Andric}
1960b57cec5SDimitry Andric
1970b57cec5SDimitry Andricdef MemRegRegAsmOperand : AsmOperandClass {
1980b57cec5SDimitry Andric  let Name = "MemRegReg";
1990b57cec5SDimitry Andric  let ParserMethod  = "parseMemoryOperand";
2000b57cec5SDimitry Andric}
2010b57cec5SDimitry Andricdef MEMrr : Operand<i32> {
2020b57cec5SDimitry Andric  let DecoderMethod = "decodeRrMemoryValue";
2030b57cec5SDimitry Andric  let EncoderMethod = "getRrMemoryOpValue";
2040b57cec5SDimitry Andric  let MIOperandInfo = (ops GPR:$Op1, GPR:$Op2, AluOp:$Opcode);
2050b57cec5SDimitry Andric  let ParserMatchClass = MemRegRegAsmOperand;
2060b57cec5SDimitry Andric  let PrintMethod   = "printMemRrOperand";
2070b57cec5SDimitry Andric}
2080b57cec5SDimitry Andric
2090b57cec5SDimitry Andricdef MemImmAsmOperand : AsmOperandClass {
2100b57cec5SDimitry Andric  let Name = "MemImm";
2110b57cec5SDimitry Andric  let ParserMethod  = "parseMemoryOperand";
2120b57cec5SDimitry Andric}
2130b57cec5SDimitry Andricdef MEMi : Operand<i32> {
2140b57cec5SDimitry Andric  let MIOperandInfo = (ops i32lo21:$offset);
2150b57cec5SDimitry Andric  let ParserMatchClass = MemImmAsmOperand;
2160b57cec5SDimitry Andric  let PrintMethod   = "printMemImmOperand";
2170b57cec5SDimitry Andric}
2180b57cec5SDimitry Andric
2190b57cec5SDimitry Andricdef MemSplsAsmOperand : AsmOperandClass {
2200b57cec5SDimitry Andric  let Name = "MemSpls";
2210b57cec5SDimitry Andric  let ParserMethod  = "parseMemoryOperand";
2220b57cec5SDimitry Andric}
2230b57cec5SDimitry Andricdef MEMspls : Operand<i32> {
2240b57cec5SDimitry Andric  let DecoderMethod = "decodeSplsValue";
2250b57cec5SDimitry Andric  let EncoderMethod = "getSplsOpValue";
2260b57cec5SDimitry Andric  let MIOperandInfo = (ops GPR:$base, imm10:$offset, AluOp:$Opcode);
2270b57cec5SDimitry Andric  let ParserMatchClass = MemSplsAsmOperand;
2280b57cec5SDimitry Andric  let PrintMethod   = "printMemSplsOperand";
2290b57cec5SDimitry Andric}
2300b57cec5SDimitry Andric
2310b57cec5SDimitry Andricdef CCOp : Operand<i32> {
2320b57cec5SDimitry Andric  let PrintMethod = "printCCOperand";
2330b57cec5SDimitry Andric}
2340b57cec5SDimitry Andric
2350b57cec5SDimitry Andric// Predicate operand. Default to 0 = true.
2360b57cec5SDimitry Andricdef CondCodeOperand : AsmOperandClass { let Name = "CondCode"; }
2370b57cec5SDimitry Andric
2380b57cec5SDimitry Andricdef pred : PredicateOperand<i32, (ops i32imm), (ops (i32 0))> {
2390b57cec5SDimitry Andric  let PrintMethod = "printPredicateOperand";
2400b57cec5SDimitry Andric  let ParserMatchClass = CondCodeOperand;
2410b57cec5SDimitry Andric  let DecoderMethod = "decodePredicateOperand";
2420b57cec5SDimitry Andric}
2430b57cec5SDimitry Andric
2440b57cec5SDimitry Andriclet hasSideEffects = 0, Inst = 0x00000001 in
2450b57cec5SDimitry Andric  def NOP : InstLanai<(outs), (ins), "nop", []>;
2460b57cec5SDimitry Andric
2470b57cec5SDimitry Andric// Special NOPs to change logging level in vlanai.
2480b57cec5SDimitry Andriclet hasSideEffects = 0, Inst = 0x00000002 in
2490b57cec5SDimitry Andric  def LOG0 : InstLanai<(outs), (ins), "log_0", []>;
2500b57cec5SDimitry Andriclet hasSideEffects = 0, Inst = 0x00000003 in
2510b57cec5SDimitry Andric  def LOG1 : InstLanai<(outs), (ins), "log_1", []>;
2520b57cec5SDimitry Andriclet hasSideEffects = 0, Inst = 0x00000004 in
2530b57cec5SDimitry Andric  def LOG2 : InstLanai<(outs), (ins), "log_2", []>;
2540b57cec5SDimitry Andriclet hasSideEffects = 0, Inst = 0x00000005 in
2550b57cec5SDimitry Andric  def LOG3 : InstLanai<(outs), (ins), "log_3", []>;
2560b57cec5SDimitry Andriclet hasSideEffects = 0, Inst = 0x00000006 in
2570b57cec5SDimitry Andric  def LOG4 : InstLanai<(outs), (ins), "log_4", []>;
2580b57cec5SDimitry Andric
2590b57cec5SDimitry Andric// Map an SPLS instruction onto itself. All other instructions will be mapped
2600b57cec5SDimitry Andric// onto -1. Used to identify SPLS instructions.
2610b57cec5SDimitry Andricdef splsIdempotent : InstrMapping {
2620b57cec5SDimitry Andric  let FilterClass = "InstSPLS";
2630b57cec5SDimitry Andric  let RowFields = ["AsmString"];
2640b57cec5SDimitry Andric  let ColFields = ["PostEncoderMethod"];
2650b57cec5SDimitry Andric  let KeyCol = ["adjustPqBitsSpls"];
2660b57cec5SDimitry Andric  let ValueCols = [["adjustPqBitsSpls"]];
2670b57cec5SDimitry Andric}
2680b57cec5SDimitry Andric
2690b57cec5SDimitry Andric// -------------------------------------------------- //
2700b57cec5SDimitry Andric// ALU instructions
2710b57cec5SDimitry Andric// -------------------------------------------------- //
272349cc55cSDimitry Andricmulticlass ALUbase<bits<3> subOp, string AsmStr,
2730b57cec5SDimitry Andric                   PatLeaf LoExt, PatLeaf HiExt,
2740b57cec5SDimitry Andric                   list<dag> loPattern, list<dag> hiPattern> {
2750b57cec5SDimitry Andric  // Register Immediate
2760b57cec5SDimitry Andric  let H = 0 in
2770b57cec5SDimitry Andric    def LO : InstRI<subOp, (outs GPR:$Rd), (ins GPR:$Rs1, LoExt:$imm16),
2780b57cec5SDimitry Andric                    !strconcat(AsmStr, "\t$Rs1, $imm16, $Rd"),
2790b57cec5SDimitry Andric                    loPattern>;
2800b57cec5SDimitry Andric  let H = 1 in
2810b57cec5SDimitry Andric    def HI : InstRI<subOp, (outs GPR:$Rd), (ins GPR:$Rs1, HiExt:$imm16),
2820b57cec5SDimitry Andric                    !strconcat(AsmStr, "\t$Rs1, $imm16, $Rd"),
2830b57cec5SDimitry Andric                    hiPattern>;
2840b57cec5SDimitry Andric
2850b57cec5SDimitry Andric}
2860b57cec5SDimitry Andric
2870b57cec5SDimitry Andricmulticlass ALUarith<bits<3> subOp, string AsmStr, SDNode OpNode,
2880b57cec5SDimitry Andric                    PatLeaf LoExt, PatLeaf HiExt> {
289349cc55cSDimitry Andric  defm I_ : ALUbase<subOp, AsmStr, LoExt, HiExt, [], []>;
2900b57cec5SDimitry Andric
2910b57cec5SDimitry Andric  // Register Register
2920b57cec5SDimitry Andric  let JJJJJ = 0 in
2930b57cec5SDimitry Andric    def R : InstRR<subOp, (outs GPR:$Rd), (ins GPR:$Rs1, GPR:$Rs2, pred:$DDDI),
2940b57cec5SDimitry Andric                   !strconcat(AsmStr, "$DDDI\t$Rs1, $Rs2, $Rd"),
2950b57cec5SDimitry Andric                   [(set GPR:$Rd, (OpNode GPR:$Rs1, GPR:$Rs2))]>;
2960b57cec5SDimitry Andric}
2970b57cec5SDimitry Andric
2980b57cec5SDimitry Andricmulticlass ALUlogic<bits<3> subOp, string AsmStr, SDNode OpNode,
2990b57cec5SDimitry Andric                    PatLeaf LoExt, PatLeaf HiExt> {
300349cc55cSDimitry Andric  defm I_ : ALUbase<subOp, AsmStr, LoExt, HiExt,
3010b57cec5SDimitry Andric                    [(set GPR:$Rd, (OpNode GPR:$Rs1, LoExt:$imm16))],
3020b57cec5SDimitry Andric                    [(set GPR:$Rd, (OpNode GPR:$Rs1, HiExt:$imm16))]>;
3030b57cec5SDimitry Andric
3040b57cec5SDimitry Andric  // Register Register
3050b57cec5SDimitry Andric  let JJJJJ = 0 in
3060b57cec5SDimitry Andric    def R : InstRR<subOp, (outs GPR:$Rd), (ins GPR:$Rs1, GPR:$Rs2, pred:$DDDI),
3070b57cec5SDimitry Andric                   !strconcat(AsmStr, "$DDDI\t$Rs1, $Rs2, $Rd"),
3080b57cec5SDimitry Andric                   [(set GPR:$Rd, (OpNode GPR:$Rs1, GPR:$Rs2))]>;
3090b57cec5SDimitry Andric}
3100b57cec5SDimitry Andric
3110b57cec5SDimitry Andric// Non flag setting ALU operations
3120b57cec5SDimitry Andriclet isAsCheapAsAMove = 1, F = 0 in {
3130b57cec5SDimitry Andric  let isCommutable = 1 in {
3140b57cec5SDimitry Andric    defm ADD_ : ALUarith<0b000, "add", add, i32lo16z, i32hi16>;
3150b57cec5SDimitry Andric  }
3160b57cec5SDimitry Andric  defm SUB_ : ALUarith<0b010,   "sub", sub, i32lo16z, i32hi16>;
3170b57cec5SDimitry Andric  let isCommutable = 1 in {
3180b57cec5SDimitry Andric    defm AND_ : ALUlogic<0b100, "and", and, i32lo16and, i32hi16and>;
3190b57cec5SDimitry Andric    defm OR_  : ALUlogic<0b101,  "or",  or, i32lo16z, i32hi16>;
3200b57cec5SDimitry Andric    defm XOR_ : ALUlogic<0b110, "xor", xor, i32lo16z, i32hi16>;
3210b57cec5SDimitry Andric  }
3220b57cec5SDimitry Andric}
3230b57cec5SDimitry Andric
3240b57cec5SDimitry Andricdef : Pat<(add GPR:$Rs1, i32lo16z:$imm),
3250b57cec5SDimitry Andric          (ADD_I_LO GPR:$Rs1, i32lo16z:$imm)>;
3260b57cec5SDimitry Andric
3270b57cec5SDimitry Andricdef : Pat<(sub GPR:$Rs1, i32lo16z:$imm),
3280b57cec5SDimitry Andric          (SUB_I_LO GPR:$Rs1, i32lo16z:$imm)>;
3290b57cec5SDimitry Andric
3300b57cec5SDimitry Andricdef : Pat<(add GPR:$Rs1, i32hi16:$imm),
3310b57cec5SDimitry Andric          (ADD_I_HI GPR:$Rs1, i32hi16:$imm)>;
3320b57cec5SDimitry Andric
3330b57cec5SDimitry Andricdef : Pat<(sub GPR:$Rs1, i32hi16:$imm),
3340b57cec5SDimitry Andric          (SUB_I_HI GPR:$Rs1, i32hi16:$imm)>;
3350b57cec5SDimitry Andric
3360b57cec5SDimitry Andricdef : Pat<(i32 i32lo16and:$imm), (AND_I_LO (i32 R1), i32lo16and:$imm)>;
3370b57cec5SDimitry Andricdef : Pat<(i32 i32hi16and:$imm), (AND_I_HI (i32 R1), i32hi16and:$imm)>;
3380b57cec5SDimitry Andric
3390b57cec5SDimitry Andric// Change add/sub with negative number to sub/add
3400b57cec5SDimitry Andricdef : Pat<(add GPR:$Rs1, i32neg16:$imm),
3410b57cec5SDimitry Andric          (SUB_I_LO GPR:$Rs1, (NEG $imm))>;
3420b57cec5SDimitry Andricdef : Pat<(sub GPR:$Rs1, i32neg16:$imm),
3430b57cec5SDimitry Andric          (ADD_I_LO GPR:$Rs1, (NEG $imm))>;
3440b57cec5SDimitry Andric
3450b57cec5SDimitry Andric// Flag (incl. carry) setting addition and subtraction
3460b57cec5SDimitry Andriclet F = 1, Defs = [SR] in {
3470b57cec5SDimitry Andric  defm ADD_F_ : ALUarith<0b000, "add.f", addc, i32lo16z, i32hi16>;
3480b57cec5SDimitry Andric  defm SUB_F_ : ALUarith<0b010, "sub.f", subc, i32lo16z, i32hi16>;
3490b57cec5SDimitry Andric}
3500b57cec5SDimitry Andric
3510b57cec5SDimitry Andricdef : Pat<(addc GPR:$Rs1, i32lo16z:$imm),
3520b57cec5SDimitry Andric          (ADD_F_I_LO GPR:$Rs1, i32lo16z:$imm)>;
3530b57cec5SDimitry Andric
3540b57cec5SDimitry Andricdef : Pat<(subc GPR:$Rs1, i32lo16z:$imm),
3550b57cec5SDimitry Andric          (SUB_F_I_LO GPR:$Rs1, i32lo16z:$imm)>;
3560b57cec5SDimitry Andric
3570b57cec5SDimitry Andricdef : Pat<(addc GPR:$Rs1, i32hi16:$imm),
3580b57cec5SDimitry Andric          (ADD_F_I_HI GPR:$Rs1, i32hi16:$imm)>;
3590b57cec5SDimitry Andric
3600b57cec5SDimitry Andricdef : Pat<(subc GPR:$Rs1, i32hi16:$imm),
3610b57cec5SDimitry Andric          (SUB_F_I_HI GPR:$Rs1, i32hi16:$imm)>;
3620b57cec5SDimitry Andric
3630b57cec5SDimitry Andric// Carry using addition and subtraction
3640b57cec5SDimitry Andriclet F = 0, Uses = [SR] in {
3650b57cec5SDimitry Andric  defm ADDC_ : ALUarith<0b001, "addc", adde, i32lo16z, i32hi16>;
3660b57cec5SDimitry Andric  defm SUBB_ : ALUarith<0b011, "subb", sube, i32lo16z, i32hi16>;
3670b57cec5SDimitry Andric}
3680b57cec5SDimitry Andric
3690b57cec5SDimitry Andricdef : Pat<(adde GPR:$Rs1, i32lo16z:$imm),
3700b57cec5SDimitry Andric          (ADDC_I_LO GPR:$Rs1, i32lo16z:$imm)>;
3710b57cec5SDimitry Andric
3720b57cec5SDimitry Andricdef : Pat<(sube GPR:$Rs1, i32lo16z:$imm),
3730b57cec5SDimitry Andric          (SUBB_I_LO GPR:$Rs1, i32lo16z:$imm)>;
3740b57cec5SDimitry Andric
3750b57cec5SDimitry Andricdef : Pat<(adde GPR:$Rs1, i32hi16:$imm),
3760b57cec5SDimitry Andric          (ADDC_I_HI GPR:$Rs1, i32hi16:$imm)>;
3770b57cec5SDimitry Andric
3780b57cec5SDimitry Andricdef : Pat<(sube GPR:$Rs1, i32hi16:$imm),
3790b57cec5SDimitry Andric          (SUBB_I_HI GPR:$Rs1, i32hi16:$imm)>;
3800b57cec5SDimitry Andric
3810b57cec5SDimitry Andric// Flag setting ALU operations
3820b57cec5SDimitry Andriclet isAsCheapAsAMove = 1, F = 1, Defs = [SR] in {
3830b57cec5SDimitry Andric  let isCommutable = 1 in {
3840b57cec5SDimitry Andric    defm AND_F_ : ALUlogic<0b100, "and.f",  and, i32lo16and, i32hi16and>;
3850b57cec5SDimitry Andric    defm OR_F_  : ALUlogic<0b101,  "or.f",   or, i32lo16z, i32hi16>;
3860b57cec5SDimitry Andric    defm XOR_F_ : ALUlogic<0b110, "xor.f",  xor, i32lo16z, i32hi16>;
3870b57cec5SDimitry Andric  }
3880b57cec5SDimitry Andric}
3890b57cec5SDimitry Andric
3900b57cec5SDimitry Andriclet isAsCheapAsAMove = 1, F = 1, Defs = [SR], Uses = [SR] in {
3910b57cec5SDimitry Andric  defm ADDC_F_ : ALUarith<0b001, "addc.f", adde, i32lo16z, i32hi16>;
3920b57cec5SDimitry Andric  defm SUBB_F_ : ALUarith<0b011, "subb.f", sube, i32lo16z, i32hi16>;
3930b57cec5SDimitry Andric}
3940b57cec5SDimitry Andric
3950b57cec5SDimitry Andricdef : Pat<(LanaiSubbF GPR:$Rs1, GPR:$Rs2),
3960b57cec5SDimitry Andric          (SUBB_F_R GPR:$Rs1, GPR:$Rs2)>;
3970b57cec5SDimitry Andric
3980b57cec5SDimitry Andricdef : Pat<(LanaiSubbF GPR:$Rs1, i32lo16z:$imm),
3990b57cec5SDimitry Andric          (SUBB_F_I_LO GPR:$Rs1, i32lo16z:$imm)>;
4000b57cec5SDimitry Andric
4010b57cec5SDimitry Andricdef : Pat<(LanaiSubbF GPR:$Rs1, i32hi16:$imm),
4020b57cec5SDimitry Andric          (SUBB_F_I_HI GPR:$Rs1, i32hi16:$imm)>;
4030b57cec5SDimitry Andric
4040b57cec5SDimitry Andricdef : InstAlias<"mov $src, $dst", (ADD_R GPR:$dst, GPR:$src, R0, 0)>;
4050b57cec5SDimitry Andric
4060b57cec5SDimitry Andriclet isAsCheapAsAMove = 1, Rs1 = R0.Num, isCodeGenOnly = 1, H = 1, F = 0,
4070b57cec5SDimitry Andric  isReMaterializable = 1 in
4080b57cec5SDimitry Andric  def MOVHI : InstRI<0b000, (outs GPR:$Rd), (ins i32hi16:$imm16),
4090b57cec5SDimitry Andric                     "mov\t$imm16, $Rd",
4100b57cec5SDimitry Andric                     [(set GPR:$Rd, i32hi16:$imm16)]>;
4110b57cec5SDimitry Andric
4120b57cec5SDimitry Andricdef : InstAlias<"mov $imm16, $dst", (ADD_I_LO GPR:$dst, R0, i32lo16z:$imm16)>;
4130b57cec5SDimitry Andricdef : InstAlias<"mov $imm16, $dst", (ADD_I_HI GPR:$dst, R0, i32hi16:$imm16)>;
4140b57cec5SDimitry Andricdef : InstAlias<"mov $imm16, $dst",
4150b57cec5SDimitry Andric                (AND_I_LO GPR:$dst, R1, i32lo16and:$imm16)>;
4160b57cec5SDimitry Andricdef : InstAlias<"mov $imm16, $dst",
4170b57cec5SDimitry Andric                (AND_I_HI GPR:$dst, R1, i32hi16and:$imm16)>;
4180b57cec5SDimitry Andric
4190b57cec5SDimitry Andric// Shift instructions
4200b57cec5SDimitry Andricclass ShiftRI<string AsmStr, list<dag> Pattern>
4210b57cec5SDimitry Andric  : InstRI<0b111, (outs GPR:$Rd), (ins GPR:$Rs1, immShift:$imm16),
4220b57cec5SDimitry Andric           !strconcat(AsmStr, "\t$Rs1, $imm16, $Rd"), Pattern> {
4230b57cec5SDimitry Andric  let isReMaterializable = 1;
4240b57cec5SDimitry Andric}
4250b57cec5SDimitry Andric
4260b57cec5SDimitry Andriclet F = 0 in {
4270b57cec5SDimitry Andric  let H = 0 in
4280b57cec5SDimitry Andric    def SL_I : ShiftRI<"sh", [(set GPR:$Rd, (shl GPR:$Rs1, immShift:$imm16))]>;
4290b57cec5SDimitry Andric  let H = 1 in
4300b57cec5SDimitry Andric    def SA_I : ShiftRI<"sha", []>;
4310b57cec5SDimitry Andric}
4320b57cec5SDimitry Andricdef : Pat<(srl GPR:$Rs1, immShift:$imm), (SL_I GPR:$Rs1, (NEG $imm))>;
4330b57cec5SDimitry Andricdef : Pat<(sra GPR:$Rs1, immShift:$imm), (SA_I GPR:$Rs1, (NEG $imm))>;
4340b57cec5SDimitry Andric
4350b57cec5SDimitry Andriclet F = 1, Defs = [SR] in {
4360b57cec5SDimitry Andric  let H = 0 in
4370b57cec5SDimitry Andric    def SL_F_I : ShiftRI<"sh.f", []>;
4380b57cec5SDimitry Andric  let H = 1 in
4390b57cec5SDimitry Andric    def SA_F_I : ShiftRI<"sha.f", []>;
4400b57cec5SDimitry Andric}
4410b57cec5SDimitry Andric
4420b57cec5SDimitry Andricclass ShiftRR<string AsmStr, list<dag> Pattern>
4430b57cec5SDimitry Andric  : InstRR<0b111, (outs GPR:$Rd), (ins GPR:$Rs1, GPR:$Rs2, pred:$DDDI), AsmStr,
4440b57cec5SDimitry Andric           Pattern>;
4450b57cec5SDimitry Andric
4460b57cec5SDimitry Andriclet F = 0 in {
4470b57cec5SDimitry Andric  let JJJJJ = 0b10000 in
4480b57cec5SDimitry Andric    def SHL_R : ShiftRR<"sh$DDDI\t$Rs1, $Rs2, $Rd",
4490b57cec5SDimitry Andric                        [(set GPR:$Rd, (shl GPR:$Rs1, GPR:$Rs2))]>;
4500b57cec5SDimitry Andric  let isCodeGenOnly = 1 in {
4510b57cec5SDimitry Andric    let JJJJJ = 0b10000 in
4520b57cec5SDimitry Andric      def SRL_R : ShiftRR<"sh$DDDI\t$Rs1, $Rs2, $Rd", []>;
4530b57cec5SDimitry Andric  }
4540b57cec5SDimitry Andric  let JJJJJ = 0b11000 in
4550b57cec5SDimitry Andric    def SRA_R : ShiftRR<"sha$DDDI\t$Rs1, $Rs2, $Rd", []>;
4560b57cec5SDimitry Andric}
4570b57cec5SDimitry Andric
4580b57cec5SDimitry Andriclet F = 1, Defs = [SR] in {
4590b57cec5SDimitry Andric  let JJJJJ = 0b10000 in
4600b57cec5SDimitry Andric    def SHL_F_R : ShiftRR<"sh.f$DDDI\t$Rs1, $Rs2, $Rd", []>;
4610b57cec5SDimitry Andric  let isCodeGenOnly = 1 in {
4620b57cec5SDimitry Andric    let JJJJJ = 0b10000 in
4630b57cec5SDimitry Andric      def SRL_F_R : ShiftRR<"sh.f$DDDI\t$Rs1, $Rs2, $Rd", []>;
4640b57cec5SDimitry Andric  }
4650b57cec5SDimitry Andric  let JJJJJ = 0b11000 in
4660b57cec5SDimitry Andric    def SRA_F_R : ShiftRR<"sha.f$DDDI\t$Rs1, $Rs2, $Rd", []>;
4670b57cec5SDimitry Andric}
4680b57cec5SDimitry Andric
4690b57cec5SDimitry Andric// Expand shift-right operations
4700b57cec5SDimitry Andricdef : Pat<(srl GPR:$Rs1, GPR:$Rs2),
4710b57cec5SDimitry Andric          (SRL_R GPR:$Rs1, (SUB_R R0, GPR:$Rs2))>;
4720b57cec5SDimitry Andricdef : Pat<(sra GPR:$Rs1, GPR:$Rs2),
4730b57cec5SDimitry Andric          (SRA_R GPR:$Rs1, (SUB_R R0, GPR:$Rs2))>;
4740b57cec5SDimitry Andric
4750b57cec5SDimitry Andric// -------------------------------------------------- //
4760b57cec5SDimitry Andric// LOAD instructions
4770b57cec5SDimitry Andric// -------------------------------------------------- //
4780b57cec5SDimitry Andric
4790b57cec5SDimitry Andricclass LoadRR<string OpcString, PatFrag OpNode, ValueType Ty>
4800b57cec5SDimitry Andric  : InstRRM<0b0, (outs GPR:$Rd), (ins MEMrr:$src),
4810b57cec5SDimitry Andric            !strconcat(OpcString, "\t$src, $Rd"),
4820b57cec5SDimitry Andric            [(set (Ty GPR:$Rd), (OpNode ADDRrr:$src))]>,
4830b57cec5SDimitry Andric    Sched<[WriteLD]> {
4840b57cec5SDimitry Andric  bits<20> src;
4850b57cec5SDimitry Andric
4860b57cec5SDimitry Andric  let Rs1 = src{19-15};
4870b57cec5SDimitry Andric  let Rs2 = src{14-10};
4880b57cec5SDimitry Andric  let P = src{9};
4890b57cec5SDimitry Andric  let Q = src{8};
4900b57cec5SDimitry Andric  let BBB = src{7-5};
4910b57cec5SDimitry Andric  let JJJJJ = src{4-0};
4920b57cec5SDimitry Andric  let mayLoad = 1;
4930b57cec5SDimitry Andric}
4940b57cec5SDimitry Andric
4950b57cec5SDimitry Andricclass LoadRI<string OpcString, PatFrag OpNode, ValueType Ty>
4960b57cec5SDimitry Andric  : InstRM<0b0, (outs GPR:$Rd), (ins MEMri:$src),
4970b57cec5SDimitry Andric           !strconcat(OpcString, "\t$src, $Rd"),
4980b57cec5SDimitry Andric           [(set (Ty GPR:$Rd), (OpNode ADDRri:$src))]>,
4990b57cec5SDimitry Andric    Sched<[WriteLD]> {
5000b57cec5SDimitry Andric  bits<23> src;
5010b57cec5SDimitry Andric
5020b57cec5SDimitry Andric  let Itinerary = IIC_LD;
5030b57cec5SDimitry Andric  let Rs1 = src{22-18};
5040b57cec5SDimitry Andric  let P = src{17};
5050b57cec5SDimitry Andric  let Q = src{16};
5060b57cec5SDimitry Andric  let imm16 = src{15-0};
5070b57cec5SDimitry Andric  let isReMaterializable = 1;
5080b57cec5SDimitry Andric  let mayLoad = 1;
5090b57cec5SDimitry Andric}
5100b57cec5SDimitry Andric
5110b57cec5SDimitry Andriclet E = 0 in {
5120b57cec5SDimitry Andric  let YL = 0b01 in {
5130b57cec5SDimitry Andric    // uld is used here and ld in the alias as the alias is printed out first if
5140b57cec5SDimitry Andric    // an alias exist
5150b57cec5SDimitry Andric    def LDW_RI : LoadRI<"uld", load, i32>;
5160b57cec5SDimitry Andric    def LDW_RR : LoadRR<"ld", load, i32>;
5170b57cec5SDimitry Andric  }
5180b57cec5SDimitry Andric}
5190b57cec5SDimitry Andric
5200b57cec5SDimitry Andricdef : InstAlias<"ld $src, $dst", (LDW_RI GPR:$dst, MEMri:$src)>;
5210b57cec5SDimitry Andric
5220b57cec5SDimitry Andriclet E = 1 in {
5230b57cec5SDimitry Andric  let YL = 0b01 in {
5240b57cec5SDimitry Andric    def LDWz_RR : LoadRR<"uld", zextloadi32, i32>;
5250b57cec5SDimitry Andric  }
5260b57cec5SDimitry Andric}
5270b57cec5SDimitry Andric
5280b57cec5SDimitry Andriclet E = 1 in {
5290b57cec5SDimitry Andric  let YL = 0b00 in
5300b57cec5SDimitry Andric    def LDHz_RR : LoadRR<"uld.h", zextloadi16, i32>;
5310b57cec5SDimitry Andric  let YL = 0b10 in
5320b57cec5SDimitry Andric    def LDBz_RR : LoadRR<"uld.b", zextloadi8, i32>;
5330b57cec5SDimitry Andric}
5340b57cec5SDimitry Andric
5350b57cec5SDimitry Andriclet E = 0 in {
5360b57cec5SDimitry Andric  let YL = 0b00 in
5370b57cec5SDimitry Andric    def LDHs_RR : LoadRR<"ld.h", sextloadi16, i32>;
5380b57cec5SDimitry Andric  let YL = 0b10 in
5390b57cec5SDimitry Andric    def LDBs_RR : LoadRR<"ld.b", sextloadi8, i32>;
5400b57cec5SDimitry Andric}
5410b57cec5SDimitry Andric
5420b57cec5SDimitry Andricdef LDADDR : InstSLS<0x0, (outs GPR:$Rd), (ins MEMi:$src),
5430b57cec5SDimitry Andric                     "ld\t$src, $Rd",
5440b57cec5SDimitry Andric                     [(set (i32 GPR:$Rd), (load ADDRsls:$src))]>,
5450b57cec5SDimitry Andric    Sched<[WriteLD]> {
5460b57cec5SDimitry Andric  bits<21> src;
5470b57cec5SDimitry Andric
5480b57cec5SDimitry Andric  let Itinerary = IIC_LD;
5490b57cec5SDimitry Andric  let msb = src{20-16};
5500b57cec5SDimitry Andric  let lsb = src{15-0};
5510b57cec5SDimitry Andric  let isReMaterializable = 1;
5520b57cec5SDimitry Andric  let mayLoad = 1;
5530b57cec5SDimitry Andric}
5540b57cec5SDimitry Andric
5550b57cec5SDimitry Andricclass LoadSPLS<string asmstring, PatFrag opNode>
5560b57cec5SDimitry Andric  : InstSPLS<(outs GPR:$Rd), (ins MEMspls:$src),
5570b57cec5SDimitry Andric             !strconcat(asmstring, "\t$src, $Rd"),
5580b57cec5SDimitry Andric             [(set (i32 GPR:$Rd), (opNode ADDRspls:$src))]>,
5590b57cec5SDimitry Andric    Sched<[WriteLDSW]> {
5600b57cec5SDimitry Andric  bits<17> src;
5610b57cec5SDimitry Andric  let Itinerary = IIC_LDSW;
5620b57cec5SDimitry Andric  let Rs1 = src{16-12};
5630b57cec5SDimitry Andric  let P = src{11};
5640b57cec5SDimitry Andric  let Q = src{10};
5650b57cec5SDimitry Andric  let imm10 = src{9-0};
5660b57cec5SDimitry Andric  let mayLoad = 1;
5670b57cec5SDimitry Andric  let isReMaterializable = 1;
5680b57cec5SDimitry Andric}
5690b57cec5SDimitry Andric
5700b57cec5SDimitry Andriclet Y = 0, S = 0, E = 1 in
5710b57cec5SDimitry Andric  def LDHz_RI : LoadSPLS<"uld.h", zextloadi16>;
5720b57cec5SDimitry Andric
5730b57cec5SDimitry Andriclet Y = 0, S = 0, E = 0 in
5740b57cec5SDimitry Andric  def LDHs_RI : LoadSPLS<"ld.h", sextloadi16>;
5750b57cec5SDimitry Andric
5760b57cec5SDimitry Andriclet Y = 1, S = 0, E = 1 in
5770b57cec5SDimitry Andric  def LDBz_RI : LoadSPLS<"uld.b", zextloadi8>;
5780b57cec5SDimitry Andric
5790b57cec5SDimitry Andriclet Y = 1, S = 0, E = 0 in
5800b57cec5SDimitry Andric  def LDBs_RI : LoadSPLS<"ld.b", sextloadi8>;
5810b57cec5SDimitry Andric
5820b57cec5SDimitry Andricdef SLI : InstSLI<(outs GPR:$Rd), (ins i32lo21:$imm),
5830b57cec5SDimitry Andric                  "mov\t$imm, $Rd",
5840b57cec5SDimitry Andric                  [(set GPR:$Rd, i32lo21:$imm)]> {
5850b57cec5SDimitry Andric  bits<21> imm;
5860b57cec5SDimitry Andric
5870b57cec5SDimitry Andric  let msb = imm{20-16};
5880b57cec5SDimitry Andric  let lsb = imm{15-0};
5890b57cec5SDimitry Andric  let isReMaterializable = 1;
5900b57cec5SDimitry Andric  let isAsCheapAsAMove = 1;
5910b57cec5SDimitry Andric}
5920b57cec5SDimitry Andric
5930b57cec5SDimitry Andric// -------------------------------------------------- //
5940b57cec5SDimitry Andric// STORE instructions
5950b57cec5SDimitry Andric// -------------------------------------------------- //
5960b57cec5SDimitry Andric
5970b57cec5SDimitry Andricclass StoreRR<string OpcString, PatFrag OpNode, ValueType Ty>
5980b57cec5SDimitry Andric  : InstRRM<0b1, (outs), (ins GPR:$Rd, MEMrr:$dst),
5990b57cec5SDimitry Andric            !strconcat(OpcString, "\t$Rd, $dst"),
6000b57cec5SDimitry Andric            [(OpNode (Ty GPR:$Rd), ADDRrr:$dst)]>,
6010b57cec5SDimitry Andric    Sched<[WriteST]> {
6020b57cec5SDimitry Andric  bits<20> dst;
6030b57cec5SDimitry Andric
6040b57cec5SDimitry Andric  let Itinerary = IIC_ST;
6050b57cec5SDimitry Andric  let Rs1 = dst{19-15};
6060b57cec5SDimitry Andric  let Rs2 = dst{14-10};
6070b57cec5SDimitry Andric  let P = dst{9};
6080b57cec5SDimitry Andric  let Q = dst{8};
6090b57cec5SDimitry Andric  let BBB = dst{7-5};
6100b57cec5SDimitry Andric  let JJJJJ = dst{4-0};
6110b57cec5SDimitry Andric  let mayStore = 1;
6120b57cec5SDimitry Andric}
6130b57cec5SDimitry Andric
6140b57cec5SDimitry Andricclass StoreRI<string OpcString, PatFrag OpNode, ValueType Ty>
6150b57cec5SDimitry Andric  : InstRM<0b1, (outs), (ins GPR:$Rd, MEMri:$dst),
6160b57cec5SDimitry Andric           !strconcat(OpcString, "\t$Rd, $dst"),
6170b57cec5SDimitry Andric           [(OpNode (Ty GPR:$Rd), ADDRri:$dst)]>,
6180b57cec5SDimitry Andric    Sched<[WriteST]> {
6190b57cec5SDimitry Andric  bits<23> dst;
6200b57cec5SDimitry Andric
6210b57cec5SDimitry Andric  let Itinerary = IIC_ST;
6220b57cec5SDimitry Andric  let Rs1 = dst{22-18};
6230b57cec5SDimitry Andric  let P = dst{17};
6240b57cec5SDimitry Andric  let Q = dst{16};
6250b57cec5SDimitry Andric  let imm16 = dst{15-0};
6260b57cec5SDimitry Andric  let mayStore = 1;
6270b57cec5SDimitry Andric}
6280b57cec5SDimitry Andric
6290b57cec5SDimitry Andriclet YL = 0b01, E = 0 in {
6300b57cec5SDimitry Andric  def SW_RR : StoreRR<"st", store, i32>;
6310b57cec5SDimitry Andric  def SW_RI : StoreRI<"st", store, i32>;
6320b57cec5SDimitry Andric}
6330b57cec5SDimitry Andric
6340b57cec5SDimitry Andriclet E = 0 in {
6350b57cec5SDimitry Andric  let YL = 0b00 in
6360b57cec5SDimitry Andric    def STH_RR : StoreRR<"st.h", truncstorei16, i32>;
6370b57cec5SDimitry Andric  let YL = 0b10 in
6380b57cec5SDimitry Andric    def STB_RR : StoreRR<"st.b", truncstorei8, i32>;
6390b57cec5SDimitry Andric}
6400b57cec5SDimitry Andric
6410b57cec5SDimitry Andricdef STADDR : InstSLS<0x1, (outs), (ins GPR:$Rd, MEMi:$dst),
6420b57cec5SDimitry Andric                     "st\t$Rd, $dst",
6430b57cec5SDimitry Andric                     [(store (i32 GPR:$Rd), ADDRsls:$dst)]>,
6440b57cec5SDimitry Andric    Sched<[WriteST]> {
6450b57cec5SDimitry Andric  bits<21> dst;
6460b57cec5SDimitry Andric
6470b57cec5SDimitry Andric  let Itinerary = IIC_ST;
6480b57cec5SDimitry Andric  let msb = dst{20-16};
6490b57cec5SDimitry Andric  let lsb = dst{15-0};
6500b57cec5SDimitry Andric  let mayStore = 1;
6510b57cec5SDimitry Andric}
6520b57cec5SDimitry Andric
6530b57cec5SDimitry Andricclass StoreSPLS<string asmstring, PatFrag opNode>
6540b57cec5SDimitry Andric  : InstSPLS<(outs), (ins GPR:$Rd, MEMspls:$dst),
6550b57cec5SDimitry Andric             !strconcat(asmstring, "\t$Rd, $dst"),
6560b57cec5SDimitry Andric             [(opNode (i32 GPR:$Rd), ADDRspls:$dst)]>,
6570b57cec5SDimitry Andric    Sched<[WriteSTSW]> {
6580b57cec5SDimitry Andric  bits<17> dst;
6590b57cec5SDimitry Andric
6600b57cec5SDimitry Andric  let Itinerary = IIC_STSW;
6610b57cec5SDimitry Andric  let Rs1 = dst{16-12};
6620b57cec5SDimitry Andric  let P = dst{11};
6630b57cec5SDimitry Andric  let Q = dst{10};
6640b57cec5SDimitry Andric  let imm10 = dst{9-0};
6650b57cec5SDimitry Andric  let mayStore = 1;
6660b57cec5SDimitry Andric}
6670b57cec5SDimitry Andric
6680b57cec5SDimitry Andriclet Y = 0, S = 1, E = 0 in
6690b57cec5SDimitry Andric  def STH_RI : StoreSPLS<"st.h", truncstorei16>;
6700b57cec5SDimitry Andric
6710b57cec5SDimitry Andriclet Y = 1, S = 1, E = 0 in
6720b57cec5SDimitry Andric  def STB_RI : StoreSPLS<"st.b", truncstorei8>;
6730b57cec5SDimitry Andric
6740b57cec5SDimitry Andric// -------------------------------------------------- //
6750b57cec5SDimitry Andric// BRANCH instructions
6760b57cec5SDimitry Andric// -------------------------------------------------- //
6770b57cec5SDimitry Andric
6780b57cec5SDimitry Andriclet isBranch = 1, isBarrier = 1, isTerminator = 1, hasDelaySlot = 1 in {
6790b57cec5SDimitry Andric  def BT : InstBR<(outs), (ins BrTarget:$addr),
6800b57cec5SDimitry Andric                  "bt\t$addr",
6810b57cec5SDimitry Andric                  [(br bb:$addr)]> {
6820b57cec5SDimitry Andric    let DDDI = 0b0000;
6830b57cec5SDimitry Andric  }
6840b57cec5SDimitry Andric  let Uses = [SR] in
6850b57cec5SDimitry Andric    def BRCC : InstBR<(outs), (ins BrTarget:$addr, CCOp:$DDDI),
6860b57cec5SDimitry Andric                      "b$DDDI\t$addr",
6870b57cec5SDimitry Andric                      [(LanaiBrCC bb:$addr, imm:$DDDI)]>;
6880b57cec5SDimitry Andric
6890b57cec5SDimitry Andric  let isIndirectBranch = 1 in {
6900b57cec5SDimitry Andric    def JR : InstRR<0b101, (outs), (ins GPR:$Rs2), "bt\t$Rs2",
6910b57cec5SDimitry Andric                    [(brind GPR:$Rs2)]> {
6920b57cec5SDimitry Andric      let Rs1 = R0.Num;
6930b57cec5SDimitry Andric      let Rd = R2.Num;
6940b57cec5SDimitry Andric      let F = 0;
6950b57cec5SDimitry Andric      let JJJJJ = 0;
6960b57cec5SDimitry Andric      let DDDI = 0;
6970b57cec5SDimitry Andric    }
6980b57cec5SDimitry Andric  }
6990b57cec5SDimitry Andric}
7000b57cec5SDimitry Andric
7010b57cec5SDimitry Andric// -------------------------------------------------- //
7020b57cec5SDimitry Andric// Condition/SF instructions
7030b57cec5SDimitry Andric// -------------------------------------------------- //
7040b57cec5SDimitry Andric
7050b57cec5SDimitry Andric// Instructions to set flags used in lowering comparisons.
7060b57cec5SDimitry Andricmulticlass SF<bits<3> op2Val, string AsmStr> {
7070b57cec5SDimitry Andric  let F = 1, Rd = R0.Num, JJJJJ = 0, Defs = [SR], DDDI = 0 in
7080b57cec5SDimitry Andric    def _RR : InstRR<op2Val, (outs), (ins GPR:$Rs1, GPR:$Rs2),
7090b57cec5SDimitry Andric                     !strconcat(AsmStr, "\t$Rs1, $Rs2, %r0"),
7100b57cec5SDimitry Andric                     [(LanaiSetFlag (i32 GPR:$Rs1), (i32 GPR:$Rs2))]>;
7110b57cec5SDimitry Andric  let F = 1, Rd = R0.Num, H = 0, Defs = [SR] in
7120b57cec5SDimitry Andric    def _RI_LO : InstRI<op2Val, (outs), (ins GPR:$Rs1, i32lo16z:$imm16),
7130b57cec5SDimitry Andric                     !strconcat(AsmStr, "\t$Rs1, $imm16, %r0"),
7140b57cec5SDimitry Andric                     [(LanaiSetFlag (i32 GPR:$Rs1), i32lo16z:$imm16)]>;
7150b57cec5SDimitry Andric  let F = 1, Rd = R0.Num, H = 1, Defs = [SR] in
7160b57cec5SDimitry Andric    def _RI_HI : InstRI<op2Val, (outs), (ins GPR:$Rs1, i32hi16:$imm16),
7170b57cec5SDimitry Andric                     !strconcat(AsmStr, "\t$Rs1, $imm16, %r0"),
7180b57cec5SDimitry Andric                     [(LanaiSetFlag (i32 GPR:$Rs1), i32hi16:$imm16)]>;
7190b57cec5SDimitry Andric}
7200b57cec5SDimitry Andriclet isCodeGenOnly = 1, isCompare = 1 in {
7210b57cec5SDimitry Andric  defm SFSUB_F : SF<0b010, "sub.f">;
7220b57cec5SDimitry Andric}
7230b57cec5SDimitry Andric
7240b57cec5SDimitry Andric// Jump and link
7250b57cec5SDimitry Andriclet isCall = 1, hasDelaySlot = 1, isCodeGenOnly = 1, Uses = [SP],
7260b57cec5SDimitry Andric    Defs = [RCA] in {
7270b57cec5SDimitry Andric  def CALL : Pseudo<(outs), (ins CallTarget:$addr), "", []>;
7280b57cec5SDimitry Andric  def CALLR : Pseudo<(outs), (ins GPR:$Rs1), "", [(Call GPR:$Rs1)]>;
7290b57cec5SDimitry Andric}
7300b57cec5SDimitry Andric
7310b57cec5SDimitry Andriclet isReturn = 1, isTerminator = 1, hasDelaySlot = 1, isBarrier = 1,
7320b57cec5SDimitry Andric    Uses = [RCA] in {
7330b57cec5SDimitry Andric  def RET : InstRM<0b0, (outs), (ins),
7340b57cec5SDimitry Andric                   "ld\t-4[%fp], %pc ! return",
735*06c3fb27SDimitry Andric                   [(RetGlue)]> {
7360b57cec5SDimitry Andric    let Rd = PC.Num;
7370b57cec5SDimitry Andric    let Rs1 = FP.Num;
7380b57cec5SDimitry Andric    let P = 1;
7390b57cec5SDimitry Andric    let Q = 0;
7400b57cec5SDimitry Andric    let imm16 = -4;
7410b57cec5SDimitry Andric
7420b57cec5SDimitry Andric    // Post encoding is not needed for RET.
7430b57cec5SDimitry Andric    let PostEncoderMethod = "";
7440b57cec5SDimitry Andric  }
7450b57cec5SDimitry Andric}
7460b57cec5SDimitry Andric
7470b57cec5SDimitry Andric// ADJCALLSTACKDOWN/UP implicitly use/def SP because they may be expanded into
7480b57cec5SDimitry Andric// a stack adjustment and the codegen must know that they may modify the stack
7490b57cec5SDimitry Andric// pointer before prolog-epilog rewriting occurs.
7500b57cec5SDimitry Andric// Pessimistically assume ADJCALLSTACKDOWN / ADJCALLSTACKUP will become
7510b57cec5SDimitry Andric// sub / add which can clobber SP.
7520b57cec5SDimitry Andriclet Defs = [SP], Uses = [SP] in {
7530b57cec5SDimitry Andric  def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
7540b57cec5SDimitry Andric                                "#ADJCALLSTACKDOWN $amt1 $amt2",
7550b57cec5SDimitry Andric                                [(CallSeqStart timm:$amt1, timm:$amt2)]>;
7560b57cec5SDimitry Andric  def ADJCALLSTACKUP   : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
7570b57cec5SDimitry Andric                                "#ADJCALLSTACKUP $amt1 $amt2",
7580b57cec5SDimitry Andric                                [(CallSeqEnd timm:$amt1, timm:$amt2)]>;
7590b57cec5SDimitry Andric}
7600b57cec5SDimitry Andric
7610b57cec5SDimitry Andriclet Defs = [SP], Uses = [SP] in {
7620b57cec5SDimitry Andric  def ADJDYNALLOC : Pseudo<(outs GPR:$dst), (ins GPR:$src),
7630b57cec5SDimitry Andric                           "#ADJDYNALLOC $dst $src",
7640b57cec5SDimitry Andric                           [(set GPR:$dst, (LanaiAdjDynAlloc GPR:$src))]>;
7650b57cec5SDimitry Andric}
7660b57cec5SDimitry Andric
7670b57cec5SDimitry Andriclet Uses = [SR] in {
7680b57cec5SDimitry Andric  def SCC : InstSCC<(outs GPR:$Rs1), (ins CCOp:$DDDI),
7690b57cec5SDimitry Andric                    "s$DDDI\t$Rs1",
7700b57cec5SDimitry Andric                    [(set (i32 GPR:$Rs1), (LanaiSetCC imm:$DDDI))]>;
7710b57cec5SDimitry Andric}
7720b57cec5SDimitry Andric
7730b57cec5SDimitry Andric// Select with hardware support
7740b57cec5SDimitry Andriclet Uses = [SR], isSelect = 1 in {
7750b57cec5SDimitry Andric  def SELECT : InstRR<0b111, (outs GPR:$Rd),
7760b57cec5SDimitry Andric                      (ins GPR:$Rs1, GPR:$Rs2, CCOp:$DDDI),
7770b57cec5SDimitry Andric                      "sel.$DDDI $Rs1, $Rs2, $Rd",
7780b57cec5SDimitry Andric                      [(set (i32 GPR:$Rd),
7790b57cec5SDimitry Andric                       (LanaiSelectCC (i32 GPR:$Rs1), (i32 GPR:$Rs2),
7800b57cec5SDimitry Andric                                      (imm:$DDDI)))]> {
7810b57cec5SDimitry Andric    let JJJJJ = 0;
7820b57cec5SDimitry Andric    let F = 0;
7830b57cec5SDimitry Andric  }
7840b57cec5SDimitry Andric}
7850b57cec5SDimitry Andric
7860b57cec5SDimitry Andriclet isBranch = 1, isBarrier = 1, isTerminator = 1, hasDelaySlot = 1,
7870b57cec5SDimitry Andric    isIndirectBranch = 1, Uses = [SR] in {
7880b57cec5SDimitry Andric  def BRIND_CC : InstRR<0b101, (outs), (ins GPR:$Rs1, CCOp:$DDDI),
7890b57cec5SDimitry Andric                        "b$DDDI\t$Rs1", []> {
7900b57cec5SDimitry Andric    let F = 0;
7910b57cec5SDimitry Andric    let JJJJJ = 0;
7920b57cec5SDimitry Andric    let Rd = PC.Num;
7930b57cec5SDimitry Andric    let Rs2 = R0.Num;
7940b57cec5SDimitry Andric  }
7950b57cec5SDimitry Andric
7960b57cec5SDimitry Andric  def BRIND_CCA : InstRR<0b101, (outs), (ins GPR:$Rs1, GPR:$Rs2, CCOp:$DDDI),
7970b57cec5SDimitry Andric                         "b${DDDI}\t$Rs1 add $Rs2", []> {
7980b57cec5SDimitry Andric    let F = 0;
7990b57cec5SDimitry Andric    let Rd = PC.Num;
8000b57cec5SDimitry Andric    let JJJJJ = 0;
8010b57cec5SDimitry Andric  }
8020b57cec5SDimitry Andric}
8030b57cec5SDimitry Andric
8040b57cec5SDimitry Andric// TODO: This only considers the case where BROFF is an immediate and not where
8050b57cec5SDimitry Andric// it is a register. Add support for register relative branching.
8060b57cec5SDimitry Andriclet isBranch = 1, isBarrier = 1, isTerminator = 1, hasDelaySlot = 1, Rs1 = 0,
8070b57cec5SDimitry Andric    Uses = [SR] in
8080b57cec5SDimitry Andric  def BRR : InstBRR<(outs), (ins i16imm:$imm16, CCOp:$DDDI),
8090b57cec5SDimitry Andric                    "b${DDDI}.r\t$imm16", []>;
8100b57cec5SDimitry Andric
8110b57cec5SDimitry Andriclet F = 0 in {
8120b57cec5SDimitry Andric// Population Count (POPC)
8130b57cec5SDimitry Andricdef POPC: InstSpecial<0b001, (outs GPR:$Rd), (ins GPR:$Rs1),
8140b57cec5SDimitry Andric                      "popc\t$Rs1, $Rd",
8150b57cec5SDimitry Andric                      [(set GPR:$Rd, (ctpop GPR:$Rs1))]>;
8160b57cec5SDimitry Andric
8170b57cec5SDimitry Andric// Count Leading Zeros (LEADZ)
8180b57cec5SDimitry Andricdef LEADZ: InstSpecial<0b010, (outs GPR:$Rd), (ins GPR:$Rs1),
8190b57cec5SDimitry Andric                       "leadz\t$Rs1, $Rd", [(set GPR:$Rd, (ctlz GPR:$Rs1))]>;
8200b57cec5SDimitry Andric
8210b57cec5SDimitry Andric// Count Trailing Zeros (TRAILZ)
8220b57cec5SDimitry Andricdef TRAILZ : InstSpecial<0b011, (outs GPR:$Rd), (ins GPR:$Rs1),
8230b57cec5SDimitry Andric                         "trailz\t$Rs1, $Rd",
8240b57cec5SDimitry Andric                         [(set GPR:$Rd, (cttz GPR:$Rs1))]>;
8250b57cec5SDimitry Andric}
8260b57cec5SDimitry Andric
8270b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
8280b57cec5SDimitry Andric// Non-Instruction Patterns
8290b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
8300b57cec5SDimitry Andric
8310b57cec5SDimitry Andric// unsigned 16-bit immediate
8320b57cec5SDimitry Andricdef : Pat<(i32 i32lo16z:$imm), (OR_I_LO (i32 R0), imm:$imm)>;
8330b57cec5SDimitry Andric
8340b57cec5SDimitry Andric// arbitrary immediate
8350b57cec5SDimitry Andricdef : Pat<(i32 imm:$imm), (OR_I_LO (MOVHI (HI16 imm:$imm)), (LO16 imm:$imm))>;
8360b57cec5SDimitry Andric
8370b57cec5SDimitry Andric// Calls
8380b57cec5SDimitry Andricdef : Pat<(Call tglobaladdr:$dst), (CALL tglobaladdr:$dst)>;
8390b57cec5SDimitry Andricdef : Pat<(Call texternalsym:$dst), (CALL texternalsym:$dst)>;
8400b57cec5SDimitry Andric
8410b57cec5SDimitry Andric// Loads
8420b57cec5SDimitry Andricdef : Pat<(extloadi8  ADDRspls:$src), (i32 (LDBz_RI ADDRspls:$src))>;
8430b57cec5SDimitry Andricdef : Pat<(extloadi16 ADDRspls:$src), (i32 (LDHz_RI ADDRspls:$src))>;
8440b57cec5SDimitry Andric// Loads up to 32-bits are already atomic.
8450b57cec5SDimitry Andric// TODO: This is a workaround for a particular failing case and should be
8460b57cec5SDimitry Andric// handled more generally.
8470b57cec5SDimitry Andricdef : Pat<(atomic_load_8  ADDRspls:$src), (i32 (LDBz_RI ADDRspls:$src))>;
8480b57cec5SDimitry Andric
8490b57cec5SDimitry Andric// GlobalAddress, ExternalSymbol, Jumptable, ConstantPool
8500b57cec5SDimitry Andricdef : Pat<(LanaiHi tglobaladdr:$dst), (MOVHI tglobaladdr:$dst)>;
8510b57cec5SDimitry Andricdef : Pat<(LanaiLo tglobaladdr:$dst), (OR_I_LO (i32 R0), tglobaladdr:$dst)>;
8520b57cec5SDimitry Andricdef : Pat<(LanaiSmall tglobaladdr:$dst), (SLI tglobaladdr:$dst)>;
8530b57cec5SDimitry Andricdef : Pat<(LanaiHi texternalsym:$dst), (MOVHI texternalsym:$dst)>;
8540b57cec5SDimitry Andricdef : Pat<(LanaiLo texternalsym:$dst), (OR_I_LO (i32 R0), texternalsym:$dst)>;
8550b57cec5SDimitry Andricdef : Pat<(LanaiSmall texternalsym:$dst), (SLI texternalsym:$dst)>;
8560b57cec5SDimitry Andricdef : Pat<(LanaiHi tblockaddress:$dst), (MOVHI tblockaddress:$dst)>;
8570b57cec5SDimitry Andricdef : Pat<(LanaiLo tblockaddress:$dst), (OR_I_LO (i32 R0), tblockaddress:$dst)>;
8580b57cec5SDimitry Andricdef : Pat<(LanaiSmall tblockaddress:$dst), (SLI tblockaddress:$dst)>;
8590b57cec5SDimitry Andricdef : Pat<(LanaiHi tjumptable:$dst), (MOVHI tjumptable:$dst)>;
8600b57cec5SDimitry Andricdef : Pat<(LanaiLo tjumptable:$dst), (OR_I_LO (i32 R0), tjumptable:$dst)>;
8610b57cec5SDimitry Andricdef : Pat<(LanaiSmall tjumptable:$dst), (SLI tjumptable:$dst)>;
8620b57cec5SDimitry Andricdef : Pat<(LanaiHi tconstpool:$dst), (MOVHI tconstpool:$dst)>;
8630b57cec5SDimitry Andricdef : Pat<(LanaiLo tconstpool:$dst), (OR_I_LO (i32 R0), tconstpool:$dst)>;
8640b57cec5SDimitry Andricdef : Pat<(LanaiSmall tconstpool:$dst), (SLI tconstpool:$dst)>;
8650b57cec5SDimitry Andric
8660b57cec5SDimitry Andricdef : Pat<(or GPR:$hi, (LanaiLo tglobaladdr:$lo)),
8670b57cec5SDimitry Andric          (OR_I_LO GPR:$hi, tglobaladdr:$lo)>;
8680b57cec5SDimitry Andricdef : Pat<(or R0, (LanaiSmall tglobaladdr:$small)),
8690b57cec5SDimitry Andric          (SLI tglobaladdr:$small)>;
8700b57cec5SDimitry Andricdef : Pat<(or GPR:$hi, (LanaiLo texternalsym:$lo)),
8710b57cec5SDimitry Andric          (OR_I_LO GPR:$hi, texternalsym:$lo)>;
8720b57cec5SDimitry Andricdef : Pat<(or R0, (LanaiSmall texternalsym:$small)),
8730b57cec5SDimitry Andric          (SLI texternalsym:$small)>;
8740b57cec5SDimitry Andricdef : Pat<(or GPR:$hi, (LanaiLo tblockaddress:$lo)),
8750b57cec5SDimitry Andric          (OR_I_LO GPR:$hi, tblockaddress:$lo)>;
8760b57cec5SDimitry Andricdef : Pat<(or R0, (LanaiSmall tblockaddress:$small)),
8770b57cec5SDimitry Andric          (SLI tblockaddress:$small)>;
8780b57cec5SDimitry Andricdef : Pat<(or GPR:$hi, (LanaiLo tjumptable:$lo)),
8790b57cec5SDimitry Andric          (OR_I_LO GPR:$hi, tjumptable:$lo)>;
8800b57cec5SDimitry Andricdef : Pat<(or R0, (LanaiSmall tjumptable:$small)),
8810b57cec5SDimitry Andric          (SLI tjumptable:$small)>;
8820b57cec5SDimitry Andricdef : Pat<(or GPR:$hi, (LanaiLo tconstpool:$lo)),
8830b57cec5SDimitry Andric          (OR_I_LO GPR:$hi, tconstpool:$lo)>;
8840b57cec5SDimitry Andricdef : Pat<(or R0, (LanaiSmall tconstpool:$small)),
8850b57cec5SDimitry Andric          (SLI tconstpool:$small)>;
886