brintos

brintos / llvm-project-archived public Read only

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