Home | History | Annotate | Download | only in Lanai
      1 //===-- LanaiInstrInfo.td - Target Description for Lanai Target -----------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file describes the Lanai instructions in TableGen format.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 //===----------------------------------------------------------------------===//
     15 // Instruction format superclass
     16 //===----------------------------------------------------------------------===//
     17 
     18 include "LanaiInstrFormats.td"
     19 
     20 // -------------------------------------------------- //
     21 // Instruction Operands and Patterns
     22 // -------------------------------------------------- //
     23 
     24 //  These are target-independent nodes, but have target-specific formats.
     25 def SDT_LanaiCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>]>;
     26 def SDT_LanaiCallSeqEnd   : SDCallSeqEnd<[SDTCisVT<0, i32>,
     27                                           SDTCisVT<1, i32>]>;
     28 def SDT_LanaiCall         : SDTypeProfile<0, -1, [SDTCisVT<0, i32>]>;
     29 def SDT_LanaiSetFlag      : SDTypeProfile<0,  2, [SDTCisSameAs<0, 1>]>;
     30 def SDT_LanaiSelectCC     : SDTypeProfile<1,  3, [SDTCisSameAs<0, 1>,
     31                                                   SDTCisSameAs<1, 2>]>;
     32 def SDT_LanaiSetCC        : SDTypeProfile<1,  1, [SDTCisVT<0, i32>,
     33                                                   SDTCisVT<1, i32>]>;
     34 def SDT_LanaiBrCC         : SDTypeProfile<0,  2, [SDTCisVT<0, OtherVT>,
     35                                                   SDTCisVT<1, i32>]>;
     36 def SDT_LanaiAdjDynAlloc  : SDTypeProfile<1,  1, [SDTCisVT<0, i32>,
     37                                                   SDTCisVT<1, i32>]>;
     38 
     39 def Call             : SDNode<"LanaiISD::CALL", SDT_LanaiCall,
     40                               [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
     41                                SDNPVariadic]>;
     42 def RetFlag          : SDNode<"LanaiISD::RET_FLAG", SDTNone,
     43                               [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
     44 def CallSeqStart     : SDNode<"ISD::CALLSEQ_START", SDT_LanaiCallSeqStart,
     45                               [SDNPHasChain, SDNPOutGlue]>;
     46 def CallSeqEnd       : SDNode<"ISD::CALLSEQ_END", SDT_LanaiCallSeqEnd,
     47                               [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
     48 def LanaiSetFlag     : SDNode<"LanaiISD::SET_FLAG", SDT_LanaiSetFlag,
     49                               [SDNPOutGlue]>;
     50 def LanaiSubbF       : SDNode<"LanaiISD::SUBBF", SDT_LanaiSetFlag,
     51                               [SDNPOutGlue, SDNPInGlue]>;
     52 def LanaiBrCC        : SDNode<"LanaiISD::BR_CC", SDT_LanaiBrCC,
     53                               [SDNPHasChain, SDNPInGlue]>;
     54 def LanaiSelectCC    : SDNode<"LanaiISD::SELECT_CC", SDT_LanaiSelectCC,
     55                               [SDNPInGlue]>;
     56 def LanaiSetCC       : SDNode<"LanaiISD::SETCC", SDT_LanaiSetCC,
     57                               [SDNPInGlue]>;
     58 def LanaiHi          : SDNode<"LanaiISD::HI", SDTIntUnaryOp>;
     59 def LanaiLo          : SDNode<"LanaiISD::LO", SDTIntUnaryOp>;
     60 def LanaiSmall       : SDNode<"LanaiISD::SMALL", SDTIntUnaryOp>;
     61 def LanaiAdjDynAlloc : SDNode<"LanaiISD::ADJDYNALLOC", SDT_LanaiAdjDynAlloc>;
     62 
     63 // Extract bits 0-15 (low-end) of an immediate value.
     64 def LO16 : SDNodeXForm<imm, [{
     65   return CurDAG->getTargetConstant((uint64_t)N->getZExtValue() & 0xffff,
     66                                    SDLoc(N), MVT::i32);
     67 }]>;
     68 
     69 // Extract bits 16-31 (high-end) of an immediate value.
     70 // Transformation function: shift the immediate value down into the low bits.
     71 def HI16 : SDNodeXForm<imm, [{
     72   return CurDAG->getTargetConstant((uint64_t)N->getZExtValue() >> 16, SDLoc(N),
     73                                    MVT::i32);
     74 }]>;
     75 
     76 def NEG : SDNodeXForm<imm, [{
     77   return CurDAG->getTargetConstant(-N->getSExtValue(), SDLoc(N), MVT::i32);
     78 }]>;
     79 
     80 def LO21 : SDNodeXForm<imm, [{
     81   return CurDAG->getTargetConstant((uint64_t)N->getZExtValue() & 0x1fffff,
     82                                    SDLoc(N), MVT::i32);
     83 }]>;
     84 
     85 // Branch targets
     86 def BrTargetAsmOperand : AsmOperandClass {
     87   let Name = "BrTarget";
     88 }
     89 def BrTarget   : Operand<OtherVT> {
     90   let ParserMatchClass = BrTargetAsmOperand;
     91   let EncoderMethod = "getBranchTargetOpValue";
     92   let DecoderMethod = "decodeBranch";
     93 }
     94 
     95 def CallTargetAsmOperand : AsmOperandClass {
     96   let Name = "CallTarget";
     97 }
     98 def CallTarget : Operand<i32> {
     99   let ParserMatchClass = CallTargetAsmOperand;
    100   let EncoderMethod = "getBranchTargetOpValue";
    101   let DecoderMethod = "decodeBranch";
    102 }
    103 
    104 def ImmShiftAsmOperand : AsmOperandClass { let Name = "ImmShift"; }
    105 def immShift : Operand<i32>, PatLeaf<(imm), [{
    106     int Imm = N->getSExtValue();
    107     return Imm >= -31 && Imm <= 31;}]> {
    108   let ParserMatchClass = ImmShiftAsmOperand;
    109   let DecoderMethod = "decodeShiftImm";
    110 }
    111 
    112 def Imm10AsmOperand : AsmOperandClass { let Name = "Imm10"; }
    113 def imm10 : Operand<i32>, PatLeaf<(imm), [{
    114     return isInt<10>(N->getSExtValue()); }]> {
    115   let ParserMatchClass = Imm10AsmOperand;
    116 }
    117 
    118 def immZExt21 : PatLeaf<(imm),
    119                         [{return isUInt<21>(N->getZExtValue()); }], LO21>;
    120 
    121 def LoImm16AsmOperand : AsmOperandClass { let Name = "LoImm16"; }
    122 def i32lo16z : Operand<i32>, PatLeaf<(i32 imm), [{
    123     // i32lo16 predicate - true if the 32-bit immediate has only rightmost 16
    124     // bits set.
    125     return ((N->getZExtValue() & 0xFFFFUL) == N->getZExtValue());}], LO16> {
    126   let ParserMatchClass = LoImm16AsmOperand;
    127 }
    128 def i32neg16 : Operand<i32>, PatLeaf<(i32 imm), [{
    129     // i32neg16 predicate - true if the 32-bit immediate is negative and can
    130     // be represented by a 16 bit integer.
    131     int Imm = N->getSExtValue();
    132     return (Imm < 0) && (isInt<16>(Imm));}], LO16> {
    133   let ParserMatchClass = LoImm16AsmOperand;
    134 }
    135 def i32lo16s : Operand<i32>, PatLeaf<(i32 imm), [{
    136     // i32lo16 predicate - true if the 32-bit immediate has only rightmost 16
    137     // bits set.
    138     return ((int64_t)(N->getSExtValue() & 0xFFFFUL) == N->getSExtValue());}], LO16> {
    139   let ParserMatchClass = LoImm16AsmOperand;
    140 }
    141 
    142 def LoImm16AndAsmOperand : AsmOperandClass { let Name = "LoImm16And"; }
    143 def i32lo16and : Operand<i32>, PatLeaf<(i32 imm), [{
    144     // i32lo16 predicate - true if the 32-bit immediate has the rightmost 16
    145     // bits set and the leftmost 16 bits 1's.
    146     return (N->getZExtValue() >= 0xFFFF0000UL);}], LO16> {
    147   let ParserMatchClass = LoImm16AndAsmOperand;
    148   let PrintMethod = "printLo16AndImmOperand";
    149 }
    150 
    151 def HiImm16AsmOperand : AsmOperandClass { let Name = "HiImm16"; }
    152 def i32hi16 : Operand<i32>, PatLeaf<(i32 imm), [{
    153     // i32hi16 predicate - true if the 32-bit immediate has only leftmost 16
    154     // bits set.
    155     return ((N->getZExtValue() & 0xFFFF0000UL) == N->getZExtValue());}], HI16> {
    156   let ParserMatchClass = HiImm16AsmOperand;
    157   let PrintMethod = "printHi16ImmOperand";
    158 }
    159 
    160 def HiImm16AndAsmOperand : AsmOperandClass { let Name = "HiImm16And"; }
    161 def i32hi16and : Operand<i32>, PatLeaf<(i32 imm), [{
    162     // i32lo16 predicate - true if the 32-bit immediate has the leftmost 16
    163     // bits set and the rightmost 16 bits 1's.
    164     return ((N->getZExtValue() & 0xFFFFUL) == 0xFFFFUL);}], HI16> {
    165   let ParserMatchClass = HiImm16AndAsmOperand;
    166   let PrintMethod = "printHi16AndImmOperand";
    167 }
    168 
    169 def LoImm21AsmOperand : AsmOperandClass { let Name = "LoImm21"; }
    170 def i32lo21 : Operand<i32>, PatLeaf<(i32 imm), [{
    171     // i32lo21 predicate - true if the 32-bit immediate has only rightmost 21
    172     // bits set.
    173     return ((N->getZExtValue() & 0x1FFFFFUL) == N->getZExtValue());}], LO21> {
    174   let ParserMatchClass = LoImm21AsmOperand;
    175 }
    176 
    177 def AluOp : Operand<i32> {
    178   let PrintMethod = "printAluOperand";
    179 }
    180 
    181 // Addressing modes.
    182 def ADDRrr : ComplexPattern<i32, 3, "selectAddrRr", [], []>;
    183 def ADDRri : ComplexPattern<i32, 3, "selectAddrRi", [frameindex], []>;
    184 def ADDRsls : ComplexPattern<i32, 1, "selectAddrSls", [frameindex], []>;
    185 def ADDRspls : ComplexPattern<i32, 3, "selectAddrSpls", [frameindex], []>;
    186 
    187 // Address operands
    188 def MemRegImmAsmOperand : AsmOperandClass {
    189   let Name = "MemRegImm";
    190   let ParserMethod  = "parseMemoryOperand";
    191 }
    192 def MEMri : Operand<i32> {
    193   let DecoderMethod = "decodeRiMemoryValue";
    194   let EncoderMethod = "getRiMemoryOpValue";
    195   let MIOperandInfo = (ops GPR:$base, i32lo16s:$offset, AluOp:$Opcode);
    196   let ParserMatchClass = MemRegImmAsmOperand;
    197   let PrintMethod   = "printMemRiOperand";
    198 }
    199 
    200 def MemRegRegAsmOperand : AsmOperandClass {
    201   let Name = "MemRegReg";
    202   let ParserMethod  = "parseMemoryOperand";
    203 }
    204 def MEMrr : Operand<i32> {
    205   let DecoderMethod = "decodeRrMemoryValue";
    206   let EncoderMethod = "getRrMemoryOpValue";
    207   let MIOperandInfo = (ops GPR:$Op1, GPR:$Op2, AluOp:$Opcode);
    208   let ParserMatchClass = MemRegRegAsmOperand;
    209   let PrintMethod   = "printMemRrOperand";
    210 }
    211 
    212 def MemImmAsmOperand : AsmOperandClass {
    213   let Name = "MemImm";
    214   let ParserMethod  = "parseMemoryOperand";
    215 }
    216 def MEMi : Operand<i32> {
    217   let MIOperandInfo = (ops i32lo21:$offset);
    218   let ParserMatchClass = MemImmAsmOperand;
    219   let PrintMethod   = "printMemImmOperand";
    220 }
    221 
    222 def MemSplsAsmOperand : AsmOperandClass {
    223   let Name = "MemSpls";
    224   let ParserMethod  = "parseMemoryOperand";
    225 }
    226 def MEMspls : Operand<i32> {
    227   let DecoderMethod = "decodeSplsValue";
    228   let EncoderMethod = "getSplsOpValue";
    229   let MIOperandInfo = (ops GPR:$base, imm10:$offset, AluOp:$Opcode);
    230   let ParserMatchClass = MemSplsAsmOperand;
    231   let PrintMethod   = "printMemSplsOperand";
    232 }
    233 
    234 def CCOp : Operand<i32> {
    235   let PrintMethod = "printCCOperand";
    236 }
    237 
    238 // Predicate operand. Default to 0 = true.
    239 def CondCodeOperand : AsmOperandClass { let Name = "CondCode"; }
    240 
    241 def pred : PredicateOperand<i32, (ops i32imm), (ops (i32 0))> {
    242   let PrintMethod = "printPredicateOperand";
    243   let ParserMatchClass = CondCodeOperand;
    244   let DecoderMethod = "decodePredicateOperand";
    245 }
    246 
    247 let hasSideEffects = 0, Inst = 0x00000001 in
    248   def NOP : InstLanai<(outs), (ins), "nop", []>;
    249 
    250 // Special NOPs to change logging level in vlanai.
    251 let hasSideEffects = 0, Inst = 0x00000002 in
    252   def LOG0 : InstLanai<(outs), (ins), "log_0", []>;
    253 let hasSideEffects = 0, Inst = 0x00000003 in
    254   def LOG1 : InstLanai<(outs), (ins), "log_1", []>;
    255 let hasSideEffects = 0, Inst = 0x00000004 in
    256   def LOG2 : InstLanai<(outs), (ins), "log_2", []>;
    257 let hasSideEffects = 0, Inst = 0x00000005 in
    258   def LOG3 : InstLanai<(outs), (ins), "log_3", []>;
    259 let hasSideEffects = 0, Inst = 0x00000006 in
    260   def LOG4 : InstLanai<(outs), (ins), "log_4", []>;
    261 
    262 // Map an SPLS instruction onto itself. All other instructions will be mapped
    263 // onto -1. Used to identify SPLS instructions.
    264 def splsIdempotent : InstrMapping {
    265   let FilterClass = "InstSPLS";
    266   let RowFields = ["AsmString"];
    267   let ColFields = ["PostEncoderMethod"];
    268   let KeyCol = ["adjustPqBitsSpls"];
    269   let ValueCols = [["adjustPqBitsSpls"]];
    270 }
    271 
    272 // -------------------------------------------------- //
    273 // ALU instructions
    274 // -------------------------------------------------- //
    275 multiclass ALUbase<bits<3> subOp, string AsmStr, SDNode OpNode,
    276                    PatLeaf LoExt, PatLeaf HiExt,
    277                    list<dag> loPattern, list<dag> hiPattern> {
    278   // Register Immediate
    279   let H = 0 in
    280     def LO : InstRI<subOp, (outs GPR:$Rd), (ins GPR:$Rs1, LoExt:$imm16),
    281                     !strconcat(AsmStr, "\t$Rs1, $imm16, $Rd"),
    282                     loPattern>;
    283   let H = 1 in
    284     def HI : InstRI<subOp, (outs GPR:$Rd), (ins GPR:$Rs1, HiExt:$imm16),
    285                     !strconcat(AsmStr, "\t$Rs1, $imm16, $Rd"),
    286                     hiPattern>;
    287 
    288 }
    289 
    290 multiclass ALUarith<bits<3> subOp, string AsmStr, SDNode OpNode,
    291                     PatLeaf LoExt, PatLeaf HiExt> {
    292   defm I_ : ALUbase<subOp, AsmStr, OpNode, LoExt, HiExt, [], []>;
    293 
    294   // Register Register
    295   let JJJJJ = 0 in
    296     def R : InstRR<subOp, (outs GPR:$Rd), (ins GPR:$Rs1, GPR:$Rs2, pred:$DDDI),
    297                    !strconcat(AsmStr, "$DDDI\t$Rs1, $Rs2, $Rd"),
    298                    [(set GPR:$Rd, (OpNode GPR:$Rs1, GPR:$Rs2))]>;
    299 }
    300 
    301 multiclass ALUlogic<bits<3> subOp, string AsmStr, SDNode OpNode,
    302                     PatLeaf LoExt, PatLeaf HiExt> {
    303   defm I_ : ALUbase<subOp, AsmStr, OpNode, LoExt, HiExt,
    304                     [(set GPR:$Rd, (OpNode GPR:$Rs1, LoExt:$imm16))],
    305                     [(set GPR:$Rd, (OpNode GPR:$Rs1, HiExt:$imm16))]>;
    306 
    307   // Register Register
    308   let JJJJJ = 0 in
    309     def R : InstRR<subOp, (outs GPR:$Rd), (ins GPR:$Rs1, GPR:$Rs2, pred:$DDDI),
    310                    !strconcat(AsmStr, "$DDDI\t$Rs1, $Rs2, $Rd"),
    311                    [(set GPR:$Rd, (OpNode GPR:$Rs1, GPR:$Rs2))]>;
    312 }
    313 
    314 // Non flag setting ALU operations
    315 let isAsCheapAsAMove = 1, F = 0 in {
    316   let isCommutable = 1 in {
    317     defm ADD_ : ALUarith<0b000, "add", add, i32lo16z, i32hi16>;
    318   }
    319   defm SUB_ : ALUarith<0b010,   "sub", sub, i32lo16z, i32hi16>;
    320   let isCommutable = 1 in {
    321     defm AND_ : ALUlogic<0b100, "and", and, i32lo16and, i32hi16and>;
    322     defm OR_  : ALUlogic<0b101,  "or",  or, i32lo16z, i32hi16>;
    323     defm XOR_ : ALUlogic<0b110, "xor", xor, i32lo16z, i32hi16>;
    324   }
    325 }
    326 
    327 def : Pat<(add GPR:$Rs1, i32lo16z:$imm),
    328           (ADD_I_LO GPR:$Rs1, i32lo16z:$imm)>;
    329 
    330 def : Pat<(sub GPR:$Rs1, i32lo16z:$imm),
    331           (SUB_I_LO GPR:$Rs1, i32lo16z:$imm)>;
    332 
    333 def : Pat<(add GPR:$Rs1, i32hi16:$imm),
    334           (ADD_I_HI GPR:$Rs1, i32hi16:$imm)>;
    335 
    336 def : Pat<(sub GPR:$Rs1, i32hi16:$imm),
    337           (SUB_I_HI GPR:$Rs1, i32hi16:$imm)>;
    338 
    339 def : Pat<(i32 i32lo16and:$imm), (AND_I_LO (i32 R1), i32lo16and:$imm)>;
    340 def : Pat<(i32 i32hi16and:$imm), (AND_I_HI (i32 R1), i32hi16and:$imm)>;
    341 
    342 // Change add/sub with negative number to sub/add
    343 def : Pat<(add GPR:$Rs1, i32neg16:$imm),
    344           (SUB_I_LO GPR:$Rs1, (NEG $imm))>;
    345 def : Pat<(sub GPR:$Rs1, i32neg16:$imm),
    346           (ADD_I_LO GPR:$Rs1, (NEG $imm))>;
    347 
    348 // Flag (incl. carry) setting addition and subtraction
    349 let F = 1, Defs = [SR] in {
    350   defm ADD_F_ : ALUarith<0b000, "add.f", addc, i32lo16z, i32hi16>;
    351   defm SUB_F_ : ALUarith<0b010, "sub.f", subc, i32lo16z, i32hi16>;
    352 }
    353 
    354 def : Pat<(addc GPR:$Rs1, i32lo16z:$imm),
    355           (ADD_F_I_LO GPR:$Rs1, i32lo16z:$imm)>;
    356 
    357 def : Pat<(subc GPR:$Rs1, i32lo16z:$imm),
    358           (SUB_F_I_LO GPR:$Rs1, i32lo16z:$imm)>;
    359 
    360 def : Pat<(addc GPR:$Rs1, i32hi16:$imm),
    361           (ADD_F_I_HI GPR:$Rs1, i32hi16:$imm)>;
    362 
    363 def : Pat<(subc GPR:$Rs1, i32hi16:$imm),
    364           (SUB_F_I_HI GPR:$Rs1, i32hi16:$imm)>;
    365 
    366 // Carry using addition and subtraction
    367 let F = 0, Uses = [SR] in {
    368   defm ADDC_ : ALUarith<0b001, "addc", adde, i32lo16z, i32hi16>;
    369   defm SUBB_ : ALUarith<0b011, "subb", sube, i32lo16z, i32hi16>;
    370 }
    371 
    372 def : Pat<(adde GPR:$Rs1, i32lo16z:$imm),
    373           (ADDC_I_LO GPR:$Rs1, i32lo16z:$imm)>;
    374 
    375 def : Pat<(sube GPR:$Rs1, i32lo16z:$imm),
    376           (SUBB_I_LO GPR:$Rs1, i32lo16z:$imm)>;
    377 
    378 def : Pat<(adde GPR:$Rs1, i32hi16:$imm),
    379           (ADDC_I_HI GPR:$Rs1, i32hi16:$imm)>;
    380 
    381 def : Pat<(sube GPR:$Rs1, i32hi16:$imm),
    382           (SUBB_I_HI GPR:$Rs1, i32hi16:$imm)>;
    383 
    384 // Flag setting ALU operations
    385 let isAsCheapAsAMove = 1, F = 1, Defs = [SR] in {
    386   let isCommutable = 1 in {
    387     defm AND_F_ : ALUlogic<0b100, "and.f",  and, i32lo16and, i32hi16and>;
    388     defm OR_F_  : ALUlogic<0b101,  "or.f",   or, i32lo16z, i32hi16>;
    389     defm XOR_F_ : ALUlogic<0b110, "xor.f",  xor, i32lo16z, i32hi16>;
    390   }
    391 }
    392 
    393 let isAsCheapAsAMove = 1, F = 1, Defs = [SR], Uses = [SR] in {
    394   defm ADDC_F_ : ALUarith<0b001, "addc.f", adde, i32lo16z, i32hi16>;
    395   defm SUBB_F_ : ALUarith<0b011, "subb.f", sube, i32lo16z, i32hi16>;
    396 }
    397 
    398 def : Pat<(LanaiSubbF GPR:$Rs1, GPR:$Rs2),
    399           (SUBB_F_R GPR:$Rs1, GPR:$Rs2)>;
    400 
    401 def : Pat<(LanaiSubbF GPR:$Rs1, i32lo16z:$imm),
    402           (SUBB_F_I_LO GPR:$Rs1, i32lo16z:$imm)>;
    403 
    404 def : Pat<(LanaiSubbF GPR:$Rs1, i32hi16:$imm),
    405           (SUBB_F_I_HI GPR:$Rs1, i32hi16:$imm)>;
    406 
    407 def : InstAlias<"mov $src, $dst", (ADD_R GPR:$dst, GPR:$src, R0, 0)>;
    408 
    409 let isAsCheapAsAMove = 1, Rs1 = R0.Num, isCodeGenOnly = 1, H = 1, F = 0,
    410   isReMaterializable = 1 in
    411   def MOVHI : InstRI<0b000, (outs GPR:$Rd), (ins i32hi16:$imm16),
    412                      "mov\t$imm16, $Rd",
    413                      [(set GPR:$Rd, i32hi16:$imm16)]>;
    414 
    415 def : InstAlias<"mov $imm16, $dst", (ADD_I_LO GPR:$dst, R0, i32lo16z:$imm16)>;
    416 def : InstAlias<"mov $imm16, $dst", (ADD_I_HI GPR:$dst, R0, i32hi16:$imm16)>;
    417 def : InstAlias<"mov $imm16, $dst",
    418                 (AND_I_LO GPR:$dst, R1, i32lo16and:$imm16)>;
    419 def : InstAlias<"mov $imm16, $dst",
    420                 (AND_I_HI GPR:$dst, R1, i32hi16and:$imm16)>;
    421 
    422 // Shift instructions
    423 class ShiftRI<string AsmStr, list<dag> Pattern>
    424   : InstRI<0b111, (outs GPR:$Rd), (ins GPR:$Rs1, immShift:$imm16),
    425            !strconcat(AsmStr, "\t$Rs1, $imm16, $Rd"), Pattern> {
    426   let isReMaterializable = 1;
    427 }
    428 
    429 let F = 0 in {
    430   let H = 0 in
    431     def SL_I : ShiftRI<"sh", [(set GPR:$Rd, (shl GPR:$Rs1, immShift:$imm16))]>;
    432   let H = 1 in
    433     def SA_I : ShiftRI<"sha", []>;
    434 }
    435 def : Pat<(srl GPR:$Rs1, immShift:$imm), (SL_I GPR:$Rs1, (NEG $imm))>;
    436 def : Pat<(sra GPR:$Rs1, immShift:$imm), (SA_I GPR:$Rs1, (NEG $imm))>;
    437 
    438 let F = 1, Defs = [SR] in {
    439   let H = 0 in
    440     def SL_F_I : ShiftRI<"sh.f", []>;
    441   let H = 1 in
    442     def SA_F_I : ShiftRI<"sha.f", []>;
    443 }
    444 
    445 class ShiftRR<string AsmStr, list<dag> Pattern>
    446   : InstRR<0b111, (outs GPR:$Rd), (ins GPR:$Rs1, GPR:$Rs2, pred:$DDDI), AsmStr,
    447            Pattern>;
    448 
    449 let F = 0 in {
    450   let JJJJJ = 0b10000 in
    451     def SHL_R : ShiftRR<"sh$DDDI\t$Rs1, $Rs2, $Rd",
    452                         [(set GPR:$Rd, (shl GPR:$Rs1, GPR:$Rs2))]>;
    453   let isCodeGenOnly = 1 in {
    454     let JJJJJ = 0b10000 in
    455       def SRL_R : ShiftRR<"sh$DDDI\t$Rs1, $Rs2, $Rd", []>;
    456   }
    457   let JJJJJ = 0b11000 in
    458     def SRA_R : ShiftRR<"sha$DDDI\t$Rs1, $Rs2, $Rd", []>;
    459 }
    460 
    461 let F = 1, Defs = [SR] in {
    462   let JJJJJ = 0b10000 in
    463     def SHL_F_R : ShiftRR<"sh.f$DDDI\t$Rs1, $Rs2, $Rd", []>;
    464   let isCodeGenOnly = 1 in {
    465     let JJJJJ = 0b10000 in
    466       def SRL_F_R : ShiftRR<"sh.f$DDDI\t$Rs1, $Rs2, $Rd", []>;
    467   }
    468   let JJJJJ = 0b11000 in
    469     def SRA_F_R : ShiftRR<"sha.f$DDDI\t$Rs1, $Rs2, $Rd", []>;
    470 }
    471 
    472 // Expand shift-right operations
    473 def : Pat<(srl GPR:$Rs1, GPR:$Rs2),
    474           (SRL_R GPR:$Rs1, (SUB_R R0, GPR:$Rs2))>;
    475 def : Pat<(sra GPR:$Rs1, GPR:$Rs2),
    476           (SRA_R GPR:$Rs1, (SUB_R R0, GPR:$Rs2))>;
    477 
    478 // -------------------------------------------------- //
    479 // LOAD instructions
    480 // -------------------------------------------------- //
    481 
    482 class LoadRR<string OpcString, PatFrag OpNode, ValueType Ty>
    483   : InstRRM<0b0, (outs GPR:$Rd), (ins MEMrr:$src),
    484             !strconcat(OpcString, "\t$src, $Rd"),
    485             [(set (Ty GPR:$Rd), (OpNode ADDRrr:$src))]>,
    486     Sched<[WriteLD]> {
    487   bits<20> src;
    488 
    489   let Rs1 = src{19-15};
    490   let Rs2 = src{14-10};
    491   let P = src{9};
    492   let Q = src{8};
    493   let BBB = src{7-5};
    494   let JJJJJ = src{4-0};
    495   let mayLoad = 1;
    496 }
    497 
    498 class LoadRI<string OpcString, PatFrag OpNode, ValueType Ty>
    499   : InstRM<0b0, (outs GPR:$Rd), (ins MEMri:$src),
    500            !strconcat(OpcString, "\t$src, $Rd"),
    501            [(set (Ty GPR:$Rd), (OpNode ADDRri:$src))]>,
    502     Sched<[WriteLD]> {
    503   bits<23> src;
    504 
    505   let Itinerary = IIC_LD;
    506   let Rs1 = src{22-18};
    507   let P = src{17};
    508   let Q = src{16};
    509   let imm16 = src{15-0};
    510   let isReMaterializable = 1;
    511   let mayLoad = 1;
    512 }
    513 
    514 let E = 0 in {
    515   let YL = 0b01 in {
    516     // uld is used here and ld in the alias as the alias is printed out first if
    517     // an alias exist
    518     def LDW_RI : LoadRI<"uld", load, i32>;
    519     def LDW_RR : LoadRR<"ld", load, i32>;
    520   }
    521 }
    522 
    523 def : InstAlias<"ld $src, $dst", (LDW_RI GPR:$dst, MEMri:$src)>;
    524 
    525 let E = 1 in {
    526   let YL = 0b01 in {
    527     def LDWz_RR : LoadRR<"uld", zextloadi32, i32>;
    528   }
    529 }
    530 
    531 let E = 1 in {
    532   let YL = 0b00 in
    533     def LDHz_RR : LoadRR<"uld.h", zextloadi16, i32>;
    534   let YL = 0b10 in
    535     def LDBz_RR : LoadRR<"uld.b", zextloadi8, i32>;
    536 }
    537 
    538 let E = 0 in {
    539   let YL = 0b00 in
    540     def LDHs_RR : LoadRR<"ld.h", sextloadi16, i32>;
    541   let YL = 0b10 in
    542     def LDBs_RR : LoadRR<"ld.b", sextloadi8, i32>;
    543 }
    544 
    545 def LDADDR : InstSLS<0x0, (outs GPR:$Rd), (ins MEMi:$src),
    546                      "ld\t$src, $Rd",
    547                      [(set (i32 GPR:$Rd), (load ADDRsls:$src))]>,
    548     Sched<[WriteLD]> {
    549   bits<21> src;
    550 
    551   let Itinerary = IIC_LD;
    552   let msb = src{20-16};
    553   let lsb = src{15-0};
    554   let isReMaterializable = 1;
    555   let mayLoad = 1;
    556 }
    557 
    558 class LoadSPLS<string asmstring, PatFrag opNode>
    559   : InstSPLS<(outs GPR:$Rd), (ins MEMspls:$src),
    560              !strconcat(asmstring, "\t$src, $Rd"),
    561              [(set (i32 GPR:$Rd), (opNode ADDRspls:$src))]>,
    562     Sched<[WriteLDSW]> {
    563   bits<17> src;
    564   let Itinerary = IIC_LDSW;
    565   let Rs1 = src{16-12};
    566   let P = src{11};
    567   let Q = src{10};
    568   let imm10 = src{9-0};
    569   let mayLoad = 1;
    570   let isReMaterializable = 1;
    571 }
    572 
    573 let Y = 0, S = 0, E = 1 in
    574   def LDHz_RI : LoadSPLS<"uld.h", zextloadi16>;
    575 
    576 let Y = 0, S = 0, E = 0 in
    577   def LDHs_RI : LoadSPLS<"ld.h", sextloadi16>;
    578 
    579 let Y = 1, S = 0, E = 1 in
    580   def LDBz_RI : LoadSPLS<"uld.b", zextloadi8>;
    581 
    582 let Y = 1, S = 0, E = 0 in
    583   def LDBs_RI : LoadSPLS<"ld.b", sextloadi8>;
    584 
    585 def SLI : InstSLI<(outs GPR:$Rd), (ins i32lo21:$imm),
    586                   "mov\t$imm, $Rd",
    587                   [(set GPR:$Rd, i32lo21:$imm)]> {
    588   bits<21> imm;
    589 
    590   let msb = imm{20-16};
    591   let lsb = imm{15-0};
    592   let isReMaterializable = 1;
    593   let isAsCheapAsAMove = 1;
    594 }
    595 
    596 // -------------------------------------------------- //
    597 // STORE instructions
    598 // -------------------------------------------------- //
    599 
    600 class StoreRR<string OpcString, PatFrag OpNode, ValueType Ty>
    601   : InstRRM<0b1, (outs), (ins GPR:$Rd, MEMrr:$dst),
    602             !strconcat(OpcString, "\t$Rd, $dst"),
    603             [(OpNode (Ty GPR:$Rd), ADDRrr:$dst)]>,
    604     Sched<[WriteST]> {
    605   bits<20> dst;
    606 
    607   let Itinerary = IIC_ST;
    608   let Rs1 = dst{19-15};
    609   let Rs2 = dst{14-10};
    610   let P = dst{9};
    611   let Q = dst{8};
    612   let BBB = dst{7-5};
    613   let JJJJJ = dst{4-0};
    614   let mayStore = 1;
    615 }
    616 
    617 class StoreRI<string OpcString, PatFrag OpNode, ValueType Ty>
    618   : InstRM<0b1, (outs), (ins GPR:$Rd, MEMri:$dst),
    619            !strconcat(OpcString, "\t$Rd, $dst"),
    620            [(OpNode (Ty GPR:$Rd), ADDRri:$dst)]>,
    621     Sched<[WriteST]> {
    622   bits<23> dst;
    623 
    624   let Itinerary = IIC_ST;
    625   let Rs1 = dst{22-18};
    626   let P = dst{17};
    627   let Q = dst{16};
    628   let imm16 = dst{15-0};
    629   let mayStore = 1;
    630 }
    631 
    632 let YL = 0b01, E = 0 in {
    633   def SW_RR : StoreRR<"st", store, i32>;
    634   def SW_RI : StoreRI<"st", store, i32>;
    635 }
    636 
    637 let E = 0 in {
    638   let YL = 0b00 in
    639     def STH_RR : StoreRR<"st.h", truncstorei16, i32>;
    640   let YL = 0b10 in
    641     def STB_RR : StoreRR<"st.b", truncstorei8, i32>;
    642 }
    643 
    644 def STADDR : InstSLS<0x1, (outs), (ins GPR:$Rd, MEMi:$dst),
    645                      "st\t$Rd, $dst",
    646                      [(store (i32 GPR:$Rd), ADDRsls:$dst)]>,
    647     Sched<[WriteST]> {
    648   bits<21> dst;
    649 
    650   let Itinerary = IIC_ST;
    651   let msb = dst{20-16};
    652   let lsb = dst{15-0};
    653   let mayStore = 1;
    654 }
    655 
    656 class StoreSPLS<string asmstring, PatFrag opNode>
    657   : InstSPLS<(outs), (ins GPR:$Rd, MEMspls:$dst),
    658              !strconcat(asmstring, "\t$Rd, $dst"),
    659              [(opNode (i32 GPR:$Rd), ADDRspls:$dst)]>,
    660     Sched<[WriteSTSW]> {
    661   bits<17> dst;
    662 
    663   let Itinerary = IIC_STSW;
    664   let Rs1 = dst{16-12};
    665   let P = dst{11};
    666   let Q = dst{10};
    667   let imm10 = dst{9-0};
    668   let mayStore = 1;
    669 }
    670 
    671 let Y = 0, S = 1, E = 0 in
    672   def STH_RI : StoreSPLS<"st.h", truncstorei16>;
    673 
    674 let Y = 1, S = 1, E = 0 in
    675   def STB_RI : StoreSPLS<"st.b", truncstorei8>;
    676 
    677 // -------------------------------------------------- //
    678 // BRANCH instructions
    679 // -------------------------------------------------- //
    680 
    681 let isBranch = 1, isBarrier = 1, isTerminator = 1, hasDelaySlot = 1 in {
    682   def BT : InstBR<(outs), (ins BrTarget:$addr),
    683                   "bt\t$addr",
    684                   [(br bb:$addr)]> {
    685     let DDDI = 0b0000;
    686   }
    687   let Uses = [SR] in
    688     def BRCC : InstBR<(outs), (ins BrTarget:$addr, CCOp:$DDDI),
    689                       "b$DDDI\t$addr",
    690                       [(LanaiBrCC bb:$addr, imm:$DDDI)]>;
    691 
    692   let isIndirectBranch = 1 in {
    693     def JR : InstRR<0b101, (outs), (ins GPR:$Rs2), "bt\t$Rs2",
    694                     [(brind GPR:$Rs2)]> {
    695       let Rs1 = R0.Num;
    696       let Rd = R2.Num;
    697       let F = 0;
    698       let JJJJJ = 0;
    699       let DDDI = 0;
    700     }
    701   }
    702 }
    703 
    704 // -------------------------------------------------- //
    705 // Condition/SF instructions
    706 // -------------------------------------------------- //
    707 
    708 // Instructions to set flags used in lowering comparisons.
    709 multiclass SF<bits<3> op2Val, string AsmStr> {
    710   let F = 1, Rd = R0.Num, JJJJJ = 0, Defs = [SR], DDDI = 0 in
    711     def _RR : InstRR<op2Val, (outs), (ins GPR:$Rs1, GPR:$Rs2),
    712                      !strconcat(AsmStr, "\t$Rs1, $Rs2, %r0"),
    713                      [(LanaiSetFlag (i32 GPR:$Rs1), (i32 GPR:$Rs2))]>;
    714   let F = 1, Rd = R0.Num, H = 0, Defs = [SR] in
    715     def _RI_LO : InstRI<op2Val, (outs), (ins GPR:$Rs1, i32lo16z:$imm16),
    716                      !strconcat(AsmStr, "\t$Rs1, $imm16, %r0"),
    717                      [(LanaiSetFlag (i32 GPR:$Rs1), i32lo16z:$imm16)]>;
    718   let F = 1, Rd = R0.Num, H = 1, Defs = [SR] in
    719     def _RI_HI : InstRI<op2Val, (outs), (ins GPR:$Rs1, i32hi16:$imm16),
    720                      !strconcat(AsmStr, "\t$Rs1, $imm16, %r0"),
    721                      [(LanaiSetFlag (i32 GPR:$Rs1), i32hi16:$imm16)]>;
    722 }
    723 let isCodeGenOnly = 1, isCompare = 1 in {
    724   defm SFSUB_F : SF<0b010, "sub.f">;
    725 }
    726 
    727 // Jump and link
    728 let isCall = 1, hasDelaySlot = 1, isCodeGenOnly = 1, Uses = [SP],
    729     Defs = [RCA] in {
    730   def CALL : Pseudo<(outs), (ins CallTarget:$addr), "", []>;
    731   def CALLR : Pseudo<(outs), (ins GPR:$Rs1), "", [(Call GPR:$Rs1)]>;
    732 }
    733 
    734 let isReturn = 1, isTerminator = 1, hasDelaySlot = 1, isBarrier = 1,
    735     Uses = [RCA] in {
    736   def RET : InstRM<0b0, (outs), (ins),
    737                    "ld\t-4[%fp], %pc ! return",
    738                    [(RetFlag)]> {
    739     let Rd = PC.Num;
    740     let Rs1 = FP.Num;
    741     let P = 1;
    742     let Q = 0;
    743     let imm16 = -4;
    744 
    745     // Post encoding is not needed for RET.
    746     let PostEncoderMethod = "";
    747   }
    748 }
    749 
    750 // ADJCALLSTACKDOWN/UP implicitly use/def SP because they may be expanded into
    751 // a stack adjustment and the codegen must know that they may modify the stack
    752 // pointer before prolog-epilog rewriting occurs.
    753 // Pessimistically assume ADJCALLSTACKDOWN / ADJCALLSTACKUP will become
    754 // sub / add which can clobber SP.
    755 let Defs = [SP], Uses = [SP] in {
    756   def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt),
    757                                 "#ADJCALLSTACKDOWN $amt",
    758                                 [(CallSeqStart timm:$amt)]>;
    759   def ADJCALLSTACKUP   : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
    760                                 "#ADJCALLSTACKUP $amt1 $amt2",
    761                                 [(CallSeqEnd timm:$amt1, timm:$amt2)]>;
    762 }
    763 
    764 let Defs = [SP], Uses = [SP] in {
    765   def ADJDYNALLOC : Pseudo<(outs GPR:$dst), (ins GPR:$src),
    766                            "#ADJDYNALLOC $dst $src",
    767                            [(set GPR:$dst, (LanaiAdjDynAlloc GPR:$src))]>;
    768 }
    769 
    770 let Uses = [SR] in {
    771   def SCC : InstSCC<(outs GPR:$Rs1), (ins CCOp:$DDDI),
    772                     "s$DDDI\t$Rs1",
    773                     [(set (i32 GPR:$Rs1), (LanaiSetCC imm:$DDDI))]>;
    774 }
    775 
    776 // SCC's output is already 1-bit so and'ing with 1 is redundant.
    777 def : Pat<(and (LanaiSetCC imm:$DDDI), 1), (SCC imm:$DDDI)>;
    778 
    779 // Select with hardware support
    780 let Uses = [SR], isSelect = 1 in {
    781   def SELECT : InstRR<0b111, (outs GPR:$Rd),
    782                       (ins GPR:$Rs1, GPR:$Rs2, CCOp:$DDDI),
    783                       "sel.$DDDI $Rs1, $Rs2, $Rd",
    784                       [(set (i32 GPR:$Rd),
    785                        (LanaiSelectCC (i32 GPR:$Rs1), (i32 GPR:$Rs2),
    786                                       (imm:$DDDI)))]> {
    787     let JJJJJ = 0;
    788     let F = 0;
    789   }
    790 }
    791 
    792 let isBranch = 1, isBarrier = 1, isTerminator = 1, hasDelaySlot = 1,
    793     isIndirectBranch = 1, Uses = [SR] in {
    794   def BRIND_CC : InstRR<0b101, (outs), (ins GPR:$Rs1, CCOp:$DDDI),
    795                         "b$DDDI\t$Rs1", []> {
    796     let F = 0;
    797     let JJJJJ = 0;
    798     let Rd = PC.Num;
    799     let Rs2 = R0.Num;
    800   }
    801 
    802   def BRIND_CCA : InstRR<0b101, (outs), (ins GPR:$Rs1, GPR:$Rs2, CCOp:$DDDI),
    803                          "b${DDDI}\t$Rs1 add $Rs2", []> {
    804     let F = 0;
    805     let Rd = PC.Num;
    806     let JJJJJ = 0;
    807   }
    808 }
    809 
    810 // TODO: This only considers the case where BROFF is an immediate and not where
    811 // it is a register. Add support for register relative branching.
    812 let isBranch = 1, isBarrier = 1, isTerminator = 1, hasDelaySlot = 1, Rs1 = 0,
    813     Uses = [SR] in
    814   def BRR : InstBRR<(outs), (ins i16imm:$imm16, CCOp:$DDDI),
    815                     "b${DDDI}.r\t$imm16", []>;
    816 
    817 let F = 0 in {
    818 // Population Count (POPC)
    819 def POPC: InstSpecial<0b001, (outs GPR:$Rd), (ins GPR:$Rs1),
    820                       "popc\t$Rs1, $Rd",
    821                       [(set GPR:$Rd, (ctpop GPR:$Rs1))]>;
    822 
    823 // Count Leading Zeros (LEADZ)
    824 def LEADZ: InstSpecial<0b010, (outs GPR:$Rd), (ins GPR:$Rs1),
    825                        "leadz\t$Rs1, $Rd", [(set GPR:$Rd, (ctlz GPR:$Rs1))]>;
    826 
    827 // Count Trailing Zeros (TRAILZ)
    828 def TRAILZ : InstSpecial<0b011, (outs GPR:$Rd), (ins GPR:$Rs1),
    829                          "trailz\t$Rs1, $Rd",
    830                          [(set GPR:$Rd, (cttz GPR:$Rs1))]>;
    831 }
    832 
    833 //===----------------------------------------------------------------------===//
    834 // Non-Instruction Patterns
    835 //===----------------------------------------------------------------------===//
    836 
    837 // i32 0 and R0 can be used interchangeably.
    838 def : Pat<(i32 0), (i32 R0)>;
    839 // i32 -1 and R1 can be used interchangeably.
    840 def : Pat<(i32 -1), (i32 R1)>;
    841 
    842 // unsigned 16-bit immediate
    843 def : Pat<(i32 i32lo16z:$imm), (OR_I_LO (i32 R0), imm:$imm)>;
    844 
    845 // arbitrary immediate
    846 def : Pat<(i32 imm:$imm), (OR_I_LO (MOVHI (HI16 imm:$imm)), (LO16 imm:$imm))>;
    847 
    848 // Calls
    849 def : Pat<(Call tglobaladdr:$dst), (CALL tglobaladdr:$dst)>;
    850 def : Pat<(Call texternalsym:$dst), (CALL texternalsym:$dst)>;
    851 
    852 // Loads
    853 def : Pat<(extloadi8  ADDRspls:$src), (i32 (LDBz_RI ADDRspls:$src))>;
    854 def : Pat<(extloadi16 ADDRspls:$src), (i32 (LDHz_RI ADDRspls:$src))>;
    855 
    856 // GlobalAddress, ExternalSymbol, Jumptable, ConstantPool
    857 def : Pat<(LanaiHi tglobaladdr:$dst), (MOVHI tglobaladdr:$dst)>;
    858 def : Pat<(LanaiLo tglobaladdr:$dst), (OR_I_LO (i32 R0), tglobaladdr:$dst)>;
    859 def : Pat<(LanaiSmall tglobaladdr:$dst), (SLI tglobaladdr:$dst)>;
    860 def : Pat<(LanaiHi texternalsym:$dst), (MOVHI texternalsym:$dst)>;
    861 def : Pat<(LanaiLo texternalsym:$dst), (OR_I_LO (i32 R0), texternalsym:$dst)>;
    862 def : Pat<(LanaiSmall texternalsym:$dst), (SLI texternalsym:$dst)>;
    863 def : Pat<(LanaiHi tblockaddress:$dst), (MOVHI tblockaddress:$dst)>;
    864 def : Pat<(LanaiLo tblockaddress:$dst), (OR_I_LO (i32 R0), tblockaddress:$dst)>;
    865 def : Pat<(LanaiSmall tblockaddress:$dst), (SLI tblockaddress:$dst)>;
    866 def : Pat<(LanaiHi tjumptable:$dst), (MOVHI tjumptable:$dst)>;
    867 def : Pat<(LanaiLo tjumptable:$dst), (OR_I_LO (i32 R0), tjumptable:$dst)>;
    868 def : Pat<(LanaiSmall tjumptable:$dst), (SLI tjumptable:$dst)>;
    869 def : Pat<(LanaiHi tconstpool:$dst), (MOVHI tconstpool:$dst)>;
    870 def : Pat<(LanaiLo tconstpool:$dst), (OR_I_LO (i32 R0), tconstpool:$dst)>;
    871 def : Pat<(LanaiSmall tconstpool:$dst), (SLI tconstpool:$dst)>;
    872 
    873 def : Pat<(or GPR:$hi, (LanaiLo tglobaladdr:$lo)),
    874           (OR_I_LO GPR:$hi, tglobaladdr:$lo)>;
    875 def : Pat<(or R0, (LanaiSmall tglobaladdr:$small)),
    876           (SLI tglobaladdr:$small)>;
    877 def : Pat<(or GPR:$hi, (LanaiLo texternalsym:$lo)),
    878           (OR_I_LO GPR:$hi, texternalsym:$lo)>;
    879 def : Pat<(or R0, (LanaiSmall texternalsym:$small)),
    880           (SLI texternalsym:$small)>;
    881 def : Pat<(or GPR:$hi, (LanaiLo tblockaddress:$lo)),
    882           (OR_I_LO GPR:$hi, tblockaddress:$lo)>;
    883 def : Pat<(or R0, (LanaiSmall tblockaddress:$small)),
    884           (SLI tblockaddress:$small)>;
    885 def : Pat<(or GPR:$hi, (LanaiLo tjumptable:$lo)),
    886           (OR_I_LO GPR:$hi, tjumptable:$lo)>;
    887 def : Pat<(or R0, (LanaiSmall tjumptable:$small)),
    888           (SLI tjumptable:$small)>;
    889 def : Pat<(or GPR:$hi, (LanaiLo tconstpool:$lo)),
    890           (OR_I_LO GPR:$hi, tconstpool:$lo)>;
    891 def : Pat<(or R0, (LanaiSmall tconstpool:$small)),
    892           (SLI tconstpool:$small)>;
    893