brintos

brintos / llvm-project-archived public Read only

0
0
Text · 95.2 KiB · 84b962b Raw
2391 lines · plain
1//===-- RISCVInstrInfo.td - Target Description for RISC-V --*- tablegen -*-===//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 RISC-V instructions in TableGen format.10//11//===----------------------------------------------------------------------===//12 13//===----------------------------------------------------------------------===//14// RISC-V specific DAG Nodes.15//===----------------------------------------------------------------------===//16 17class RVSDNode<string opcode, SDTypeProfile type_profile,18               list<SDNodeProperty> properties = []>19    : SDNode<"RISCVISD::" # opcode, type_profile, properties> {20  bit HasPassthruOp = false;21  bit HasMaskOp = false;22  let TSFlags{0} = HasPassthruOp;23  let TSFlags{1} = HasMaskOp;24}25 26// Target-independent type requirements, but with target-specific formats.27def SDT_CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>,28                                       SDTCisVT<1, i32>]>;29def SDT_CallSeqEnd   : SDCallSeqEnd<[SDTCisVT<0, i32>,30                                     SDTCisVT<1, i32>]>;31 32// Target-dependent type requirements.33def SDT_RISCVCall     : SDTypeProfile<0, -1, [SDTCisVT<0, XLenVT>]>;34def SDT_RISCVSelectCC : SDTypeProfile<1, 5, [SDTCisSameAs<1, 2>,35                                             SDTCisVT<3, OtherVT>,36                                             SDTCisSameAs<0, 4>,37                                             SDTCisSameAs<4, 5>]>;38def SDT_RISCVBrCC : SDTypeProfile<0, 4, [SDTCisSameAs<0, 1>,39                                         SDTCisVT<2, OtherVT>,40                                         SDTCisVT<3, OtherVT>]>;41def SDT_RISCVIntUnaryOpW : SDTypeProfile<1, 1, [42  SDTCisSameAs<0, 1>, SDTCisVT<0, i64>43]>;44def SDT_RISCVIntBinOpW : SDTypeProfile<1, 2, [45  SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisVT<0, i64>46]>;47 48// Target-independent nodes, but with target-specific formats.49def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_CallSeqStart,50                           [SDNPHasChain, SDNPOutGlue]>;51def callseq_end   : SDNode<"ISD::CALLSEQ_END", SDT_CallSeqEnd,52                           [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;53 54def riscv_call      : RVSDNode<"CALL", SDT_RISCVCall,55                               [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,56                                SDNPVariadic]>;57def riscv_tail      : RVSDNode<"TAIL", SDT_RISCVCall,58                               [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,59                                SDNPVariadic]>;60 61// Software guarded calls for large code model62def riscv_sw_guarded_call : RVSDNode<"SW_GUARDED_CALL", SDT_RISCVCall,63                                     [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,64                                      SDNPVariadic]>;65def riscv_sw_guarded_tail : RVSDNode<"SW_GUARDED_TAIL", SDT_RISCVCall,66                                     [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,67                                      SDNPVariadic]>;68 69def riscv_ret_glue  : RVSDNode<"RET_GLUE", SDTNone,70                               [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;71def riscv_sret_glue : RVSDNode<"SRET_GLUE", SDTNone,72                               [SDNPHasChain, SDNPOptInGlue]>;73def riscv_mret_glue : RVSDNode<"MRET_GLUE", SDTNone,74                               [SDNPHasChain, SDNPOptInGlue]>;75def riscv_mnret_glue : RVSDNode<"MNRET_GLUE", SDTNone,76                                [SDNPHasChain, SDNPOptInGlue]>;77def riscv_mileaveret_glue : RVSDNode<"QC_C_MILEAVERET_GLUE", SDTNone,78                                     [SDNPHasChain, SDNPOptInGlue]>;79 80// Select with condition operator - This selects between a true value and81// a false value (ops #3 and #4) based on the boolean result of comparing82// the lhs and rhs (ops #0 and #1) of a conditional expression with the83// condition code in op #2, a XLenVT constant from the ISD::CondCode enum.84// The lhs and rhs are XLenVT integers. The true and false values can be85// integer or floating point.86def riscv_selectcc  : RVSDNode<"SELECT_CC", SDT_RISCVSelectCC>;87def riscv_brcc      : RVSDNode<"BR_CC", SDT_RISCVBrCC,88                               [SDNPHasChain]>;89 90// Software guarded BRIND node. Operand is the target address.91def riscv_sw_guarded_brind : RVSDNode<"SW_GUARDED_BRIND",92                                      SDTBrind, [SDNPHasChain]>;93 94// RV64I shifts, directly matching the semantics of the named RISC-V95// instructions.96def riscv_sllw      : RVSDNode<"SLLW", SDT_RISCVIntBinOpW>;97def riscv_sraw      : RVSDNode<"SRAW", SDT_RISCVIntBinOpW>;98def riscv_srlw      : RVSDNode<"SRLW", SDT_RISCVIntBinOpW>;99 100// Reads value of CSR. The first operand is the address of the required CSR.101// The result is the read value.102def riscv_read_csr  : RVSDNode<"READ_CSR",103                               SDTypeProfile<1, 1, [SDTCisInt<0>,104                                                    SDTCisInt<1>]>,105                               [SDNPHasChain]>;106// Write value to CSR. The first operand is the address of the required CSR,107// the second is the value to write.108def riscv_write_csr : RVSDNode<"WRITE_CSR",109                               SDTypeProfile<0, 2, [SDTCisInt<0>,110                                                    SDTCisInt<1>]>,111                               [SDNPHasChain]>;112 113// Read and write value of CSR. The first operand is the address of the114// required CSR, the second is the value to write, and the result is the115// read value (before modification).116def riscv_swap_csr  : RVSDNode<"SWAP_CSR",117                               SDTypeProfile<1, 2, [SDTCisInt<0>,118                                                    SDTCisInt<1>,119                                                    SDTCisInt<2>]>,120                               [SDNPHasChain]>;121 122// Clear bits of CSR. The first operand is the address of the required CSR,123// the second is the bitmask of cleared bits.124def riscv_clear_csr  : RVSDNode<"CLEAR_CSR",125                               SDTypeProfile<0, 2, [SDTCisInt<0>,126                                                    SDTCisInt<1>]>,127                               [SDNPHasChain]>;128 129// Set bits of CSR. The first operand is the address of the required CSR,130// the second is the bitmask of bits to set.131def riscv_set_csr  : RVSDNode<"SET_CSR",132                               SDTypeProfile<0, 2, [SDTCisInt<0>,133                                                    SDTCisInt<1>]>,134                               [SDNPHasChain]>;135 136// A read of the 64-bit counter CSR on a 32-bit target (returns (Lo, Hi)).137// It takes a chain operand and another two target constant operands (the138// CSR numbers of the low and high parts of the counter).139def riscv_read_counter_wide : RVSDNode<"READ_COUNTER_WIDE",140                                       SDTypeProfile<2, 2, [SDTCisVT<0, i32>,141                                                            SDTCisVT<1, i32>,142                                                            SDTCisInt<2>,143                                                            SDTCisInt<3>]>,144                                       [SDNPHasChain, SDNPSideEffect]>;145 146// Add the Lo 12 bits from an address. Selected to ADDI.147def riscv_add_lo : RVSDNode<"ADD_LO", SDTIntBinOp>;148 149// Get the Hi 20 bits from an address. Selected to LUI.150def riscv_hi : RVSDNode<"HI", SDTIntUnaryOp>;151 152// Represents an AUIPC+ADDI pair. Selected to PseudoLLA.153def riscv_lla : RVSDNode<"LLA", SDTIntUnaryOp>;154 155// Selected as PseudoAddTPRel. Used to emit a TP-relative relocation.156def riscv_add_tprel : RVSDNode<"ADD_TPREL",157                               SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>,158                                                    SDTCisSameAs<0, 2>,159                                                    SDTCisSameAs<0, 3>,160                                                    SDTCisInt<0>]>>;161 162// To avoid stack clash, allocation is performed by block and each block is163// probed.164def riscv_probed_alloca : RVSDNode<"PROBED_ALLOCA",165                                   SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>,166                                   [SDNPHasChain, SDNPMayStore]>;167 168 169defvar GPRPairVT = untyped;170 171/// Turn a pair of `i<xlen>`s into an even-odd register pair (`untyped`).172/// - Output: `untyped` even-odd register pair173/// - Input 0: `i<xlen>` low-order bits, for even register.174/// - Input 1: `i<xlen>` high-order bits, for odd register.175def riscv_build_gpr_pair : RVSDNode<"BuildGPRPair",176                                    SDTypeProfile<1, 2, [SDTCisVT<0, GPRPairVT>,177                                                         SDTCisVT<1, XLenVT>,178                                                         SDTCisVT<2, XLenVT>]>>;179 180/// Turn an even-odd register pair (`untyped`) into a pair of `i<xlen>`s.181/// - Output 0: `i<xlen>` low-order bits, from even register.182/// - Output 1: `i<xlen>` high-order bits, from odd register.183/// - Input: `untyped` even-odd register pair184def riscv_split_gpr_pair : RVSDNode<"SplitGPRPair",185                                    SDTypeProfile<2, 1, [SDTCisVT<0, XLenVT>,186                                                         SDTCisVT<1, XLenVT>,187                                                         SDTCisVT<2, GPRPairVT>]>>;188 189//===----------------------------------------------------------------------===//190// Operand and SDNode transformation definitions.191//===----------------------------------------------------------------------===//192 193class ImmXLenAsmOperand<string prefix, string suffix = ""> : AsmOperandClass {194  let Name = prefix # "ImmXLen" # suffix;195  let RenderMethod = "addImmOperands";196  let DiagnosticType = !strconcat("Invalid", Name);197}198 199class ImmAsmOperand<string prefix, int width, string suffix> : AsmOperandClass {200  let Name = prefix # "Imm" # width # suffix;201  let RenderMethod = "addImmOperands";202  let DiagnosticType = !strconcat("Invalid", Name);203}204 205def ImmZeroAsmOperand : AsmOperandClass {206  let Name = "ImmZero";207  let RenderMethod = "addImmOperands";208  let DiagnosticType = !strconcat("Invalid", Name);209  let DiagnosticString = "immediate must be zero";210}211 212// A parse method for (${gpr}) or 0(${gpr}), where the 0 is be silently ignored.213def ZeroOffsetMemOpOperand : AsmOperandClass {214  let Name = "ZeroOffsetMemOpOperand";215  let RenderMethod = "addRegOperands";216  let PredicateMethod = "isGPR";217  let ParserMethod = "parseZeroOffsetMemOp";218}219 220class MemOperand<RegisterClass regClass> : RegisterOperand<regClass>{221  let OperandType = "OPERAND_MEMORY";222}223 224def GPRMemZeroOffset : MemOperand<GPR> {225  let ParserMatchClass = ZeroOffsetMemOpOperand;226  let PrintMethod = "printZeroOffsetMemOp";227}228 229def GPRMem : MemOperand<GPR>;230 231def SPMem : MemOperand<SP>;232 233def GPRCMem : MemOperand<GPRC>;234 235class SImmAsmOperand<int width, string suffix = "">236    : ImmAsmOperand<"S", width, suffix> {237}238 239class UImmAsmOperand<int width, string suffix = "">240    : ImmAsmOperand<"U", width, suffix> {241}242 243class BareSImmNLsb0AsmOperand<int width>244    : ImmAsmOperand<"BareS", width, "Lsb0"> {245  let PredicateMethod = "isBareSimmNLsb0<" # width # ">";246}247 248class RISCVOp<ValueType vt = XLenVT> : Operand<vt> {249  let OperandNamespace = "RISCVOp";250}251 252class RISCVUImmOp<int bitsNum> : RISCVOp {253  let ParserMatchClass = UImmAsmOperand<bitsNum>;254  let EncoderMethod = "getImmOpValue";255  let DecoderMethod = "decodeUImmOperand<" # bitsNum # ">";256  let OperandType = "OPERAND_UIMM" # bitsNum;257  let MCOperandPredicate = [{258    int64_t Imm;259    if (!MCOp.evaluateAsConstantImm(Imm))260      return false;261    return isUInt<}]# bitsNum #[{>(Imm);262  }];263}264 265class RISCVUImmLeafOp<int bitsNum> :266  RISCVUImmOp<bitsNum>, ImmLeaf<XLenVT, "return isUInt<" # bitsNum # ">(Imm);">;267 268class RISCVSImmOp<int bitsNum> : RISCVOp {269  let ParserMatchClass = SImmAsmOperand<bitsNum>;270  let EncoderMethod = "getImmOpValue";271  let DecoderMethod = "decodeSImmOperand<" # bitsNum # ">";272  let OperandType = "OPERAND_SIMM" # bitsNum;273  let MCOperandPredicate = [{274    int64_t Imm;275    if (!MCOp.evaluateAsConstantImm(Imm))276      return false;277    return isInt<}] # bitsNum # [{>(Imm);278  }];279}280 281class RISCVSImmLeafOp<int bitsNum> :282  RISCVSImmOp<bitsNum>, ImmLeaf<XLenVT, "return isInt<" # bitsNum # ">(Imm);">;283 284def FenceArg : AsmOperandClass {285  let Name = "FenceArg";286  let RenderMethod = "addFenceArgOperands";287  let ParserMethod = "parseFenceArg";288}289 290def fencearg : RISCVOp {291  let ParserMatchClass = FenceArg;292  let PrintMethod = "printFenceArg";293  let DecoderMethod = "decodeUImmOperand<4>";294  let OperandType = "OPERAND_UIMM4";295}296 297def UImmLog2XLenAsmOperand : AsmOperandClass {298  let Name = "UImmLog2XLen";299  let RenderMethod = "addImmOperands";300  let DiagnosticType = "InvalidUImmLog2XLen";301}302 303def uimmlog2xlen : RISCVOp, ImmLeaf<XLenVT, [{304  if (Subtarget->is64Bit())305    return isUInt<6>(Imm);306  return isUInt<5>(Imm);307}]> {308  let ParserMatchClass = UImmLog2XLenAsmOperand;309  let DecoderMethod = "decodeUImmLog2XLenOperand";310  let MCOperandPredicate = [{311    int64_t Imm;312    if (!MCOp.evaluateAsConstantImm(Imm))313      return false;314    if (STI.getTargetTriple().isArch64Bit())315      return isUInt<6>(Imm);316    return isUInt<5>(Imm);317  }];318  let OperandType = "OPERAND_UIMMLOG2XLEN";319}320 321def InsnDirectiveOpcode : AsmOperandClass {322  let Name = "InsnDirectiveOpcode";323  let ParserMethod = "parseInsnDirectiveOpcode";324  let RenderMethod = "addImmOperands";325  let PredicateMethod = "isImm";326}327 328def uimm1 : RISCVUImmLeafOp<1>;329def uimm2 : RISCVUImmLeafOp<2>;330def uimm3 : RISCVUImmLeafOp<3>;331def uimm4 : RISCVUImmLeafOp<4>;332def uimm5 : RISCVUImmLeafOp<5>;333def uimm6 : RISCVUImmLeafOp<6>;334def uimm7_opcode : RISCVUImmOp<7> {335  let ParserMatchClass = InsnDirectiveOpcode;336}337def uimm7 : RISCVUImmLeafOp<7>;338def uimm8 : RISCVUImmOp<8>;339def uimm16 : RISCVUImmOp<16>;340def uimm32 : RISCVUImmOp<32>;341def uimm48 : RISCVUImmOp<48>;342def uimm64 : RISCVUImmOp<64>;343 344def simm12_lo : RISCVSImmLeafOp<12> {345  let ParserMatchClass = SImmAsmOperand<12, "LO">;346  let MCOperandPredicate = [{347    int64_t Imm;348    if (MCOp.evaluateAsConstantImm(Imm))349      return isInt<12>(Imm);350    return MCOp.isBareSymbolRef();351  }];352}353 354// A 12-bit signed immediate which cannot fit in 6-bit signed immediate,355// but even negative value fit in 12-bit.356def simm12_no6 : ImmLeaf<XLenVT, [{357  return isInt<12>(Imm) && !isInt<6>(Imm) && isInt<12>(-Imm);}]>;358 359class BareSImm13Lsb0MaybeSym : Operand<OtherVT> {360  let MCOperandPredicate = [{361    int64_t Imm;362    if (MCOp.evaluateAsConstantImm(Imm))363      return isShiftedInt<12, 1>(Imm);364    return MCOp.isBareSymbolRef();365  }];366}367 368// A 13-bit signed immediate where the least significant bit is zero. The ImmLeaf369// is needed so that the CompressInstEmitter can correctly add checks for the370// compress patterns that involve instructions that use this operand. Similar to371// bare_simm9_lsb0 in RISCVInstrInfoC.td.372def bare_simm13_lsb0 : BareSImm13Lsb0MaybeSym,373                       ImmLeaf<XLenVT, [{return isShiftedInt<12, 1>(Imm);}]> {374  let ParserMatchClass = BareSImmNLsb0AsmOperand<13>;375  let PrintMethod = "printBranchOperand";376  let EncoderMethod = "getImmOpValueAsrN<1>";377  let DecoderMethod = "decodeSImmOperandAndLslN<13, 1>";378  let OperandType = "OPERAND_PCREL";379}380 381// We need this (sort of) duplicate definition since adding ImmLeaf to382// bare_simm13_lsb0 above makes it not sit well with codegen patterns where it383// is used to match with a basic block (eg. BccPat<>).384def bare_simm13_lsb0_bb : BareSImm13Lsb0MaybeSym;385 386class UImm20OperandMaybeSym : RISCVUImmOp<20> {387  let MCOperandPredicate = [{388    int64_t Imm;389    if (MCOp.evaluateAsConstantImm(Imm))390      return isUInt<20>(Imm);391    return MCOp.isBareSymbolRef();392  }];393}394 395def uimm20_lui : UImm20OperandMaybeSym {396  let ParserMatchClass = UImmAsmOperand<20, "LUI">;397}398def uimm20_auipc : UImm20OperandMaybeSym {399  let ParserMatchClass = UImmAsmOperand<20, "AUIPC">;400}401 402def uimm20 : RISCVUImmOp<20>;403 404def Simm21Lsb0JALAsmOperand : BareSImmNLsb0AsmOperand<21> {405  let ParserMethod = "parseJALOffset";406}407 408// A 21-bit signed immediate where the least significant bit is zero.409def simm21_lsb0_jal : Operand<OtherVT>,410                      ImmLeaf<XLenVT, [{return isShiftedInt<20, 1>(Imm);}]>  {411  let ParserMatchClass = Simm21Lsb0JALAsmOperand;412  let PrintMethod = "printBranchOperand";413  let EncoderMethod = "getImmOpValueAsrN<1>";414  let DecoderMethod = "decodeSImmOperandAndLslN<21, 1>";415  let MCOperandPredicate = [{416    int64_t Imm;417    if (MCOp.evaluateAsConstantImm(Imm))418      return isShiftedInt<20, 1>(Imm);419    return MCOp.isBareSymbolRef();420  }];421  let OperandType = "OPERAND_PCREL";422}423 424def BareSymbol : AsmOperandClass {425  let Name = "BareSymbol";426  let RenderMethod = "addImmOperands";427  let DiagnosticType = "InvalidBareSymbol";428  let DiagnosticString = "operand must be a bare symbol name";429  let ParserMethod = "parseBareSymbol";430}431 432// A bare symbol.433def bare_symbol : Operand<XLenVT> {434  let ParserMatchClass = BareSymbol;435}436 437def CallSymbol : AsmOperandClass {438  let Name = "CallSymbol";439  let RenderMethod = "addImmOperands";440  let DiagnosticType = "InvalidCallSymbol";441  let DiagnosticString = "operand must be a bare symbol name";442  let ParserMethod = "parseCallSymbol";443}444 445// A bare symbol used in call/tail only.446def call_symbol : Operand<XLenVT> {447  let ParserMatchClass = CallSymbol;448}449 450def PseudoJumpSymbol : AsmOperandClass {451  let Name = "PseudoJumpSymbol";452  let RenderMethod = "addImmOperands";453  let DiagnosticType = "InvalidPseudoJumpSymbol";454  let DiagnosticString = "operand must be a valid jump target";455  let ParserMethod = "parsePseudoJumpSymbol";456}457 458// A bare symbol used for pseudo jumps only.459def pseudo_jump_symbol : Operand<XLenVT> {460  let ParserMatchClass = PseudoJumpSymbol;461}462 463def TPRelAddSymbol : AsmOperandClass {464  let Name = "TPRelAddSymbol";465  let RenderMethod = "addImmOperands";466  let DiagnosticType = "InvalidTPRelAddSymbol";467  let DiagnosticString = "operand must be a symbol with %tprel_add specifier";468  let ParserMethod = "parseOperandWithSpecifier";469}470 471// A bare symbol with the %tprel_add variant.472def tprel_add_symbol : Operand<XLenVT> {473  let ParserMatchClass = TPRelAddSymbol;474}475 476def CSRSystemRegister : AsmOperandClass {477  let Name = "CSRSystemRegister";478  let ParserMethod = "parseCSRSystemRegister";479  let DiagnosticType = "InvalidCSRSystemRegister";480}481 482def csr_sysreg : RISCVOp, TImmLeaf<XLenVT, "return isUInt<12>(Imm);"> {483  let ParserMatchClass = CSRSystemRegister;484  let PrintMethod = "printCSRSystemRegister";485  let DecoderMethod = "decodeUImmOperand<12>";486  let OperandType = "OPERAND_UIMM12";487}488 489// A parameterized register class alternative to i32imm/i64imm from Target.td.490def ixlenimm : Operand<XLenVT>;491 492// Condition code used by select and short forward branch pseudos.493def cond_code : RISCVOp {494  let OperandType = "OPERAND_COND_CODE";495}496 497def ixlenimm_li : Operand<XLenVT> {498  let ParserMatchClass = ImmXLenAsmOperand<"", "LI">;499}500 501// Accepts subset of LI operands, used by LAImm and LLAImm502def ixlenimm_li_restricted : Operand<XLenVT> {503  let ParserMatchClass = ImmXLenAsmOperand<"", "LI_Restricted">;504}505 506// Standalone (codegen-only) immleaf patterns.507 508// A 12-bit signed immediate plus one where the imm range will be -2047~2048.509def simm12_plus1 : ImmLeaf<XLenVT,510  [{return (isInt<12>(Imm) && Imm != -2048) || Imm == 2048;}]>;511 512// A 6-bit constant greater than 32.513def uimm6gt32 : ImmLeaf<XLenVT, [{514  return isUInt<6>(Imm) && Imm > 32;515}]>;516 517// Addressing modes.518def AddrRegImm : ComplexPattern<iPTR, 2, "SelectAddrRegImm">;519 520class AddrRegRegScale<int N>521    : ComplexPattern<iPTR, 3, "SelectAddrRegRegScale<"#N#">">;522class AddrRegZextRegScale<int N>523    : ComplexPattern<i64, 3, "SelectAddrRegZextRegScale<"#N#", 32>",524                     [], [], 10>;525 526// Return the negation of an immediate value.527def NegImm : SDNodeXForm<imm, [{528  return CurDAG->getSignedTargetConstant(-N->getSExtValue(), SDLoc(N),529                                         N->getValueType(0));530}]>;531def GINegImm : GICustomOperandRenderer<"renderNegImm">,532  GISDNodeXFormEquiv<NegImm>;533 534// Return an immediate value minus 32.535def ImmSub32 : SDNodeXForm<imm, [{536  return CurDAG->getSignedTargetConstant(N->getSExtValue() - 32, SDLoc(N),537                                         N->getValueType(0));538}]>;539 540// Return an immediate subtracted from XLen.541def ImmSubFromXLen : SDNodeXForm<imm, [{542  uint64_t XLen = Subtarget->getXLen();543  return CurDAG->getTargetConstant(XLen - N->getZExtValue(), SDLoc(N),544                                   N->getValueType(0));545}]>;546def GIImmSubFromXLen : GICustomOperandRenderer<"renderImmSubFromXLen">,547  GISDNodeXFormEquiv<ImmSubFromXLen>;548 549// Return an immediate subtracted from 32.550def ImmSubFrom32 : SDNodeXForm<imm, [{551  return CurDAG->getTargetConstant(32 - N->getZExtValue(), SDLoc(N),552                                   N->getValueType(0));553}]>;554def GIImmSubFrom32 : GICustomOperandRenderer<"renderImmSubFrom32">,555  GISDNodeXFormEquiv<ImmSubFrom32>;556 557// Check if (add r, imm) can be optimized to (ADDI (ADDI r, imm0), imm1),558// in which imm = imm0 + imm1 and both imm0 and imm1 are simm12. We make imm0559// as large as possible and imm1 as small as possible so that we might be able560// to use c.addi for the small immediate.561def AddiPair : ImmLeaf<XLenVT, [{562  // The immediate operand must be in range [-4096,-2049] or [2048,4094].563  return (-4096 <= Imm && Imm <= -2049) || (2048 <= Imm && Imm <= 4094);564}]>;565 566// Return imm - (imm < 0 ? -2048 : 2047).567def AddiPairImmSmall : SDNodeXForm<imm, [{568  int64_t Imm = N->getSExtValue();569  int64_t Adj = N->getSExtValue() < 0 ? -2048 : 2047;570  return CurDAG->getSignedTargetConstant(Imm - Adj, SDLoc(N),571                                         N->getValueType(0));572}]>;573def GIAddiPairImmSmall : GICustomOperandRenderer<"renderAddiPairImmSmall">,574                         GISDNodeXFormEquiv<AddiPairImmSmall>;575 576// Return -2048 if immediate is negative or 2047 if positive. These are the577// largest simm12 values.578def AddiPairImmLarge : SDNodeXForm<imm, [{579  int64_t Imm = N->getSExtValue() < 0 ? -2048 : 2047;580  return CurDAG->getSignedTargetConstant(Imm, SDLoc(N), N->getValueType(0));581}]>;582def GIAddiPairImmLarge : GICustomOperandRenderer<"renderAddiPairImmLarge">,583                         GISDNodeXFormEquiv<AddiPairImmLarge>;584 585def TrailingZeros : SDNodeXForm<imm, [{586  return CurDAG->getTargetConstant(llvm::countr_zero(N->getZExtValue()),587                                   SDLoc(N), N->getValueType(0));588}]>;589def GITrailingZeros : GICustomOperandRenderer<"renderTrailingZeros">,590  GISDNodeXFormEquiv<TrailingZeros>;591 592def XLenSubTrailingOnes : SDNodeXForm<imm, [{593  uint64_t XLen = Subtarget->getXLen();594  uint64_t TrailingOnes = llvm::countr_one(N->getZExtValue());595  return CurDAG->getTargetConstant(XLen - TrailingOnes, SDLoc(N),596                                   N->getValueType(0));597}]>;598def GIXLenSubTrailingOnes : GICustomOperandRenderer<"renderXLenSubTrailingOnes">,599  GISDNodeXFormEquiv<XLenSubTrailingOnes>;600 601// Checks if this mask is a non-empty sequence of ones starting at the602// most/least significant bit with the remainder zero and exceeds simm32/simm12.603def LeadingOnesMask : ImmLeaf<XLenVT, [{604  return !isInt<32>(Imm) && isMask_64(~Imm);605}], TrailingZeros>;606 607def TrailingOnesMask : IntImmLeaf<XLenVT, [{608  return !isInt<12>(Imm.getSExtValue()) && isMask_64(Imm.getZExtValue());609}], XLenSubTrailingOnes>;610 611// Similar to LeadingOnesMask, but only consider leading ones in the lower 32612// bits.613def LeadingOnesWMask : ImmLeaf<XLenVT, [{614  // If the value is a uint32 but not an int32, it must have bit 31 set and615  // bits 63:32 cleared. After that we're looking for a shifted mask but not616  // an all ones mask.617  return !isInt<32>(Imm) && isUInt<32>(Imm) && isShiftedMask_64(Imm) &&618         Imm != UINT64_C(0xffffffff);619}], TrailingZeros>;620 621//===----------------------------------------------------------------------===//622// Instruction Formats623//===----------------------------------------------------------------------===//624 625include "RISCVInstrFormats.td"626include "RISCVInstrFormatsC.td"627include "RISCVInstrFormatsV.td"628 629//===----------------------------------------------------------------------===//630// Instruction Class Templates631//===----------------------------------------------------------------------===//632 633class BranchCC_rri<bits<3> funct3, string opcodestr>634    : RVInstB<funct3, OPC_BRANCH, (outs),635              (ins GPR:$rs1, GPR:$rs2, bare_simm13_lsb0:$imm12),636              opcodestr, "$rs1, $rs2, $imm12">,637      Sched<[WriteJmp, ReadJmp, ReadJmp]> {638  let isBranch = 1;639  let isTerminator = 1;640  let hasSideEffects = 0;641  let mayLoad = 0;642  let mayStore = 0;643}644 645let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {646class Load_ri<bits<3> funct3, string opcodestr, DAGOperand rty = GPR>647    : RVInstI<funct3, OPC_LOAD, (outs rty:$rd), (ins GPRMem:$rs1, simm12_lo:$imm12),648              opcodestr, "$rd, ${imm12}(${rs1})">;649 650class HLoad_r<bits<7> funct7, bits<5> funct5, string opcodestr>651    : RVInstR<funct7, 0b100, OPC_SYSTEM, (outs GPR:$rd),652              (ins GPRMemZeroOffset:$rs1), opcodestr, "$rd, $rs1"> {653  let rs2 = funct5;654}655}656 657// Operands for stores are in the order srcreg, base, offset rather than658// reflecting the order these fields are specified in the instruction659// encoding.660let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {661class Store_rri<bits<3> funct3, string opcodestr, DAGOperand rty = GPR>662    : RVInstS<funct3, OPC_STORE, (outs),663              (ins rty:$rs2, GPRMem:$rs1, simm12_lo:$imm12),664              opcodestr, "$rs2, ${imm12}(${rs1})">;665 666class HStore_rr<bits<7> funct7, string opcodestr>667    : RVInstR<funct7, 0b100, OPC_SYSTEM, (outs),668              (ins GPR:$rs2, GPRMemZeroOffset:$rs1),669               opcodestr, "$rs2, $rs1"> {670  let rd = 0;671}672}673 674let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in675class ALU_ri<bits<3> funct3, string opcodestr>676    : RVInstI<funct3, OPC_OP_IMM, (outs GPR:$rd), (ins GPR:$rs1, simm12_lo:$imm12),677              opcodestr, "$rd, $rs1, $imm12">,678      Sched<[WriteIALU, ReadIALU]>;679 680let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in681class Shift_ri<bits<5> imm11_7, bits<3> funct3, string opcodestr>682    : RVInstIShift<imm11_7, funct3, OPC_OP_IMM, (outs GPR:$rd),683                   (ins GPR:$rs1, uimmlog2xlen:$shamt), opcodestr,684                   "$rd, $rs1, $shamt">;685 686let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in687class ALU_rr<bits<7> funct7, bits<3> funct3, string opcodestr,688             bit Commutable = 0>689    : RVInstR<funct7, funct3, OPC_OP, (outs GPR:$rd), (ins GPR:$rs1, GPR:$rs2),690              opcodestr, "$rd, $rs1, $rs2"> {691  let isCommutable = Commutable;692}693 694let hasNoSchedulingInfo = 1,695    hasSideEffects = 1, mayLoad = 0, mayStore = 0 in696class CSR_ir<bits<3> funct3, string opcodestr>697    : RVInstI<funct3, OPC_SYSTEM, (outs GPR:$rd), (ins csr_sysreg:$imm12, GPR:$rs1),698              opcodestr, "$rd, $imm12, $rs1">, Sched<[WriteCSR, ReadCSR]>;699 700let hasNoSchedulingInfo = 1,701    hasSideEffects = 1, mayLoad = 0, mayStore = 0 in702class CSR_ii<bits<3> funct3, string opcodestr>703    : RVInstI<funct3, OPC_SYSTEM, (outs GPR:$rd),704              (ins csr_sysreg:$imm12, uimm5:$rs1),705              opcodestr, "$rd, $imm12, $rs1">, Sched<[WriteCSR]>;706 707let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in708class ShiftW_ri<bits<7> imm11_5, bits<3> funct3, string opcodestr>709    : RVInstIShiftW<imm11_5, funct3, OPC_OP_IMM_32, (outs GPR:$rd),710                    (ins GPR:$rs1, uimm5:$shamt), opcodestr,711                    "$rd, $rs1, $shamt">;712 713let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in714class ALUW_rr<bits<7> funct7, bits<3> funct3, string opcodestr,715              bit Commutable = 0>716    : RVInstR<funct7, funct3, OPC_OP_32, (outs GPR:$rd),717              (ins GPR:$rs1, GPR:$rs2), opcodestr, "$rd, $rs1, $rs2"> {718  let isCommutable = Commutable;719}720 721let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in722class Priv<string opcodestr, bits<7> funct7>723    : RVInstR<funct7, 0b000, OPC_SYSTEM, (outs), (ins), opcodestr, "">;724 725let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in726class Priv_rr<string opcodestr, bits<7> funct7>727    : RVInstR<funct7, 0b000, OPC_SYSTEM, (outs), (ins GPR:$rs1, GPR:$rs2),728              opcodestr, "$rs1, $rs2"> {729  let rd = 0;730}731 732let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in733class Unary_r<bits<12> imm12, bits<3> funct3, string opcodestr>734    : RVInstIUnary<imm12, funct3, OPC_OP_IMM, (outs GPR:$rd), (ins GPR:$rs1),735                   opcodestr, "$rd, $rs1">;736 737let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in738class UnaryW_r<bits<12> imm12, bits<3> funct3, string opcodestr>739    : RVInstIUnary<imm12, funct3, OPC_OP_IMM_32, (outs GPR:$rd), (ins GPR:$rs1),740                   opcodestr, "$rd, $rs1">;741 742//===----------------------------------------------------------------------===//743// Instructions744//===----------------------------------------------------------------------===//745 746let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {747let isReMaterializable = 1, isAsCheapAsAMove = 1,748    IsSignExtendingOpW = 1 in749def LUI : RVInstU<OPC_LUI, (outs GPR:$rd), (ins uimm20_lui:$imm20),750                  "lui", "$rd, $imm20">, Sched<[WriteIALU]>;751 752def AUIPC : RVInstU<OPC_AUIPC, (outs GPR:$rd), (ins uimm20_auipc:$imm20),753                    "auipc", "$rd, $imm20">, Sched<[WriteIALU]>;754 755def JAL : RVInstJ<OPC_JAL, (outs GPR:$rd), (ins simm21_lsb0_jal:$imm20),756                  "jal", "$rd, $imm20">, Sched<[WriteJal]>;757 758def JALR : RVInstI<0b000, OPC_JALR, (outs GPR:$rd),759                   (ins GPR:$rs1, simm12_lo:$imm12),760                   "jalr", "$rd, ${imm12}(${rs1})">,761           Sched<[WriteJalr, ReadJalr]>;762} // hasSideEffects = 0, mayLoad = 0, mayStore = 0763 764def BEQ  : BranchCC_rri<0b000, "beq">;765def BNE  : BranchCC_rri<0b001, "bne">;766def BLT  : BranchCC_rri<0b100, "blt">;767def BGE  : BranchCC_rri<0b101, "bge">;768def BLTU : BranchCC_rri<0b110, "bltu">;769def BGEU : BranchCC_rri<0b111, "bgeu">;770 771let IsSignExtendingOpW = 1, canFoldAsLoad = 1, isReMaterializable = 1 in {772def LB  : Load_ri<0b000, "lb">, Sched<[WriteLDB, ReadMemBase]>;773def LH  : Load_ri<0b001, "lh">, Sched<[WriteLDH, ReadMemBase]>;774def LW  : Load_ri<0b010, "lw">, Sched<[WriteLDW, ReadMemBase]>;775def LBU : Load_ri<0b100, "lbu">, Sched<[WriteLDB, ReadMemBase]>;776def LHU : Load_ri<0b101, "lhu">, Sched<[WriteLDH, ReadMemBase]>;777}778 779def SB : Store_rri<0b000, "sb">, Sched<[WriteSTB, ReadStoreData, ReadMemBase]>;780def SH : Store_rri<0b001, "sh">, Sched<[WriteSTH, ReadStoreData, ReadMemBase]>;781def SW : Store_rri<0b010, "sw">, Sched<[WriteSTW, ReadStoreData, ReadMemBase]>;782 783// ADDI isn't always rematerializable, but isReMaterializable will be used as784// a hint which is verified in isReMaterializableImpl.785let isReMaterializable = 1, isAsCheapAsAMove = 1 in786def ADDI  : ALU_ri<0b000, "addi">;787 788let IsSignExtendingOpW = 1 in {789def SLTI  : ALU_ri<0b010, "slti">;790def SLTIU : ALU_ri<0b011, "sltiu">;791}792 793let isReMaterializable = 1, isAsCheapAsAMove = 1 in {794def XORI  : ALU_ri<0b100, "xori">;795def ORI   : ALU_ri<0b110, "ori">;796}797 798def ANDI  : ALU_ri<0b111, "andi">;799 800def SLLI : Shift_ri<0b00000, 0b001, "slli">,801           Sched<[WriteShiftImm, ReadShiftImm]>;802def SRLI : Shift_ri<0b00000, 0b101, "srli">,803           Sched<[WriteShiftImm, ReadShiftImm]>;804def SRAI : Shift_ri<0b01000, 0b101, "srai">,805           Sched<[WriteShiftImm, ReadShiftImm]>;806 807def ADD  : ALU_rr<0b0000000, 0b000, "add", Commutable=1>,808           Sched<[WriteIALU, ReadIALU, ReadIALU]>;809def SUB  : ALU_rr<0b0100000, 0b000, "sub">,810           Sched<[WriteIALU, ReadIALU, ReadIALU]>;811def SLL  : ALU_rr<0b0000000, 0b001, "sll">,812           Sched<[WriteShiftReg, ReadShiftReg, ReadShiftReg]>;813let IsSignExtendingOpW = 1 in {814def SLT  : ALU_rr<0b0000000, 0b010, "slt">,815           Sched<[WriteIALU, ReadIALU, ReadIALU]>;816def SLTU : ALU_rr<0b0000000, 0b011, "sltu">,817           Sched<[WriteIALU, ReadIALU, ReadIALU]>;818}819def XOR  : ALU_rr<0b0000000, 0b100, "xor", Commutable=1>,820           Sched<[WriteIALU, ReadIALU, ReadIALU]>;821def SRL  : ALU_rr<0b0000000, 0b101, "srl">,822           Sched<[WriteShiftReg, ReadShiftReg, ReadShiftReg]>;823def SRA  : ALU_rr<0b0100000, 0b101, "sra">,824           Sched<[WriteShiftReg, ReadShiftReg, ReadShiftReg]>;825def OR   : ALU_rr<0b0000000, 0b110, "or", Commutable=1>,826           Sched<[WriteIALU, ReadIALU, ReadIALU]>;827def AND  : ALU_rr<0b0000000, 0b111, "and", Commutable=1>,828           Sched<[WriteIALU, ReadIALU, ReadIALU]>;829 830let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in {831def FENCE : RVInstI<0b000, OPC_MISC_MEM, (outs),832                    (ins fencearg:$pred, fencearg:$succ),833                    "fence", "$pred, $succ">, Sched<[]> {834  bits<4> pred;835  bits<4> succ;836 837  let rs1 = 0;838  let rd = 0;839  let imm12 = {0b0000,pred,succ};840}841 842def FENCE_TSO : RVInstI<0b000, OPC_MISC_MEM, (outs), (ins), "fence.tso", "">, Sched<[]> {843  let rs1 = 0;844  let rd = 0;845  let imm12 = {0b1000,0b0011,0b0011};846}847 848def FENCE_I : RVInstI<0b001, OPC_MISC_MEM, (outs), (ins), "fence.i", "">, Sched<[]> {849  let rs1 = 0;850  let rd = 0;851  let imm12 = 0;852}853 854def ECALL : RVInstI<0b000, OPC_SYSTEM, (outs), (ins), "ecall", "">, Sched<[WriteJmp]> {855  let rs1 = 0;856  let rd = 0;857  let imm12 = 0;858}859 860let isTrap = 1 in861def EBREAK : RVInstI<0b000, OPC_SYSTEM, (outs), (ins), "ebreak", "">,862             Sched<[]> {863  let rs1 = 0;864  let rd = 0;865  let imm12 = 1;866}867 868// This is a de facto standard (as set by GNU binutils) 32-bit unimplemented869// instruction (i.e., it should always trap, if your implementation has invalid870// instruction traps).871let isTrap = 1 in872def UNIMP : RVInstI<0b001, OPC_SYSTEM, (outs), (ins), "unimp", "">,873            Sched<[]> {874  let rs1 = 0;875  let rd = 0;876  let imm12 = 0b110000000000;877}878 879} // hasSideEffects = 1, mayLoad = 0, mayStore = 0880 881def CSRRW : CSR_ir<0b001, "csrrw">;882def CSRRS : CSR_ir<0b010, "csrrs">;883def CSRRC : CSR_ir<0b011, "csrrc">;884 885def CSRRWI : CSR_ii<0b101, "csrrwi">;886def CSRRSI : CSR_ii<0b110, "csrrsi">;887def CSRRCI : CSR_ii<0b111, "csrrci">;888 889/// RV64I instructions890 891let Predicates = [IsRV64] in {892let canFoldAsLoad = 1, isReMaterializable = 1 in {893def LWU   : Load_ri<0b110, "lwu">, Sched<[WriteLDW, ReadMemBase]>;894def LD    : Load_ri<0b011, "ld">, Sched<[WriteLDD, ReadMemBase]>;895}896def SD    : Store_rri<0b011, "sd">, Sched<[WriteSTD, ReadStoreData, ReadMemBase]>;897 898let IsSignExtendingOpW = 1 in {899let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in900def ADDIW : RVInstI<0b000, OPC_OP_IMM_32, (outs GPR:$rd),901                    (ins GPR:$rs1, simm12_lo:$imm12),902                    "addiw", "$rd, $rs1, $imm12">,903            Sched<[WriteIALU32, ReadIALU32]>;904 905def SLLIW : ShiftW_ri<0b0000000, 0b001, "slliw">,906            Sched<[WriteShiftImm32, ReadShiftImm32]>;907def SRLIW : ShiftW_ri<0b0000000, 0b101, "srliw">,908            Sched<[WriteShiftImm32, ReadShiftImm32]>;909def SRAIW : ShiftW_ri<0b0100000, 0b101, "sraiw">,910            Sched<[WriteShiftImm32, ReadShiftImm32]>;911 912def ADDW  : ALUW_rr<0b0000000, 0b000, "addw", Commutable=1>,913            Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>;914def SUBW  : ALUW_rr<0b0100000, 0b000, "subw">,915            Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>;916def SLLW  : ALUW_rr<0b0000000, 0b001, "sllw">,917            Sched<[WriteShiftReg32, ReadShiftReg32, ReadShiftReg32]>;918def SRLW  : ALUW_rr<0b0000000, 0b101, "srlw">,919            Sched<[WriteShiftReg32, ReadShiftReg32, ReadShiftReg32]>;920def SRAW  : ALUW_rr<0b0100000, 0b101, "sraw">,921            Sched<[WriteShiftReg32, ReadShiftReg32, ReadShiftReg32]>;922} // IsSignExtendingOpW = 1923} // Predicates = [IsRV64]924 925//===----------------------------------------------------------------------===//926// Privileged instructions927//===----------------------------------------------------------------------===//928 929let isBarrier = 1, isReturn = 1, isTerminator = 1 in {930def SRET : Priv<"sret", 0b0001000>, Sched<[]> {931  let rd = 0;932  let rs1 = 0;933  let rs2 = 0b00010;934}935 936def MRET : Priv<"mret", 0b0011000>, Sched<[]> {937  let rd = 0;938  let rs1 = 0;939  let rs2 = 0b00010;940}941 942let Predicates = [HasStdExtSmrnmi] in {943def MNRET : Priv<"mnret", 0b0111000>, Sched<[]> {944  let rd = 0;945  let rs1 = 0;946  let rs2 = 0b00010;947}948}// Predicates = [HasStdExtSmrnmi]949} // isBarrier = 1, isReturn = 1, isTerminator = 1950 951 952def WFI : Priv<"wfi", 0b0001000>, Sched<[]> {953  let rd = 0;954  let rs1 = 0;955  let rs2 = 0b00101;956}957 958let Predicates = [HasStdExtSvinval] in {959def SFENCE_W_INVAL : Priv<"sfence.w.inval", 0b0001100>, Sched<[]> {960  let rd = 0;961  let rs1 = 0;962  let rs2 = 0;963}964 965def SFENCE_INVAL_IR : Priv<"sfence.inval.ir", 0b0001100>, Sched<[]> {966  let rd = 0;967  let rs1 = 0;968  let rs2 = 0b00001;969}970def SINVAL_VMA  : Priv_rr<"sinval.vma", 0b0001011>, Sched<[]>;971def HINVAL_VVMA : Priv_rr<"hinval.vvma", 0b0010011>, Sched<[]>;972def HINVAL_GVMA : Priv_rr<"hinval.gvma", 0b0110011>, Sched<[]>;973} // Predicates = [HasStdExtSvinval]974 975def SFENCE_VMA  : Priv_rr<"sfence.vma", 0b0001001>, Sched<[]>;976 977let Predicates = [HasStdExtH] in {978def HFENCE_VVMA : Priv_rr<"hfence.vvma", 0b0010001>, Sched<[]>;979def HFENCE_GVMA : Priv_rr<"hfence.gvma", 0b0110001>, Sched<[]>;980 981def HLV_B   : HLoad_r<0b0110000, 0b00000, "hlv.b">, Sched<[]>;982def HLV_BU  : HLoad_r<0b0110000, 0b00001, "hlv.bu">, Sched<[]>;983def HLV_H   : HLoad_r<0b0110010, 0b00000, "hlv.h">, Sched<[]>;984def HLV_HU  : HLoad_r<0b0110010, 0b00001, "hlv.hu">, Sched<[]>;985def HLVX_HU : HLoad_r<0b0110010, 0b00011, "hlvx.hu">, Sched<[]>;986def HLV_W   : HLoad_r<0b0110100, 0b00000, "hlv.w">, Sched<[]>;987def HLVX_WU : HLoad_r<0b0110100, 0b00011, "hlvx.wu">, Sched<[]>;988def HSV_B   : HStore_rr<0b0110001, "hsv.b">, Sched<[]>;989def HSV_H   : HStore_rr<0b0110011, "hsv.h">, Sched<[]>;990def HSV_W   : HStore_rr<0b0110101, "hsv.w">, Sched<[]>;991}992let Predicates = [IsRV64, HasStdExtH] in {993def HLV_WU  : HLoad_r<0b0110100, 0b00001, "hlv.wu">, Sched<[]>;994def HLV_D   : HLoad_r<0b0110110, 0b00000, "hlv.d">, Sched<[]>;995def HSV_D   : HStore_rr<0b0110111, "hsv.d">, Sched<[]>;996}997 998let Predicates = [HasStdExtSmctrOrSsctr] in {999def SCTRCLR : Priv<"sctrclr", 0b0001000>, Sched<[]> {1000  let rd = 0;1001  let rs1 = 0;1002  let rs2 = 0b00100;1003}1004}1005 1006//===----------------------------------------------------------------------===//1007// Debug instructions1008//===----------------------------------------------------------------------===//1009 1010let isBarrier = 1, isReturn = 1, isTerminator = 1 in {1011def DRET : Priv<"dret", 0b0111101>, Sched<[]> {1012  let rd = 0;1013  let rs1 = 0;1014  let rs2 = 0b10010;1015}1016} // isBarrier = 1, isReturn = 1, isTerminator = 11017 1018//===----------------------------------------------------------------------===//1019// Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20)1020//===----------------------------------------------------------------------===//1021 1022// Note that the size is 32 because up to 8 32-bit instructions are needed to1023// generate an arbitrary 64-bit immediate. However, the size does not really1024// matter since PseudoLI is currently only used in the AsmParser where it gets1025// expanded to real instructions immediately.1026let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 32,1027    isCodeGenOnly = 0, isAsmParserOnly = 1 in1028def PseudoLI : Pseudo<(outs GPR:$rd), (ins ixlenimm_li:$imm), [],1029                      "li", "$rd, $imm">;1030 1031def PseudoLB  : PseudoLoad<"lb">;1032def PseudoLBU : PseudoLoad<"lbu">;1033def PseudoLH  : PseudoLoad<"lh">;1034def PseudoLHU : PseudoLoad<"lhu">;1035def PseudoLW  : PseudoLoad<"lw">;1036 1037def PseudoSB  : PseudoStore<"sb">;1038def PseudoSH  : PseudoStore<"sh">;1039def PseudoSW  : PseudoStore<"sw">;1040 1041let Predicates = [IsRV64] in {1042def PseudoLWU : PseudoLoad<"lwu">;1043def PseudoLD  : PseudoLoad<"ld">;1044def PseudoSD  : PseudoStore<"sd">;1045} // Predicates = [IsRV64]1046 1047def : InstAlias<"nop",           (ADDI      X0,      X0,           0), 3>;1048def : InstAlias<"li $rd, $imm",  (ADDI GPR:$rd,      X0, simm12_lo:$imm), 2>;1049def : InstAlias<"mv $rd, $rs",   (ADDI GPR:$rd, GPR:$rs,           0)>;1050 1051def : InstAlias<"not $rd, $rs",  (XORI GPR:$rd, GPR:$rs,      -1)>;1052def : InstAlias<"neg $rd, $rs",  (SUB  GPR:$rd,      X0, GPR:$rs)>;1053 1054let Predicates = [IsRV64] in {1055def : InstAlias<"negw $rd, $rs",   (SUBW  GPR:$rd,      X0, GPR:$rs)>;1056def : InstAlias<"sext.w $rd, $rs", (ADDIW GPR:$rd, GPR:$rs,       0)>;1057} // Predicates = [IsRV64]1058 1059def : InstAlias<"seqz $rd, $rs", (SLTIU GPR:$rd, GPR:$rs,       1)>;1060def : InstAlias<"snez $rd, $rs", (SLTU  GPR:$rd,      X0, GPR:$rs)>;1061def : InstAlias<"sltz $rd, $rs", (SLT   GPR:$rd, GPR:$rs,      X0)>;1062def : InstAlias<"sgtz $rd, $rs", (SLT   GPR:$rd,      X0, GPR:$rs)>;1063 1064// sgt/sgtu are recognised by the GNU assembler but the canonical slt/sltu1065// form will always be printed. Therefore, set a zero weight.1066def : InstAlias<"sgt $rd, $rs, $rt", (SLT GPR:$rd, GPR:$rt, GPR:$rs), 0>;1067def : InstAlias<"sgtu $rd, $rs, $rt", (SLTU GPR:$rd, GPR:$rt, GPR:$rs), 0>;1068 1069def : InstAlias<"beqz $rs, $offset",1070                (BEQ GPR:$rs,      X0, bare_simm13_lsb0:$offset)>;1071def : InstAlias<"bnez $rs, $offset",1072                (BNE GPR:$rs,      X0, bare_simm13_lsb0:$offset)>;1073def : InstAlias<"blez $rs, $offset",1074                (BGE      X0, GPR:$rs, bare_simm13_lsb0:$offset)>;1075def : InstAlias<"bgez $rs, $offset",1076                (BGE GPR:$rs,      X0, bare_simm13_lsb0:$offset)>;1077def : InstAlias<"bltz $rs, $offset",1078                (BLT GPR:$rs,      X0, bare_simm13_lsb0:$offset)>;1079def : InstAlias<"bgtz $rs, $offset",1080                (BLT      X0, GPR:$rs, bare_simm13_lsb0:$offset)>;1081 1082// Always output the canonical mnemonic for the pseudo branch instructions.1083// The GNU tools emit the canonical mnemonic for the branch pseudo instructions1084// as well (e.g. "bgt" will be recognised by the assembler but never printed by1085// objdump). Match this behaviour by setting a zero weight.1086def : InstAlias<"bgt $rs, $rt, $offset",1087                (BLT  GPR:$rt, GPR:$rs, bare_simm13_lsb0:$offset), 0>;1088def : InstAlias<"ble $rs, $rt, $offset",1089                (BGE  GPR:$rt, GPR:$rs, bare_simm13_lsb0:$offset), 0>;1090def : InstAlias<"bgtu $rs, $rt, $offset",1091                (BLTU GPR:$rt, GPR:$rs, bare_simm13_lsb0:$offset), 0>;1092def : InstAlias<"bleu $rs, $rt, $offset",1093                (BGEU GPR:$rt, GPR:$rs, bare_simm13_lsb0:$offset), 0>;1094 1095def : InstAlias<"j $offset",   (JAL X0, simm21_lsb0_jal:$offset)>;1096def : InstAlias<"jal $offset", (JAL X1, simm21_lsb0_jal:$offset)>;1097 1098// Non-zero offset aliases of "jalr" are the lowest weight, followed by the1099// two-register form, then the one-register forms and finally "ret".1100def : InstAlias<"jr $rs",                (JALR      X0, GPR:$rs, 0), 3>;1101def : InstAlias<"jr ${offset}(${rs})",   (JALR      X0, GPR:$rs, simm12_lo:$offset)>;1102def : InstAlias<"jalr $rs",              (JALR      X1, GPR:$rs, 0), 3>;1103def : InstAlias<"jalr ${offset}(${rs})", (JALR      X1, GPR:$rs, simm12_lo:$offset)>;1104def : InstAlias<"jalr $rd, $rs",         (JALR GPR:$rd, GPR:$rs, 0), 2>;1105def : InstAlias<"ret",                   (JALR      X0,      X1, 0), 4>;1106 1107// Non-canonical forms for jump targets also accepted by the assembler.1108def : InstAlias<"jr $rs, $offset",        (JALR      X0, GPR:$rs, simm12_lo:$offset), 0>;1109def : InstAlias<"jalr $rs, $offset",      (JALR      X1, GPR:$rs, simm12_lo:$offset), 0>;1110def : InstAlias<"jalr $rd, $rs, $offset", (JALR GPR:$rd, GPR:$rs, simm12_lo:$offset), 0>;1111def : InstAlias<"jr (${rs})",             (JALR      X0, GPR:$rs, 0), 0>;1112def : InstAlias<"jalr (${rs})",           (JALR      X1, GPR:$rs, 0), 0>;1113def : InstAlias<"jalr $rd, (${rs})",      (JALR GPR:$rd, GPR:$rs, 0), 0>;1114 1115def : InstAlias<"fence", (FENCE 0xF, 0xF)>; // 0xF == iorw1116 1117let Predicates = [HasStdExtZihintpause] in1118def : InstAlias<"pause", (FENCE 0x1, 0x0)>; // 0x1 == w1119 1120def : InstAlias<"rdinstret $rd", (CSRRS GPR:$rd, INSTRET.Encoding, X0), 2>;1121def : InstAlias<"rdcycle $rd",   (CSRRS GPR:$rd, CYCLE.Encoding, X0), 2>;1122def : InstAlias<"rdtime $rd",    (CSRRS GPR:$rd, TIME.Encoding, X0), 2>;1123 1124let Predicates = [IsRV32] in {1125def : InstAlias<"rdinstreth $rd", (CSRRS GPR:$rd, INSTRETH.Encoding, X0), 2>;1126def : InstAlias<"rdcycleh $rd",   (CSRRS GPR:$rd, CYCLEH.Encoding, X0), 2>;1127def : InstAlias<"rdtimeh $rd",    (CSRRS GPR:$rd, TIMEH.Encoding, X0), 2>;1128} // Predicates = [IsRV32]1129 1130def : InstAlias<"csrr $rd, $csr", (CSRRS GPR:$rd, csr_sysreg:$csr,      X0)>;1131def : InstAlias<"csrw $csr, $rs", (CSRRW      X0, csr_sysreg:$csr, GPR:$rs)>;1132def : InstAlias<"csrs $csr, $rs", (CSRRS      X0, csr_sysreg:$csr, GPR:$rs)>;1133def : InstAlias<"csrc $csr, $rs", (CSRRC      X0, csr_sysreg:$csr, GPR:$rs)>;1134 1135def : InstAlias<"csrwi $csr, $imm", (CSRRWI X0, csr_sysreg:$csr, uimm5:$imm)>;1136def : InstAlias<"csrsi $csr, $imm", (CSRRSI X0, csr_sysreg:$csr, uimm5:$imm)>;1137def : InstAlias<"csrci $csr, $imm", (CSRRCI X0, csr_sysreg:$csr, uimm5:$imm)>;1138 1139let EmitPriority = 0 in {1140def : InstAlias<"csrw $csr, $imm", (CSRRWI X0, csr_sysreg:$csr, uimm5:$imm)>;1141def : InstAlias<"csrs $csr, $imm", (CSRRSI X0, csr_sysreg:$csr, uimm5:$imm)>;1142def : InstAlias<"csrc $csr, $imm", (CSRRCI X0, csr_sysreg:$csr, uimm5:$imm)>;1143 1144def : InstAlias<"csrrw $rd, $csr, $imm", (CSRRWI GPR:$rd, csr_sysreg:$csr, uimm5:$imm)>;1145def : InstAlias<"csrrs $rd, $csr, $imm", (CSRRSI GPR:$rd, csr_sysreg:$csr, uimm5:$imm)>;1146def : InstAlias<"csrrc $rd, $csr, $imm", (CSRRCI GPR:$rd, csr_sysreg:$csr, uimm5:$imm)>;1147}1148 1149def : InstAlias<"sfence.vma",     (SFENCE_VMA      X0, X0), 2>;1150def : InstAlias<"sfence.vma $rs", (SFENCE_VMA GPR:$rs, X0)>;1151 1152def : InstAlias<"hfence.gvma",     (HFENCE_GVMA      X0, X0), 2>;1153def : InstAlias<"hfence.gvma $rs", (HFENCE_GVMA GPR:$rs, X0)>;1154 1155def : InstAlias<"hfence.vvma",     (HFENCE_VVMA      X0, X0), 2>;1156def : InstAlias<"hfence.vvma $rs", (HFENCE_VVMA GPR:$rs, X0)>;1157 1158let Predicates = [HasStdExtZihintntl] in {1159  def : InstAlias<"ntl.p1",     (ADD   X0, X0, X2)>;1160  def : InstAlias<"ntl.pall",   (ADD   X0, X0, X3)>;1161  def : InstAlias<"ntl.s1",     (ADD   X0, X0, X4)>;1162  def : InstAlias<"ntl.all",    (ADD   X0, X0, X5)>;1163} // Predicates = [HasStdExtZihintntl]1164 1165let EmitPriority = 0 in {1166def : InstAlias<"lb $rd, (${rs1})",1167                (LB  GPR:$rd, GPR:$rs1, 0)>;1168def : InstAlias<"lh $rd, (${rs1})",1169                (LH  GPR:$rd, GPR:$rs1, 0)>;1170def : InstAlias<"lw $rd, (${rs1})",1171                (LW  GPR:$rd, GPR:$rs1, 0)>;1172def : InstAlias<"lbu $rd, (${rs1})",1173                (LBU  GPR:$rd, GPR:$rs1, 0)>;1174def : InstAlias<"lhu $rd, (${rs1})",1175                (LHU  GPR:$rd, GPR:$rs1, 0)>;1176 1177def : InstAlias<"sb $rs2, (${rs1})",1178                (SB  GPR:$rs2, GPR:$rs1, 0)>;1179def : InstAlias<"sh $rs2, (${rs1})",1180                (SH  GPR:$rs2, GPR:$rs1, 0)>;1181def : InstAlias<"sw $rs2, (${rs1})",1182                (SW  GPR:$rs2, GPR:$rs1, 0)>;1183 1184def : InstAlias<"add $rd, $rs1, $imm12",1185                (ADDI  GPR:$rd, GPR:$rs1, simm12_lo:$imm12)>;1186def : InstAlias<"and $rd, $rs1, $imm12",1187                (ANDI  GPR:$rd, GPR:$rs1, simm12_lo:$imm12)>;1188def : InstAlias<"xor $rd, $rs1, $imm12",1189                (XORI  GPR:$rd, GPR:$rs1, simm12_lo:$imm12)>;1190def : InstAlias<"or $rd, $rs1, $imm12",1191                (ORI  GPR:$rd, GPR:$rs1, simm12_lo:$imm12)>;1192def : InstAlias<"sll $rd, $rs1, $shamt",1193                (SLLI  GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt)>;1194def : InstAlias<"srl $rd, $rs1, $shamt",1195                (SRLI  GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt)>;1196def : InstAlias<"sra $rd, $rs1, $shamt",1197                (SRAI  GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt)>;1198let Predicates = [IsRV64] in {1199def : InstAlias<"lwu $rd, (${rs1})",1200                (LWU  GPR:$rd, GPR:$rs1, 0)>;1201def : InstAlias<"ld $rd, (${rs1})",1202                (LD  GPR:$rd, GPR:$rs1, 0)>;1203def : InstAlias<"sd $rs2, (${rs1})",1204                (SD  GPR:$rs2, GPR:$rs1, 0)>;1205 1206def : InstAlias<"addw $rd, $rs1, $imm12",1207                (ADDIW  GPR:$rd, GPR:$rs1, simm12_lo:$imm12)>;1208def : InstAlias<"sllw $rd, $rs1, $shamt",1209                (SLLIW  GPR:$rd, GPR:$rs1, uimm5:$shamt)>;1210def : InstAlias<"srlw $rd, $rs1, $shamt",1211                (SRLIW  GPR:$rd, GPR:$rs1, uimm5:$shamt)>;1212def : InstAlias<"sraw $rd, $rs1, $shamt",1213                (SRAIW  GPR:$rd, GPR:$rs1, uimm5:$shamt)>;1214} // Predicates = [IsRV64]1215def : InstAlias<"slt $rd, $rs1, $imm12",1216                (SLTI  GPR:$rd, GPR:$rs1, simm12_lo:$imm12)>;1217def : InstAlias<"sltu $rd, $rs1, $imm12",1218                (SLTIU  GPR:$rd, GPR:$rs1, simm12_lo:$imm12)>;1219}1220 1221def : MnemonicAlias<"move", "mv">;1222 1223// The SCALL and SBREAK instructions were renamed to ECALL and EBREAK in1224// version 2.1 of the user-level ISA. Like the GNU toolchain, we still accept1225// the old name for backwards compatibility.1226def : MnemonicAlias<"scall", "ecall">;1227def : MnemonicAlias<"sbreak", "ebreak">;1228 1229def : InstAlias<"zext.b $rd, $rs", (ANDI GPR:$rd, GPR:$rs, 0xFF)>;1230 1231let Predicates = [HasStdExtZicfilp] in {1232def : InstAlias<"lpad $imm20", (AUIPC X0, uimm20:$imm20)>;1233}1234 1235//===----------------------------------------------------------------------===//1236// .insn directive instructions1237//===----------------------------------------------------------------------===//1238 1239def AnyRegOperand : AsmOperandClass {1240  let Name = "AnyRegOperand";1241  let RenderMethod = "addRegOperands";1242  let PredicateMethod = "isAnyReg";1243}1244 1245def AnyReg : Operand<XLenVT> {1246  let OperandType = "OPERAND_REGISTER";1247  let ParserMatchClass = AnyRegOperand;1248}1249 1250// isCodeGenOnly = 1 to hide them from the tablegened assembly parser.1251let isCodeGenOnly = 1, hasSideEffects = 1, mayLoad = 1, mayStore = 1,1252    hasNoSchedulingInfo = 1 in {1253def Insn16 : RVInst16<(outs), (ins uimm16:$value), "", "", [], InstFormatOther> {1254  bits<16> value;1255 1256  let Inst{15-0} = value;1257  let AsmString = ".insn 0x2, $value";1258}1259def Insn32 : RVInst<(outs), (ins uimm32:$value), "", "", [], InstFormatOther> {1260  bits<32> value;1261 1262  let Inst{31-0} = value;1263  let AsmString = ".insn 0x4, $value";1264}1265def Insn48 : RVInst48<(outs), (ins uimm48:$value), "", "", [], InstFormatOther> {1266  bits<48> value;1267  let Inst{47-0} = value;1268  let AsmString = ".insn 0x6, $value";1269}1270def Insn64 : RVInst64<(outs), (ins uimm64:$value), "", "", [], InstFormatOther> {1271  bits<64> value;1272  let Inst{63-0} = value;1273  let AsmString = ".insn 0x8, $value";1274}1275} // isCodeGenOnly, hasSideEffects, mayLoad, mayStore, hasNoSchedulingInfo1276 1277// isCodeGenOnly = 1 to hide them from the tablegened assembly parser.1278let isCodeGenOnly = 1, hasSideEffects = 1, mayLoad = 1, mayStore = 1,1279    hasNoSchedulingInfo = 1 in {1280def InsnR : DirectiveInsnR<(outs AnyReg:$rd), (ins uimm7_opcode:$opcode, uimm3:$funct3,1281                                                   uimm7:$funct7, AnyReg:$rs1,1282                                                   AnyReg:$rs2),1283                           "$opcode, $funct3, $funct7, $rd, $rs1, $rs2">;1284def InsnR4 : DirectiveInsnR4<(outs AnyReg:$rd), (ins uimm7_opcode:$opcode,1285                                                     uimm3:$funct3,1286                                                     uimm2:$funct2,1287                                                     AnyReg:$rs1, AnyReg:$rs2,1288                                                     AnyReg:$rs3),1289                            "$opcode, $funct3, $funct2, $rd, $rs1, $rs2, $rs3">;1290def InsnI : DirectiveInsnI<(outs AnyReg:$rd), (ins uimm7_opcode:$opcode, uimm3:$funct3,1291                                                   AnyReg:$rs1, simm12_lo:$imm12),1292                           "$opcode, $funct3, $rd, $rs1, $imm12">;1293def InsnI_Mem : DirectiveInsnI<(outs AnyReg:$rd), (ins uimm7_opcode:$opcode,1294                                                       uimm3:$funct3,1295                                                       AnyReg:$rs1,1296                                                       simm12_lo:$imm12),1297                               "$opcode, $funct3, $rd, ${imm12}(${rs1})">;1298def InsnB : DirectiveInsnB<(outs), (ins uimm7_opcode:$opcode, uimm3:$funct3,1299                                        AnyReg:$rs1, AnyReg:$rs2,1300                                        bare_simm13_lsb0:$imm12),1301                           "$opcode, $funct3, $rs1, $rs2, $imm12">;1302def InsnU : DirectiveInsnU<(outs AnyReg:$rd), (ins uimm7_opcode:$opcode,1303                                                   uimm20_lui:$imm20),1304                           "$opcode, $rd, $imm20">;1305def InsnJ : DirectiveInsnJ<(outs AnyReg:$rd), (ins uimm7_opcode:$opcode,1306                                                   simm21_lsb0_jal:$imm20),1307                           "$opcode, $rd, $imm20">;1308def InsnS : DirectiveInsnS<(outs), (ins uimm7_opcode:$opcode, uimm3:$funct3,1309                                        AnyReg:$rs2, AnyReg:$rs1,1310                                        simm12_lo:$imm12),1311                           "$opcode, $funct3, $rs2, ${imm12}(${rs1})">;1312} // isCodeGenOnly, hasSideEffects, mayLoad, mayStore, hasNoSchedulingInfo1313 1314// Use InstAliases to match these so that we can combine the insn and format1315// into a mnemonic to use as the key for the tablegened asm matcher table. The1316// parser will take care of creating these fake mnemonics and will only do it1317// for known formats.1318let EmitPriority = 0 in {1319def : InstAlias<".insn_r $opcode, $funct3, $funct7, $rd, $rs1, $rs2",1320                (InsnR AnyReg:$rd, uimm7_opcode:$opcode, uimm3:$funct3, uimm7:$funct7,1321                       AnyReg:$rs1, AnyReg:$rs2)>;1322// Accept 4 register form of ".insn r" as alias for ".insn r4".1323def : InstAlias<".insn_r $opcode, $funct3, $funct2, $rd, $rs1, $rs2, $rs3",1324                (InsnR4 AnyReg:$rd, uimm7_opcode:$opcode, uimm3:$funct3, uimm2:$funct2,1325                        AnyReg:$rs1, AnyReg:$rs2, AnyReg:$rs3)>;1326def : InstAlias<".insn_r4 $opcode, $funct3, $funct2, $rd, $rs1, $rs2, $rs3",1327                (InsnR4 AnyReg:$rd, uimm7_opcode:$opcode, uimm3:$funct3, uimm2:$funct2,1328                        AnyReg:$rs1, AnyReg:$rs2, AnyReg:$rs3)>;1329def : InstAlias<".insn_i $opcode, $funct3, $rd, $rs1, $imm12",1330                (InsnI AnyReg:$rd, uimm7_opcode:$opcode, uimm3:$funct3, AnyReg:$rs1,1331                       simm12_lo:$imm12)>;1332def : InstAlias<".insn_i $opcode, $funct3, $rd, ${imm12}(${rs1})",1333                (InsnI_Mem AnyReg:$rd, uimm7_opcode:$opcode, uimm3:$funct3,1334                           AnyReg:$rs1, simm12_lo:$imm12)>;1335def : InstAlias<".insn_i $opcode, $funct3, $rd, (${rs1})",1336                (InsnI_Mem AnyReg:$rd, uimm7_opcode:$opcode, uimm3:$funct3,1337                           AnyReg:$rs1, 0)>;1338def : InstAlias<".insn_b $opcode, $funct3, $rs1, $rs2, $imm12",1339                (InsnB uimm7_opcode:$opcode, uimm3:$funct3, AnyReg:$rs1,1340                       AnyReg:$rs2, bare_simm13_lsb0:$imm12)>;1341// Accept sb as an alias for b.1342def : InstAlias<".insn_sb $opcode, $funct3, $rs1, $rs2, $imm12",1343                (InsnB uimm7_opcode:$opcode, uimm3:$funct3, AnyReg:$rs1,1344                       AnyReg:$rs2, bare_simm13_lsb0:$imm12)>;1345def : InstAlias<".insn_u $opcode, $rd, $imm20",1346                (InsnU AnyReg:$rd, uimm7_opcode:$opcode, uimm20_lui:$imm20)>;1347def : InstAlias<".insn_j $opcode, $rd, $imm20",1348                (InsnJ AnyReg:$rd, uimm7_opcode:$opcode, simm21_lsb0_jal:$imm20)>;1349// Accept uj as an alias for j.1350def : InstAlias<".insn_uj $opcode, $rd, $imm20",1351                (InsnJ AnyReg:$rd, uimm7_opcode:$opcode, simm21_lsb0_jal:$imm20)>;1352def : InstAlias<".insn_s $opcode, $funct3, $rs2, ${imm12}(${rs1})",1353                (InsnS uimm7_opcode:$opcode, uimm3:$funct3, AnyReg:$rs2,1354                       AnyReg:$rs1, simm12_lo:$imm12)>;1355def : InstAlias<".insn_s $opcode, $funct3, $rs2, (${rs1})",1356                (InsnS uimm7_opcode:$opcode, uimm3:$funct3, AnyReg:$rs2,1357                       AnyReg:$rs1, 0)>;1358}1359 1360//===----------------------------------------------------------------------===//1361// Pseudo-instructions and codegen patterns1362//1363// Naming convention: For 'generic' pattern classes, we use the naming1364// convention PatTy1Ty2. For pattern classes which offer a more complex1365// expansion, prefix the class name, e.g. BccPat.1366//===----------------------------------------------------------------------===//1367 1368/// Generic pattern classes1369 1370class PatGpr<SDPatternOperator OpNode, RVInst Inst, ValueType vt = XLenVT>1371    : Pat<(vt (OpNode (vt GPR:$rs1))), (Inst GPR:$rs1)>;1372class PatGprGpr<SDPatternOperator OpNode, RVInst Inst, ValueType vt = XLenVT>1373    : Pat<(vt (OpNode (vt GPR:$rs1), (vt GPR:$rs2))), (Inst GPR:$rs1, GPR:$rs2)>;1374 1375class PatGprImm<SDPatternOperator OpNode, RVInst Inst, ImmLeaf ImmType,1376                ValueType vt = XLenVT>1377    : Pat<(vt (OpNode (vt GPR:$rs1), ImmType:$imm)),1378          (Inst GPR:$rs1, ImmType:$imm)>;1379class PatGprSimm12<SDPatternOperator OpNode, RVInstI Inst>1380    : PatGprImm<OpNode, Inst, simm12_lo>;1381class PatGprUimmLog2XLen<SDPatternOperator OpNode, RVInstIShift Inst>1382    : PatGprImm<OpNode, Inst, uimmlog2xlen>;1383 1384/// Predicates1385 1386def assertsexti32 : PatFrag<(ops node:$src), (assertsext node:$src), [{1387  return cast<VTSDNode>(N->getOperand(1))->getVT().bitsLE(MVT::i32);1388}]>;1389def sexti16 : ComplexPattern<XLenVT, 1, "selectSExtBits<16>">;1390 1391def sexti32 : ComplexPattern<i64, 1, "selectSExtBits<32>">;1392def gi_sexti32 : GIComplexOperandMatcher<s64, "selectSExtBits<32>">,1393                 GIComplexPatternEquiv<sexti32>;1394 1395def assertzexti32 : PatFrag<(ops node:$src), (assertzext node:$src), [{1396  return cast<VTSDNode>(N->getOperand(1))->getVT().bitsLE(MVT::i32);1397}]>;1398 1399def zexti32 : ComplexPattern<i64, 1, "selectZExtBits<32>">;1400def gi_zexti32 : GIComplexOperandMatcher<s64, "selectZExtBits<32>">,1401                 GIComplexPatternEquiv<zexti32>;1402 1403def zexti16 : ComplexPattern<XLenVT, 1, "selectZExtBits<16>">;1404def gi_zexti16 : GIComplexOperandMatcher<s32, "selectZExtBits<16>">,1405                 GIComplexPatternEquiv<zexti16>;1406 1407def zexti8 : ComplexPattern<XLenVT, 1, "selectZExtBits<8>">;1408def gi_zexti8  : GIComplexOperandMatcher<s32, "selectZExtBits<8>">,1409                 GIComplexPatternEquiv<zexti8>;1410 1411def ext : PatFrags<(ops node:$A), [(sext node:$A), (zext node:$A)]>;1412 1413class binop_oneuse<SDPatternOperator operator>1414    : PatFrag<(ops node:$A, node:$B),1415              (operator node:$A, node:$B)> {1416  let HasOneUse = 1;1417}1418 1419def and_oneuse : binop_oneuse<and>;1420def mul_oneuse : binop_oneuse<mul>;1421 1422def mul_const_oneuse : PatFrag<(ops node:$A, node:$B),1423                               (mul node:$A, node:$B), [{1424  if (auto *N1C = dyn_cast<ConstantSDNode>(N->getOperand(1)))1425    return N1C->hasOneUse();1426  return false;1427}]>;1428 1429class unop_oneuse<SDPatternOperator operator>1430    : PatFrag<(ops node:$A),1431              (operator node:$A)> {1432  let HasOneUse = 1;1433}1434 1435def sext_oneuse   : unop_oneuse<sext>;1436def zext_oneuse   : unop_oneuse<zext>;1437def anyext_oneuse : unop_oneuse<anyext>;1438def ext_oneuse    : unop_oneuse<ext>;1439def fpext_oneuse  : unop_oneuse<any_fpextend>;1440 1441def 33signbits_node : PatLeaf<(i64 GPR:$src), [{1442  return CurDAG->ComputeNumSignBits(Op) > 32;1443}]>;1444 1445class immop_oneuse<ImmLeaf leaf> : PatLeaf<(leaf), [{1446  return N->hasOneUse();1447}]> {1448  let GISelPredicateCode = [{1449    return MRI.hasOneNonDBGUse(MI.getOperand(0).getReg());1450  }];1451}1452 1453/// Simple arithmetic operations1454 1455def : PatGprGpr<add, ADD>;1456def : PatGprSimm12<add, ADDI>;1457def : PatGprGpr<sub, SUB>;1458def : PatGprGpr<or, OR>;1459def : PatGprSimm12<or, ORI>;1460def : PatGprGpr<and, AND>;1461def : PatGprSimm12<and, ANDI>;1462def : PatGprGpr<xor, XOR>;1463def : PatGprSimm12<xor, XORI>;1464def : PatGprUimmLog2XLen<shl, SLLI>;1465def : PatGprUimmLog2XLen<srl, SRLI>;1466def : PatGprUimmLog2XLen<sra, SRAI>;1467 1468// Select 'or' as ADDI if the immediate bits are known to be 0 in $rs1. This1469// can improve compressibility.1470def riscv_or_disjoint : PatFrag<(ops node:$lhs, node:$rhs), (or node:$lhs, node:$rhs),[{1471  return orDisjoint(N);1472}]>;1473def : PatGprSimm12<riscv_or_disjoint, ADDI>;1474 1475def add_like : PatFrags<(ops node:$lhs, node:$rhs),1476                        [(riscv_or_disjoint node:$lhs, node:$rhs),1477                         (add  node:$lhs, node:$rhs)]>;1478 1479def riscv_xor_like : PatFrags<(ops node:$lhs, node:$rhs),1480                              [(riscv_or_disjoint node:$lhs, node:$rhs),1481                               (xor  node:$lhs, node:$rhs)]>;1482 1483// negate of low bit can be done via two (compressible) shifts.  The negate1484// is never compressible since rs1 and rd can't be the same register.1485def : Pat<(i32 (sub 0, (and_oneuse GPR:$rs, 1))),1486          (SRAI (i32 (SLLI $rs, 31)), 31)>, Requires<[IsRV32]>;1487def : Pat<(i64 (sub 0, (and_oneuse GPR:$rs, 1))),1488          (SRAI (i64 (SLLI $rs, 63)), 63)>, Requires<[IsRV64]>;1489 1490// AND with leading/trailing ones mask exceeding simm32/simm12.1491def : Pat<(i64 (and GPR:$rs, immop_oneuse<LeadingOnesMask>:$mask)),1492          (SLLI (i64 (SRLI $rs, (TrailingZeros imm:$mask))),1493                (TrailingZeros imm:$mask))>;1494def : Pat<(XLenVT (and GPR:$rs, immop_oneuse<TrailingOnesMask>:$mask)),1495          (SRLI (XLenVT (SLLI $rs, (XLenSubTrailingOnes imm:$mask))),1496                (XLenSubTrailingOnes imm:$mask))>;1497 1498// Match both a plain shift and one where the shift amount is masked (this is1499// typically introduced when the legalizer promotes the shift amount and1500// zero-extends it). For RISC-V, the mask is unnecessary as shifts in the base1501// ISA only read the least significant 5 bits (RV32I) or 6 bits (RV64I).1502def shiftMaskXLen : ComplexPattern<XLenVT, 1, "selectShiftMaskXLen", [], [], 0>;1503def shiftMask32   : ComplexPattern<i64, 1, "selectShiftMask32", [], [], 0>;1504// FIXME: This is labelled as handling 's32', however the ComplexPattern it1505// refers to handles both i32 and i64 based on the HwMode. Currently this LLT1506// parameter appears to be ignored so this pattern works for both, however we1507// should add a LowLevelTypeByHwMode, and use that to define our XLenLLT instead1508// here.1509def GIShiftMaskXLen :1510    GIComplexOperandMatcher<s32, "selectShiftMaskXLen">,1511    GIComplexPatternEquiv<shiftMaskXLen>;1512def GIShiftMask32 :1513    GIComplexOperandMatcher<s64, "selectShiftMask32">,1514    GIComplexPatternEquiv<shiftMask32>;1515 1516class PatGprShiftMaskXLen<SDPatternOperator OpNode, RVInst Inst>1517    : Pat<(OpNode GPR:$rs1, shiftMaskXLen:$rs2),1518          (Inst GPR:$rs1, shiftMaskXLen:$rs2)>;1519class PatGprShiftMask32<SDPatternOperator OpNode, RVInst Inst>1520    : Pat<(OpNode GPR:$rs1, shiftMask32:$rs2),1521          (Inst GPR:$rs1, shiftMask32:$rs2)>;1522 1523def : PatGprShiftMaskXLen<shl, SLL>;1524def : PatGprShiftMaskXLen<srl, SRL>;1525def : PatGprShiftMaskXLen<sra, SRA>;1526 1527// This is a special case of the ADD instruction used to facilitate the use of a1528// fourth operand to emit a relocation on a symbol relating to this instruction.1529// The relocation does not affect any bits of the instruction itself but is used1530// as a hint to the linker.1531let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 0 in1532def PseudoAddTPRel : Pseudo<(outs GPR:$rd),1533                            (ins GPR:$rs1, GPR:$rs2, tprel_add_symbol:$src), [],1534                            "add", "$rd, $rs1, $rs2, $src">;1535 1536/// FrameIndex calculations1537 1538// Transforms frameindex -> tframeindex.1539def to_tframeindex : SDNodeXForm<frameindex, [{1540  return CurDAG->getTargetFrameIndex(N->getIndex(), N->getValueType(0));1541}]>;1542 1543def : GICustomOperandRenderer<"renderFrameIndex">,1544      GISDNodeXFormEquiv<to_tframeindex>;1545 1546def : Pat<(frameindex:$fi), (ADDI (iPTR (to_tframeindex $fi)), 0)>;1547 1548def : Pat<(add_like frameindex:$fi, simm12_lo:$offset),1549          (ADDI (iPTR (to_tframeindex $fi)), simm12_lo:$offset)>;1550 1551def GIAddrRegImm :1552  GIComplexOperandMatcher<s32, "selectAddrRegImm">,1553  GIComplexPatternEquiv<AddrRegImm>;1554 1555/// Stack probing1556 1557let hasSideEffects = 1, mayLoad = 1, mayStore = 1, isCodeGenOnly = 1,1558    Defs = [X2], Uses = [X2] in {1559// Probed stack allocation of a constant size, used in function prologues when1560// stack-clash protection is enabled.1561def PROBED_STACKALLOC : Pseudo<(outs),1562                               (ins GPR:$target),1563                               []>,1564                               Sched<[]>;1565def PROBED_STACKALLOC_RVV : Pseudo<(outs),1566                                   (ins GPR:$target),1567                                   []>,1568                                   Sched<[]>;1569let usesCustomInserter = 1 in1570def PROBED_STACKALLOC_DYN : Pseudo<(outs),1571                               (ins GPR:$target),1572                               [(riscv_probed_alloca GPR:$target)]>,1573                               Sched<[]>;1574}1575 1576/// HI and ADD_LO address nodes.1577 1578// Pseudo for a rematerializable LUI+ADDI sequence for loading an address.1579// It will be expanded after register allocation.1580// FIXME: The scheduling information does not reflect the multiple instructions.1581let Size = 8, isReMaterializable = 1 in1582def PseudoMovAddr : Pseudo<(outs GPR:$dst), (ins uimm20_lui:$hi, simm12_lo:$lo), []>,1583                    Sched<[WriteIALU]>;1584 1585def riscv_hi_oneuse : unop_oneuse<riscv_hi>;1586def addr_hi_lo : PatFrag<(ops node:$hi, node:$lo),1587                         (riscv_add_lo (riscv_hi_oneuse node:$hi), node:$lo)>;1588 1589def : Pat<(addr_hi_lo tglobaladdr:$hi, tglobaladdr:$lo),1590          (PseudoMovAddr tglobaladdr:$hi, tglobaladdr:$lo)>;1591def : Pat<(addr_hi_lo tblockaddress:$hi, tblockaddress:$lo),1592          (PseudoMovAddr tblockaddress:$hi, tblockaddress:$lo)>;1593def : Pat<(addr_hi_lo tjumptable:$hi, tjumptable:$lo),1594          (PseudoMovAddr tjumptable:$hi, tjumptable:$lo)>;1595def : Pat<(addr_hi_lo tconstpool:$hi, tconstpool:$lo),1596          (PseudoMovAddr tconstpool:$hi, tconstpool:$lo)>;1597 1598def : Pat<(riscv_hi tglobaladdr:$in), (LUI tglobaladdr:$in)>;1599def : Pat<(riscv_hi tblockaddress:$in), (LUI tblockaddress:$in)>;1600def : Pat<(riscv_hi tjumptable:$in), (LUI tjumptable:$in)>;1601def : Pat<(riscv_hi tconstpool:$in), (LUI tconstpool:$in)>;1602 1603def : Pat<(riscv_add_lo GPR:$hi, tglobaladdr:$lo),1604          (ADDI GPR:$hi, tglobaladdr:$lo)>;1605def : Pat<(riscv_add_lo GPR:$hi, tblockaddress:$lo),1606          (ADDI GPR:$hi, tblockaddress:$lo)>;1607def : Pat<(riscv_add_lo GPR:$hi, tjumptable:$lo),1608          (ADDI GPR:$hi, tjumptable:$lo)>;1609def : Pat<(riscv_add_lo GPR:$hi, tconstpool:$lo),1610          (ADDI GPR:$hi, tconstpool:$lo)>;1611 1612/// TLS address nodes.1613 1614def : Pat<(riscv_hi tglobaltlsaddr:$in), (LUI tglobaltlsaddr:$in)>;1615def : Pat<(riscv_add_tprel GPR:$rs1, GPR:$rs2, tglobaltlsaddr:$src),1616          (PseudoAddTPRel GPR:$rs1, GPR:$rs2, tglobaltlsaddr:$src)>;1617def : Pat<(riscv_add_lo GPR:$src, tglobaltlsaddr:$lo),1618          (ADDI GPR:$src, tglobaltlsaddr:$lo)>;1619 1620/// Setcc1621 1622def : PatGprGpr<setlt, SLT>;1623def : PatGprSimm12<setlt, SLTI>;1624def : PatGprGpr<setult, SLTU>;1625def : PatGprSimm12<setult, SLTIU>;1626 1627// RISC-V doesn't have general instructions for integer setne/seteq, but we can1628// check for equality with 0. These ComplexPatterns rewrite the setne/seteq into1629// something that can be compared with 0.1630// These ComplexPatterns must be used in pairs.1631def riscv_setne : ComplexPattern<XLenVT, 1, "selectSETNE", [setcc]>;1632def riscv_seteq : ComplexPattern<XLenVT, 1, "selectSETEQ", [setcc]>;1633 1634// Define pattern expansions for setcc operations that aren't directly1635// handled by a RISC-V instruction.1636def : Pat<(riscv_seteq (XLenVT GPR:$rs1)), (SLTIU GPR:$rs1, 1)>;1637def : Pat<(riscv_setne (XLenVT GPR:$rs1)), (SLTU (XLenVT X0), GPR:$rs1)>;1638def : Pat<(XLenVT (setne (XLenVT GPR:$rs1), -1)), (SLTIU GPR:$rs1, -1)>;1639def : Pat<(XLenVT (seteq (XLenVT (and GPR:$rs, immop_oneuse<TrailingOnesMask>:$mask)), 0)),1640          (SLTIU (XLenVT (SLLI GPR:$rs, (XLenSubTrailingOnes imm:$mask))), 1)>;1641def : Pat<(XLenVT (setne (XLenVT (and GPR:$rs, immop_oneuse<TrailingOnesMask>:$mask)), 0)),1642          (SLTU (XLenVT X0), (XLenVT (SLLI GPR:$rs, (XLenSubTrailingOnes imm:$mask))))>;1643 1644def IntCCtoRISCVCC : SDNodeXForm<riscv_selectcc, [{1645  ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();1646  RISCVCC::CondCode BrCC = getRISCVCCForIntCC(CC);1647  return CurDAG->getTargetConstant(BrCC, SDLoc(N), Subtarget->getXLenVT());1648}]>;1649 1650def riscv_selectcc_frag : PatFrag<(ops node:$lhs, node:$rhs, node:$cc,1651                                       node:$truev, node:$falsev),1652                                  (riscv_selectcc node:$lhs, node:$rhs,1653                                                  node:$cc, node:$truev,1654                                                  node:$falsev), [{}],1655                                  IntCCtoRISCVCC>;1656 1657multiclass SelectCC_GPR_rrirr<DAGOperand valty, ValueType vt,1658                              ValueType cmpvt = XLenVT> {1659  let usesCustomInserter = 1 in1660  def _Using_CC_GPR : Pseudo<(outs valty:$dst),1661                             (ins GPR:$lhs, GPR:$rhs, cond_code:$cc,1662                              valty:$truev, valty:$falsev),1663                             [(set valty:$dst,1664                               (riscv_selectcc_frag:$cc (cmpvt GPR:$lhs), GPR:$rhs, cond,1665                                                        (vt valty:$truev), valty:$falsev))]>;1666  // Explicitly select 0 in the condition to X0. The register coalescer doesn't1667  // always do it.1668  def : Pat<(riscv_selectcc_frag:$cc (cmpvt GPR:$lhs), 0, cond, (vt valty:$truev),1669                                     valty:$falsev),1670            (!cast<Instruction>(NAME#"_Using_CC_GPR") GPR:$lhs, (XLenVT X0),1671             (IntCCtoRISCVCC $cc), valty:$truev, valty:$falsev)>;1672}1673 1674let Predicates = [NoConditionalMoveFusion] in1675defm Select_GPR : SelectCC_GPR_rrirr<GPR, XLenVT>;1676 1677class SelectCompressOpt<CondCode Cond>1678    : Pat<(riscv_selectcc_frag:$select (XLenVT GPR:$lhs), simm12_no6:$Constant, Cond,1679                                       (XLenVT GPR:$truev), GPR:$falsev),1680    (Select_GPR_Using_CC_GPR (XLenVT (ADDI GPR:$lhs, (NegImm simm12_lo:$Constant))), (XLenVT X0),1681                          (IntCCtoRISCVCC $select), GPR:$truev, GPR:$falsev)>;1682 1683def OptForMinSize : Predicate<"MF ? MF->getFunction().hasMinSize() : false">;1684 1685let Predicates = [HasStdExtC, OptForMinSize] in {1686  def : SelectCompressOpt<SETEQ>;1687  def : SelectCompressOpt<SETNE>;1688}1689 1690multiclass SelectCC_GPR_riirr<DAGOperand valty, DAGOperand imm> {1691  let usesCustomInserter = 1 in1692  def Select_# valty #_Using_ # NAME1693      : Pseudo<(outs valty:$dst),1694               (ins valty:$lhs, imm:$imm, cond_code:$cc,1695                valty:$truev, valty:$falsev), []>;1696}1697 1698let Predicates = [IsRV32] in {1699def : Pat<(i32 (setlt (i32 GPR:$rs1), 0)), (SRLI GPR:$rs1, 31)>; // compressible1700}1701let Predicates = [IsRV64] in {1702def : Pat<(i64 (setlt (i64 GPR:$rs1), 0)), (SRLI GPR:$rs1, 63)>; // compressible1703def : Pat<(i64 (setlt (sext_inreg GPR:$rs1, i32), 0)), (SRLIW GPR:$rs1, 31)>;1704}1705 1706/// Branches and jumps1707 1708// Match `riscv_brcc` and lower to the appropriate RISC-V branch instruction.1709multiclass BccPat<CondCode Cond, RVInstB Inst> {1710  def : Pat<(riscv_brcc (XLenVT GPR:$rs1), GPR:$rs2, Cond, bb:$imm12),1711            (Inst GPR:$rs1, GPR:$rs2, bare_simm13_lsb0_bb:$imm12)>;1712  // Explicitly select 0 to X0. The register coalescer doesn't always do it.1713  def : Pat<(riscv_brcc (XLenVT GPR:$rs1), 0, Cond, bb:$imm12),1714            (Inst GPR:$rs1, (XLenVT X0), bare_simm13_lsb0_bb:$imm12)>;1715}1716 1717class BrccCompressOpt<CondCode Cond, RVInstB Inst>1718    : Pat<(riscv_brcc GPR:$lhs, simm12_no6:$Constant, Cond, bb:$place),1719          (Inst (XLenVT (ADDI GPR:$lhs, (NegImm simm12_lo:$Constant))),1720                (XLenVT X0), bb:$place)>;1721 1722defm : BccPat<SETEQ, BEQ>;1723defm : BccPat<SETNE, BNE>;1724defm : BccPat<SETLT, BLT>;1725defm : BccPat<SETGE, BGE>;1726defm : BccPat<SETULT, BLTU>;1727defm : BccPat<SETUGE, BGEU>;1728 1729let Predicates = [HasStdExtZca, OptForMinSize] in {1730  def : BrccCompressOpt<SETEQ, BEQ>;1731  def : BrccCompressOpt<SETNE, BNE>;1732}1733 1734class LongBccPseudo : Pseudo<(outs),1735                             (ins GPR:$rs1, GPR:$rs2, simm21_lsb0_jal:$imm20),1736                             []> {1737  let Size = 8;1738  let isBarrier = 1;1739  let isBranch = 1;1740  let hasSideEffects = 0;1741  let mayStore = 0;1742  let mayLoad = 0;1743  let isAsmParserOnly = 1;1744  let hasNoSchedulingInfo = 1;1745}1746 1747def PseudoLongBEQ : LongBccPseudo;1748def PseudoLongBNE : LongBccPseudo;1749def PseudoLongBLT : LongBccPseudo;1750def PseudoLongBGE : LongBccPseudo;1751def PseudoLongBLTU : LongBccPseudo;1752def PseudoLongBGEU : LongBccPseudo;1753 1754let isBarrier = 1, isBranch = 1, isTerminator = 1 in1755def PseudoBR : Pseudo<(outs), (ins simm21_lsb0_jal:$imm20), [(br bb:$imm20)]>,1756               PseudoInstExpansion<(JAL X0, simm21_lsb0_jal:$imm20)>;1757 1758let Predicates = [NoStdExtZicfilp],1759    isBarrier = 1, isBranch = 1, isIndirectBranch = 1, isTerminator = 1 in1760def PseudoBRIND : Pseudo<(outs), (ins GPRJALR:$rs1, simm12_lo:$imm12), []>,1761                  PseudoInstExpansion<(JALR X0, GPR:$rs1, simm12_lo:$imm12)>;1762 1763let Predicates = [HasStdExtZicfilp],1764    isBarrier = 1, isBranch = 1, isIndirectBranch = 1, isTerminator = 1 in {1765def PseudoBRINDNonX7 : Pseudo<(outs), (ins GPRJALRNonX7:$rs1, simm12_lo:$imm12), []>,1766                       PseudoInstExpansion<(JALR X0, GPR:$rs1, simm12_lo:$imm12)>;1767def PseudoBRINDX7 : Pseudo<(outs), (ins GPRX7:$rs1, simm12_lo:$imm12), []>,1768                    PseudoInstExpansion<(JALR X0, GPR:$rs1, simm12_lo:$imm12)>;1769}1770 1771// For Zicfilp, need to avoid using X7/T2 for indirect branches which need1772// landing pad.1773let Predicates = [HasStdExtZicfilp] in {1774def : Pat<(brind GPRJALRNonX7:$rs1), (PseudoBRINDNonX7 GPRJALRNonX7:$rs1, 0)>;1775def : Pat<(brind (add GPRJALRNonX7:$rs1, simm12_lo:$imm12)),1776          (PseudoBRINDNonX7 GPRJALRNonX7:$rs1, simm12_lo:$imm12)>;1777 1778def : Pat<(riscv_sw_guarded_brind GPRX7:$rs1), (PseudoBRINDX7 GPRX7:$rs1, 0)>;1779def : Pat<(riscv_sw_guarded_brind (add GPRX7:$rs1, simm12_lo:$imm12)),1780          (PseudoBRINDX7 GPRX7:$rs1, simm12_lo:$imm12)>;1781}1782 1783let Predicates = [NoStdExtZicfilp] in {1784def : Pat<(brind GPRJALR:$rs1), (PseudoBRIND GPRJALR:$rs1, 0)>;1785def : Pat<(brind (add GPRJALR:$rs1, simm12_lo:$imm12)),1786          (PseudoBRIND GPRJALR:$rs1, simm12_lo:$imm12)>;1787}1788 1789// PseudoCALLReg is a generic pseudo instruction for calls which will eventually1790// expand to auipc and jalr while encoding, with any given register used as the1791// destination.1792// Define AsmString to print "call" when compile with -S flag.1793// Define isCodeGenOnly = 0 to support parsing assembly "call" instruction.1794let isCall = 1, isBarrier = 1, isCodeGenOnly = 0, Size = 8, hasSideEffects = 0,1795    mayStore = 0, mayLoad = 0 in1796def PseudoCALLReg : Pseudo<(outs GPR:$rd), (ins call_symbol:$func), [],1797                           "call", "$rd, $func">,1798                    Sched<[WriteIALU, WriteJalr, ReadJalr]>;1799 1800// PseudoCALL is a pseudo instruction which will eventually expand to auipc1801// and jalr while encoding. This is desirable, as an auipc+jalr pair with1802// R_RISCV_CALL and R_RISCV_RELAX relocations can be be relaxed by the linker1803// if the offset fits in a signed 21-bit immediate.1804// Define AsmString to print "call" when compile with -S flag.1805// Define isCodeGenOnly = 0 to support parsing assembly "call" instruction.1806let isCall = 1, Defs = [X1], isCodeGenOnly = 0, Size = 8 in1807def PseudoCALL : Pseudo<(outs), (ins call_symbol:$func), [],1808                        "call", "$func">,1809                 Sched<[WriteIALU, WriteJalr, ReadJalr]>;1810 1811def : Pat<(riscv_call tglobaladdr:$func), (PseudoCALL tglobaladdr:$func)>;1812def : Pat<(riscv_call texternalsym:$func), (PseudoCALL texternalsym:$func)>;1813 1814def : Pat<(riscv_sret_glue), (SRET)>;1815def : Pat<(riscv_mret_glue), (MRET)>;1816let Predicates = [HasStdExtSmrnmi] in1817def : Pat<(riscv_mnret_glue), (MNRET)>;1818 1819let isCall = 1, Defs = [X1] in {1820let Predicates = [NoStdExtZicfilp] in1821def PseudoCALLIndirect : Pseudo<(outs), (ins GPRJALR:$rs1),1822                                [(riscv_call GPRJALR:$rs1)]>,1823                         PseudoInstExpansion<(JALR X1, GPR:$rs1, 0)>;1824let Predicates = [HasStdExtZicfilp] in {1825def PseudoCALLIndirectNonX7 : Pseudo<(outs), (ins GPRJALRNonX7:$rs1),1826                                     [(riscv_call GPRJALRNonX7:$rs1)]>,1827                              PseudoInstExpansion<(JALR X1, GPR:$rs1, 0)>;1828// For large code model, non-indirect calls could be software-guarded1829def PseudoCALLIndirectX7 : Pseudo<(outs), (ins GPRX7:$rs1),1830                                  [(riscv_sw_guarded_call GPRX7:$rs1)]>,1831                           PseudoInstExpansion<(JALR X1, GPR:$rs1, 0)>;1832}1833}1834 1835let isBarrier = 1, isReturn = 1, isTerminator = 1 in1836def PseudoRET : Pseudo<(outs), (ins), [(riscv_ret_glue)]>,1837                PseudoInstExpansion<(JALR X0, X1, 0)>;1838 1839// PseudoTAIL is a pseudo instruction similar to PseudoCALL and will eventually1840// expand to auipc and jalr while encoding.1841// Define AsmString to print "tail" when compile with -S flag.1842let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [X2],1843    Size = 8, isCodeGenOnly = 0 in1844def PseudoTAIL : Pseudo<(outs), (ins call_symbol:$dst), [],1845                        "tail", "$dst">,1846                 Sched<[WriteIALU, WriteJalr, ReadJalr]>;1847 1848let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [X2] in {1849let Predicates = [NoStdExtZicfilp] in1850def PseudoTAILIndirect : Pseudo<(outs), (ins GPRTC:$rs1),1851                                [(riscv_tail GPRTC:$rs1)]>,1852                         PseudoInstExpansion<(JALR X0, GPR:$rs1, 0)>;1853let Predicates = [HasStdExtZicfilp] in {1854def PseudoTAILIndirectNonX7 : Pseudo<(outs), (ins GPRTCNonX7:$rs1),1855                                     [(riscv_tail GPRTCNonX7:$rs1)]>,1856                              PseudoInstExpansion<(JALR X0, GPR:$rs1, 0)>;1857// For large code model, non-indirect calls could be software-guarded1858def PseudoTAILIndirectX7 : Pseudo<(outs), (ins GPRX7:$rs1),1859                                  [(riscv_sw_guarded_tail GPRX7:$rs1)]>,1860                           PseudoInstExpansion<(JALR X0, GPR:$rs1, 0)>;1861}1862}1863 1864def : Pat<(riscv_tail (iPTR tglobaladdr:$dst)),1865          (PseudoTAIL tglobaladdr:$dst)>;1866def : Pat<(riscv_tail (iPTR texternalsym:$dst)),1867          (PseudoTAIL texternalsym:$dst)>;1868 1869let isCall = 0, isBarrier = 1, isBranch = 1, isTerminator = 1, Size = 8,1870    isCodeGenOnly = 0, hasSideEffects = 0, mayStore = 0, mayLoad = 0 in1871def PseudoJump : Pseudo<(outs GPR:$rd), (ins pseudo_jump_symbol:$target), [],1872                        "jump", "$target, $rd">,1873                 Sched<[WriteIALU, WriteJalr, ReadJalr]>;1874 1875// Pseudo for a rematerializable constant materialization sequence.1876// This is an experimental feature enabled by1877// -riscv-use-rematerializable-movimm in RISCVISelDAGToDAG.cpp1878// It will be expanded after register allocation.1879// FIXME: The scheduling information does not reflect the multiple instructions.1880let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 8,1881    isReMaterializable = 1 in1882def PseudoMovImm : Pseudo<(outs GPR:$dst), (ins i32imm:$imm), []>,1883                   Sched<[WriteIALU]>;1884 1885let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 8, isCodeGenOnly = 0,1886    isAsmParserOnly = 1 in1887def PseudoLLA : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],1888                       "lla", "$dst, $src">;1889 1890// Refer to comment on PseudoLI for explanation of Size=321891let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 8, isCodeGenOnly = 0,1892    isAsmParserOnly = 1 in1893def PseudoLLAImm : Pseudo<(outs GPR:$dst), (ins ixlenimm_li_restricted:$imm), [],1894                          "lla", "$dst, $imm">;1895def : Pat<(riscv_lla tglobaladdr:$in), (PseudoLLA tglobaladdr:$in)>;1896def : Pat<(riscv_lla tblockaddress:$in), (PseudoLLA tblockaddress:$in)>;1897def : Pat<(riscv_lla tjumptable:$in), (PseudoLLA tjumptable:$in)>;1898def : Pat<(riscv_lla tconstpool:$in), (PseudoLLA tconstpool:$in)>;1899 1900let hasSideEffects = 0, mayLoad = 1, mayStore = 0, Size = 8, isCodeGenOnly = 0,1901    isAsmParserOnly = 1 in1902def PseudoLGA : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],1903                       "lga", "$dst, $src">;1904 1905let hasSideEffects = 0, mayLoad = 1, mayStore = 0, Size = 8, isCodeGenOnly = 0,1906    isAsmParserOnly = 1 in1907def PseudoLA : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],1908                      "la", "$dst, $src">;1909 1910// Refer to comment on PseudoLI for explanation of Size=321911let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 32,1912    isCodeGenOnly = 0, isAsmParserOnly = 1 in1913def PseudoLAImm : Pseudo<(outs GPR:$rd), (ins ixlenimm_li_restricted:$imm), [],1914                         "la", "$rd, $imm">;1915 1916let hasSideEffects = 0, mayLoad = 1, mayStore = 0, Size = 8, isCodeGenOnly = 0,1917    isAsmParserOnly = 1 in1918def PseudoLA_TLS_IE : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],1919                             "la.tls.ie", "$dst, $src">;1920 1921let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 8, isCodeGenOnly = 0,1922    isAsmParserOnly = 1 in1923def PseudoLA_TLS_GD : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],1924                             "la.tls.gd", "$dst, $src">;1925 1926let hasSideEffects = 0, mayLoad = 1, mayStore = 0, Size = 32, isCodeGenOnly = 0 in1927def PseudoLA_TLSDESC : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],1928                             "la.tlsdesc", "$dst, $src">;1929 1930def TLSDESCCallSymbol : AsmOperandClass {1931  let Name = "TLSDESCCallSymbol";1932  let RenderMethod = "addImmOperands";1933  let DiagnosticType = "InvalidTLSDESCCallSymbol";1934  let DiagnosticString = "operand must be a symbol with %tlsdesc_call specifier";1935  let ParserMethod = "parseOperandWithSpecifier";1936}1937 1938// A bare symbol with the %tlsdesc_call variant.1939def tlsdesc_call_symbol : Operand<XLenVT> {1940  let ParserMatchClass = TLSDESCCallSymbol;1941}1942// This is a special case of the JALR instruction used to facilitate the use of a1943// fourth operand to emit a relocation on a symbol relating to this instruction.1944// The relocation does not affect any bits of the instruction itself but is used1945// as a hint to the linker.1946let isCall = 1, isBarrier = 1, isCodeGenOnly = 0, Size = 8, hasSideEffects = 0,1947    mayStore = 0, mayLoad = 0 in1948def PseudoTLSDESCCall : Pseudo<(outs GPR:$rd),1949                         (ins GPR:$rs1, simm12_lo:$imm12, tlsdesc_call_symbol:$src), [],1950                         "jalr", "$rd, ${imm12}(${rs1}), $src">,1951                         Sched<[WriteJalr, ReadJalr]> {1952  let Defs = [X10];1953  let Uses = [X10];1954}1955 1956 1957/// Sign/Zero Extends1958 1959// There are single-instruction versions of these in Zbb, so disable these1960// Pseudos if that extension is present.1961let hasSideEffects = 0, mayLoad = 0,1962    mayStore = 0, isCodeGenOnly = 0, isAsmParserOnly = 1 in {1963def PseudoSEXT_B : Pseudo<(outs GPR:$rd), (ins GPR:$rs), [], "sext.b", "$rd, $rs">;1964def PseudoSEXT_H : Pseudo<(outs GPR:$rd), (ins GPR:$rs), [], "sext.h", "$rd, $rs">;1965// rv64's sext.w is defined above, using InstAlias<"sext.w ...1966// zext.b is defined above, using InstAlias<"zext.b ...1967def PseudoZEXT_H : Pseudo<(outs GPR:$rd), (ins GPR:$rs), [], "zext.h", "$rd, $rs">;1968} // hasSideEffects = 0, ...1969 1970let Predicates = [IsRV64], hasSideEffects = 0, mayLoad = 0, mayStore = 0,1971  isCodeGenOnly = 0, isAsmParserOnly = 1 in {1972def PseudoZEXT_W : Pseudo<(outs GPR:$rd), (ins GPR:$rs), [], "zext.w", "$rd, $rs">;1973} // Predicates = [IsRV64], ...1974 1975/// Loads1976 1977class LdPat<PatFrag LoadOp, RVInst Inst, ValueType vt = XLenVT,1978            ValueType PtrVT = XLenVT>1979    : Pat<(vt (LoadOp (AddrRegImm (PtrVT GPRMem:$rs1), simm12_lo:$imm12))),1980          (Inst GPRMem:$rs1, simm12_lo:$imm12)>;1981 1982def : LdPat<sextloadi8, LB>;1983def : LdPat<extloadi8, LBU>; // Prefer unsigned due to no c.lb in Zcb.1984def : LdPat<sextloadi16, LH>;1985def : LdPat<extloadi16, LH>;1986def : LdPat<load, LW, i32>, Requires<[IsRV32]>;1987def : LdPat<zextloadi8, LBU>;1988def : LdPat<zextloadi16, LHU>;1989 1990/// Stores1991 1992class StPat<PatFrag StoreOp, RVInst Inst, RegisterClass StTy,1993            ValueType vt, ValueType PtrVT = XLenVT>1994    : Pat<(StoreOp (vt StTy:$rs2), (AddrRegImm (PtrVT GPRMem:$rs1),1995                   simm12_lo:$imm12)),1996          (Inst StTy:$rs2, GPRMem:$rs1, simm12_lo:$imm12)>;1997 1998def : StPat<truncstorei8, SB, GPR, XLenVT>;1999def : StPat<truncstorei16, SH, GPR, XLenVT>;2000def : StPat<store, SW, GPR, i32>, Requires<[IsRV32]>;2001 2002/// Fences2003 2004// Refer to Table A.6 in the version 2.3 draft of the RISC-V Instruction Set2005// Manual: Volume I.2006 2007// fence acquire -> fence r, rw2008def : Pat<(atomic_fence (XLenVT 4), (timm)), (FENCE 0b10, 0b11)>;2009// fence release -> fence rw, w2010def : Pat<(atomic_fence (XLenVT 5), (timm)), (FENCE 0b11, 0b1)>;2011// fence acq_rel -> fence.tso2012def : Pat<(atomic_fence (XLenVT 6), (timm)), (FENCE_TSO)>;2013// fence seq_cst -> fence rw, rw2014def : Pat<(atomic_fence (XLenVT 7), (timm)), (FENCE 0b11, 0b11)>;2015 2016// Lowering for atomic load and store is defined in RISCVInstrInfoA.td.2017// Although these are lowered to fence+load/store instructions defined in the2018// base RV32I/RV64I ISA, this lowering is only used when the A extension is2019// present. This is necessary as it isn't valid to mix __atomic_* libcalls2020// with inline atomic operations for the same object.2021 2022/// Access to system registers2023 2024// Helpers for defining specific operations. They are defined for each system2025// register separately. Side effect is not used because dependencies are2026// expressed via use-def properties.2027 2028class ReadSysReg<SysReg SR, list<Register> Regs>2029  : Pseudo<(outs GPR:$rd), (ins),2030           [(set GPR:$rd, (XLenVT (riscv_read_csr (XLenVT SR.Encoding))))]>,2031    PseudoInstExpansion<(CSRRS GPR:$rd, SR.Encoding, X0)> {2032  let hasSideEffects = 0;2033  let Uses = Regs;2034}2035 2036class WriteSysReg<SysReg SR, list<Register> Regs>2037  : Pseudo<(outs), (ins GPR:$val),2038           [(riscv_write_csr (XLenVT SR.Encoding), (XLenVT GPR:$val))]>,2039    PseudoInstExpansion<(CSRRW X0, SR.Encoding, GPR:$val)> {2040  let hasSideEffects = 0;2041  let Defs = Regs;2042}2043 2044class WriteSysRegImm<SysReg SR, list<Register> Regs>2045  : Pseudo<(outs), (ins uimm5:$val),2046           [(riscv_write_csr (XLenVT SR.Encoding), uimm5:$val)]>,2047    PseudoInstExpansion<(CSRRWI X0, SR.Encoding, uimm5:$val)> {2048  let hasSideEffects = 0;2049  let Defs = Regs;2050}2051 2052class SwapSysReg<SysReg SR, list<Register> Regs>2053  : Pseudo<(outs GPR:$rd), (ins GPR:$val),2054           [(set GPR:$rd, (riscv_swap_csr (XLenVT SR.Encoding), (XLenVT GPR:$val)))]>,2055    PseudoInstExpansion<(CSRRW GPR:$rd, SR.Encoding, GPR:$val)> {2056  let hasSideEffects = 0;2057  let Uses = Regs;2058  let Defs = Regs;2059}2060 2061class SwapSysRegImm<SysReg SR, list<Register> Regs>2062  : Pseudo<(outs GPR:$rd), (ins uimm5:$val),2063           [(set GPR:$rd, (XLenVT (riscv_swap_csr (XLenVT SR.Encoding), uimm5:$val)))]>,2064    PseudoInstExpansion<(CSRRWI GPR:$rd, SR.Encoding, uimm5:$val)> {2065  let hasSideEffects = 0;2066  let Uses = Regs;2067  let Defs = Regs;2068}2069 2070class ClearSysReg<SysReg SR, list<Register> Regs>2071  : Pseudo<(outs), (ins GPR:$val),2072           [(riscv_clear_csr (XLenVT SR.Encoding), (XLenVT GPR:$val))]>,2073    PseudoInstExpansion<(CSRRC X0, SR.Encoding, GPR:$val)> {2074  let hasSideEffects = 0;2075  let Uses = Regs;2076  let Defs = Regs;2077}2078 2079class ClearSysRegImm<SysReg SR, list<Register> Regs>2080  : Pseudo<(outs), (ins uimm5:$val),2081           [(riscv_clear_csr (XLenVT SR.Encoding), uimm5:$val)]>,2082    PseudoInstExpansion<(CSRRCI X0, SR.Encoding, uimm5:$val)> {2083  let hasSideEffects = 0;2084  let Uses = Regs;2085  let Defs = Regs;2086}2087 2088class SetSysReg<SysReg SR, list<Register> Regs>2089  : Pseudo<(outs), (ins GPR:$val),2090           [(riscv_set_csr (XLenVT SR.Encoding), (XLenVT GPR:$val))]>,2091    PseudoInstExpansion<(CSRRS X0, SR.Encoding, GPR:$val)> {2092  let hasSideEffects = 0;2093  let Uses = Regs;2094  let Defs = Regs;2095}2096 2097class SetSysRegImm<SysReg SR, list<Register> Regs>2098  : Pseudo<(outs), (ins uimm5:$val),2099           [(riscv_set_csr (XLenVT SR.Encoding), uimm5:$val)]>,2100    PseudoInstExpansion<(CSRRSI X0, SR.Encoding, uimm5:$val)> {2101  let hasSideEffects = 0;2102  let Uses = Regs;2103  let Defs = Regs;2104}2105 2106def ReadFRM : ReadSysReg<SysRegFRM, [FRM]>;2107let hasPostISelHook = 1 in {2108def WriteFRM : WriteSysReg<SysRegFRM, [FRM]>;2109def WriteFRMImm : WriteSysRegImm<SysRegFRM, [FRM]>;2110def SwapFRMImm : SwapSysRegImm<SysRegFRM, [FRM]>;2111}2112 2113def WriteVXRMImm : WriteSysRegImm<SysRegVXRM, [VXRM]>;2114 2115let hasSideEffects = true in {2116def ReadFFLAGS : ReadSysReg<SysRegFFLAGS, [FFLAGS]>;2117def WriteFFLAGS : WriteSysReg<SysRegFFLAGS, [FFLAGS]>;2118}2119 2120let hasPostISelHook = 1 in {2121def ReadFCSR : ReadSysReg<SysRegFCSR, [FRM, FFLAGS]>;2122def WriteFCSR : WriteSysReg<SysRegFCSR, [FRM, FFLAGS]>;2123def WriteFCSRImm : WriteSysRegImm<SysRegFCSR, [FRM, FFLAGS]>;2124def ClearFCSR : ClearSysReg<SysRegFCSR, [FRM, FFLAGS]>;2125def ClearFCSRImm : ClearSysRegImm<SysRegFCSR, [FRM, FFLAGS]>;2126def SetFCSR : SetSysReg<SysRegFCSR, [FRM, FFLAGS]>;2127def SetFCSRImm : SetSysRegImm<SysRegFCSR, [FRM, FFLAGS]>;2128}2129 2130/// Other pseudo-instructions2131 2132// Pessimistically assume the stack pointer will be clobbered2133let Defs = [X2], Uses = [X2] in {2134def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),2135                              [(callseq_start timm:$amt1, timm:$amt2)]>;2136def ADJCALLSTACKUP   : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),2137                              [(callseq_end timm:$amt1, timm:$amt2)]>;2138} // Defs = [X2], Uses = [X2]2139 2140/// RV64 patterns2141 2142let Predicates = [IsRV64, NoStdExtZba] in {2143def : Pat<(i64 (and GPR:$rs1, 0xffffffff)), (SRLI (i64 (SLLI GPR:$rs1, 32)), 32)>;2144 2145// If we're shifting a 32-bit zero extended value left by 0-31 bits, use 22146// shifts instead of 3. This can occur when unsigned is used to index an array.2147def : Pat<(i64 (shl (and GPR:$rs1, 0xffffffff), uimm5:$shamt)),2148          (SRLI (i64 (SLLI GPR:$rs1, 32)), (ImmSubFrom32 uimm5:$shamt))>;2149} // Predicates = [IsRV64, NoStdExtZba]2150 2151class binop_allhusers<SDPatternOperator operator>2152    : PatFrag<(ops node:$lhs, node:$rhs),2153              (XLenVT (operator node:$lhs, node:$rhs)), [{2154  return hasAllHUsers(N);2155}]> {2156  let GISelPredicateCode = [{ return hasAllHUsers(MI); }];2157}2158 2159// PatFrag to allow ADDW/SUBW/MULW/SLLW to be selected from i64 add/sub/mul/shl2160// if only the lower 32 bits of their result is used.2161class binop_allwusers<SDPatternOperator operator>2162    : PatFrag<(ops node:$lhs, node:$rhs), (i64 (operator node:$lhs, node:$rhs)),2163              [{2164  return hasAllWUsers(N);2165}]> {2166  let GISelPredicateCode = [{ return hasAllWUsers(MI); }];2167}2168 2169def sexti32_allwusers : PatFrag<(ops node:$src),2170                                (sext_inreg node:$src, i32), [{2171  return hasAllWUsers(N);2172}]>;2173 2174def ImmSExt32 : SDNodeXForm<imm, [{2175  return CurDAG->getTargetConstant(SignExtend64<32>(N->getSExtValue()),2176                                   SDLoc(N), N->getValueType(0));2177}]>;2178// Look for constants where the upper 32 bits are 0, but sign extending bit 312179// would be an simm12.2180def u32simm12 : ImmLeaf<XLenVT, [{2181  return isUInt<32>(Imm) && isInt<12>(SignExtend64<32>(Imm));2182}], ImmSExt32>;2183 2184let Predicates = [IsRV64] in {2185 2186def : Pat<(i64 (and GPR:$rs, immop_oneuse<LeadingOnesWMask>:$mask)),2187          (SLLI (i64 (SRLIW $rs, (TrailingZeros imm:$mask))),2188                (TrailingZeros imm:$mask))>;2189 2190/// sext and zext2191 2192// Sign extend is not needed if all users are W instructions.2193def : Pat<(sexti32_allwusers GPR:$rs1), (XLenVT GPR:$rs1)>;2194 2195def : Pat<(sext_inreg GPR:$rs1, i32), (ADDIW GPR:$rs1, 0)>;2196 2197/// ALU operations2198 2199def : Pat<(i64 (srl (and GPR:$rs1, 0xffffffff), uimm5:$shamt)),2200          (SRLIW GPR:$rs1, uimm5:$shamt)>;2201def : Pat<(i64 (srl (shl GPR:$rs1, (i64 32)), uimm6gt32:$shamt)),2202          (SRLIW GPR:$rs1, (ImmSub32 uimm6gt32:$shamt))>;2203def : Pat<(sra (sext_inreg GPR:$rs1, i32), uimm5:$shamt),2204          (SRAIW GPR:$rs1, uimm5:$shamt)>;2205def : Pat<(i64 (sra (shl GPR:$rs1, (i64 32)), uimm6gt32:$shamt)),2206          (SRAIW GPR:$rs1, (ImmSub32 uimm6gt32:$shamt))>;2207 2208def : PatGprShiftMask32<riscv_sllw, SLLW>;2209def : PatGprShiftMask32<riscv_srlw, SRLW>;2210def : PatGprShiftMask32<riscv_sraw, SRAW>;2211 2212// Select W instructions if only the lower 32 bits of the result are used.2213def : PatGprGpr<binop_allwusers<add>, ADDW>;2214def : PatGprSimm12<binop_allwusers<add>, ADDIW>;2215def : PatGprImm<binop_allwusers<add>, ADDIW, u32simm12>;2216def : PatGprGpr<binop_allwusers<sub>, SUBW>;2217def : PatGprImm<binop_allwusers<shl>, SLLIW, uimm5>;2218 2219// If this is a shr of a value sign extended from i32, and all the users only2220// use the lower 32 bits, we can use an sraiw to remove the sext_inreg. This2221// occurs because SimplifyDemandedBits prefers srl over sra.2222def : Pat<(binop_allwusers<srl> (sext_inreg GPR:$rs1, i32), uimm5:$shamt),2223          (SRAIW GPR:$rs1, uimm5:$shamt)>;2224 2225// Use binop_allwusers to recover immediates that may have been broken by2226// SimplifyDemandedBits.2227def : Pat<(binop_allwusers<and> GPR:$rs1, 0xffffffff),2228          (COPY GPR:$rs1)>;2229def : PatGprImm<binop_allwusers<and>, ANDI, u32simm12>;2230def : PatGprImm<binop_allwusers<or>,  ORI,  u32simm12>;2231def : PatGprImm<binop_allwusers<xor>, XORI, u32simm12>;2232 2233// Select 'or' as ADDIW if the immediate bits are known to be 0 in $rs1 and2234// $rs1 is sign extended. This can improve compressibility. Using ADDIW gives2235// more power to RISCVOptWInstrs.2236def : Pat<(riscv_or_disjoint 33signbits_node:$rs1, simm12_lo:$imm),2237          (ADDIW $rs1, simm12_lo:$imm)>;2238 2239/// Loads2240 2241def : LdPat<sextloadi32, LW, i64>;2242def : LdPat<extloadi32, LW, i64>;2243def : LdPat<zextloadi32, LWU, i64>;2244def : LdPat<load, LD, i64>;2245 2246/// Stores2247 2248def : StPat<truncstorei32, SW, GPR, i64>;2249def : StPat<store, SD, GPR, i64>;2250} // Predicates = [IsRV64]2251 2252// On RV64, we can directly read these 64-bit counter CSRs.2253let Predicates = [IsRV64] in {2254/// readcyclecounter2255def : Pat<(i64 (readcyclecounter)), (CSRRS CYCLE.Encoding, (XLenVT X0))>;2256/// readsteadycounter2257def : Pat<(i64 (readsteadycounter)), (CSRRS TIME.Encoding, (XLenVT X0))>;2258}2259 2260// On RV32, ReadCounterWide will be expanded to the suggested loop reading both2261// halves of 64-bit counter CSRs.2262let Predicates = [IsRV32], usesCustomInserter = 1, hasNoSchedulingInfo = 1 in2263def ReadCounterWide : Pseudo<(outs GPR:$lo, GPR:$hi), (ins i32imm:$csr_lo, i32imm:$csr_hi),2264                             [(set GPR:$lo, GPR:$hi,2265                              (riscv_read_counter_wide csr_sysreg:$csr_lo, csr_sysreg:$csr_hi))],2266                             "", "">;2267 2268/// traps2269 2270// We lower `trap` to `unimp`, as this causes a hard exception on nearly all2271// systems.2272def : Pat<(trap), (UNIMP)>;2273 2274// We lower `debugtrap` to `ebreak`, as this will get the attention of the2275// debugger if possible.2276def : Pat<(debugtrap), (EBREAK)>;2277 2278let Predicates = [IsRV64], Uses = [X5],2279    Defs = [X1, X6, X7, X28, X29, X30, X31], Size = 8 in2280def HWASAN_CHECK_MEMACCESS_SHORTGRANULES2281  : Pseudo<(outs), (ins GPRJALR:$ptr, i32imm:$accessinfo),2282           [(int_hwasan_check_memaccess_shortgranules (i64 X5), GPRJALR:$ptr,2283                                                      (i32 timm:$accessinfo))]>;2284 2285// This gets lowered into a 20-byte instruction sequence (at most)2286let hasSideEffects = 0, mayLoad = 1, mayStore = 0,2287    Defs = [ X6, X7, X28, X29, X30, X31 ], Size = 20 in {2288def KCFI_CHECK2289  : Pseudo<(outs), (ins GPRJALR:$ptr, i32imm:$type), []>, Sched<[]>;2290}2291 2292/// Simple optimization2293def : Pat<(XLenVT (add GPR:$rs1, immop_oneuse<AddiPair>:$rs2)),2294          (ADDI (XLenVT (ADDI GPR:$rs1, (AddiPairImmLarge imm:$rs2))),2295                (AddiPairImmSmall imm:$rs2))>;2296 2297def negImm : ComplexPattern<i64, 1, "selectNegImm", [], [], 0>;2298 2299let Predicates = [IsRV64] in {2300// Select W instructions if only the lower 32-bits of the result are used.2301def : Pat<(binop_allwusers<add> GPR:$rs1, immop_oneuse<AddiPair>:$rs2),2302          (ADDIW (i64 (ADDIW GPR:$rs1, (AddiPairImmLarge imm:$rs2))),2303                 (AddiPairImmSmall imm:$rs2))>;2304 2305// Select SUB if the negated constant is cheaper to materialize.2306def : Pat<(i64 (add GPR:$rs1, negImm:$rs2)), (SUB GPR:$rs1, negImm:$rs2)>;2307}2308 2309//===----------------------------------------------------------------------===//2310// Zihintpause2311//===----------------------------------------------------------------------===//2312 2313// Zihintpause2314let Predicates = [HasStdExtZihintpause] in2315def : Pat<(int_riscv_pause), (FENCE 0x1, 0x0)>;2316 2317//===----------------------------------------------------------------------===//2318// Standard extensions2319//===----------------------------------------------------------------------===//2320 2321// Multiply and Division2322include "RISCVInstrInfoM.td"2323 2324// Atomic2325include "RISCVInstrInfoA.td"2326include "RISCVInstrInfoZa.td"2327include "RISCVInstrInfoZalasr.td"2328 2329// Integer2330include "RISCVInstrInfoZimop.td"2331include "RISCVInstrInfoZicbo.td"2332include "RISCVInstrInfoZicond.td"2333include "RISCVInstrInfoZilsd.td"2334include "RISCVInstrInfoZibi.td"2335 2336// Scalar FP2337include "RISCVInstrInfoF.td"2338include "RISCVInstrInfoD.td"2339include "RISCVInstrInfoQ.td"2340include "RISCVInstrInfoZfh.td"2341include "RISCVInstrInfoZfbfmin.td"2342include "RISCVInstrInfoZfa.td"2343 2344// Scalar bitmanip and cryptography2345include "RISCVInstrInfoZb.td"2346include "RISCVInstrInfoZk.td"2347 2348// Vector2349include "RISCVInstrInfoV.td"2350include "RISCVInstrInfoZvk.td"2351include "RISCVInstrInfoZvqdotq.td"2352include "RISCVInstrInfoZvfofp8min.td"2353 2354// Packed SIMD2355include "RISCVInstrInfoP.td"2356 2357// Compressed2358include "RISCVInstrInfoC.td"2359include "RISCVInstrInfoZc.td"2360include "RISCVInstrInfoZcmop.td"2361include "RISCVInstrInfoZclsd.td"2362 2363// Control Flow Integriy, this requires Zimop/Zcmop2364include "RISCVInstrInfoZicfiss.td"2365 2366// Short Forward Branch2367include "RISCVInstrInfoSFB.td"2368 2369//===----------------------------------------------------------------------===//2370// Vendor extensions2371//===----------------------------------------------------------------------===//2372 2373include "RISCVInstrInfoXVentana.td"2374include "RISCVInstrInfoXTHead.td"2375include "RISCVInstrInfoXSf.td"2376include "RISCVInstrInfoXSfmm.td"2377include "RISCVInstrInfoXCV.td"2378include "RISCVInstrInfoXwch.td"2379include "RISCVInstrInfoXqci.td"2380include "RISCVInstrInfoXqccmp.td"2381include "RISCVInstrInfoXMips.td"2382include "RISCVInstrInfoXRivos.td"2383include "RISCVInstrInfoXAndes.td"2384include "RISCVInstrInfoXSpacemiT.td"2385 2386//===----------------------------------------------------------------------===//2387// Global ISel2388//===----------------------------------------------------------------------===//2389 2390include "RISCVInstrGISel.td"2391