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-exception 6// 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 17// Target-independent type requirements, but with target-specific formats. 18def SDT_CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>, 19 SDTCisVT<1, i32>]>; 20def SDT_CallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, 21 SDTCisVT<1, i32>]>; 22 23// Target-dependent type requirements. 24def SDT_RISCVCall : SDTypeProfile<0, -1, [SDTCisVT<0, XLenVT>]>; 25def SDT_RISCVSelectCC : SDTypeProfile<1, 5, [SDTCisSameAs<1, 2>, 26 SDTCisVT<3, OtherVT>, 27 SDTCisSameAs<0, 4>, 28 SDTCisSameAs<4, 5>]>; 29def SDT_RISCVBrCC : SDTypeProfile<0, 4, [SDTCisSameAs<0, 1>, 30 SDTCisVT<2, OtherVT>, 31 SDTCisVT<3, OtherVT>]>; 32def SDT_RISCVReadCSR : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisInt<1>]>; 33def SDT_RISCVWriteCSR : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisInt<1>]>; 34def SDT_RISCVSwapCSR : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisInt<1>, 35 SDTCisInt<2>]>; 36def SDT_RISCVReadCycleWide : SDTypeProfile<2, 0, [SDTCisVT<0, i32>, 37 SDTCisVT<1, i32>]>; 38def SDT_RISCVIntUnaryOpW : SDTypeProfile<1, 1, [ 39 SDTCisSameAs<0, 1>, SDTCisVT<0, i64> 40]>; 41def SDT_RISCVIntBinOpW : SDTypeProfile<1, 2, [ 42 SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisVT<0, i64> 43]>; 44def SDT_RISCVIntShiftDOpW : SDTypeProfile<1, 3, [ 45 SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisVT<0, i64>, SDTCisVT<3, 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 54// Target-dependent nodes. 55def riscv_call : SDNode<"RISCVISD::CALL", SDT_RISCVCall, 56 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 57 SDNPVariadic]>; 58def riscv_ret_glue : SDNode<"RISCVISD::RET_GLUE", SDTNone, 59 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 60def riscv_sret_glue : SDNode<"RISCVISD::SRET_GLUE", SDTNone, 61 [SDNPHasChain, SDNPOptInGlue]>; 62def riscv_mret_glue : SDNode<"RISCVISD::MRET_GLUE", SDTNone, 63 [SDNPHasChain, SDNPOptInGlue]>; 64def riscv_selectcc : SDNode<"RISCVISD::SELECT_CC", SDT_RISCVSelectCC>; 65def riscv_brcc : SDNode<"RISCVISD::BR_CC", SDT_RISCVBrCC, 66 [SDNPHasChain]>; 67def riscv_tail : SDNode<"RISCVISD::TAIL", SDT_RISCVCall, 68 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 69 SDNPVariadic]>; 70def riscv_sllw : SDNode<"RISCVISD::SLLW", SDT_RISCVIntBinOpW>; 71def riscv_sraw : SDNode<"RISCVISD::SRAW", SDT_RISCVIntBinOpW>; 72def riscv_srlw : SDNode<"RISCVISD::SRLW", SDT_RISCVIntBinOpW>; 73def riscv_read_csr : SDNode<"RISCVISD::READ_CSR", SDT_RISCVReadCSR, 74 [SDNPHasChain]>; 75def riscv_write_csr : SDNode<"RISCVISD::WRITE_CSR", SDT_RISCVWriteCSR, 76 [SDNPHasChain]>; 77def riscv_swap_csr : SDNode<"RISCVISD::SWAP_CSR", SDT_RISCVSwapCSR, 78 [SDNPHasChain]>; 79 80def riscv_read_cycle_wide : SDNode<"RISCVISD::READ_CYCLE_WIDE", 81 SDT_RISCVReadCycleWide, 82 [SDNPHasChain, SDNPSideEffect]>; 83 84def riscv_add_lo : SDNode<"RISCVISD::ADD_LO", SDTIntBinOp>; 85def riscv_hi : SDNode<"RISCVISD::HI", SDTIntUnaryOp>; 86def riscv_lla : SDNode<"RISCVISD::LLA", SDTIntUnaryOp>; 87def riscv_add_tprel : SDNode<"RISCVISD::ADD_TPREL", 88 SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, 89 SDTCisSameAs<0, 2>, 90 SDTCisSameAs<0, 3>, 91 SDTCisInt<0>]>>; 92 93//===----------------------------------------------------------------------===// 94// Operand and SDNode transformation definitions. 95//===----------------------------------------------------------------------===// 96 97class ImmXLenAsmOperand<string prefix, string suffix = ""> : AsmOperandClass { 98 let Name = prefix # "ImmXLen" # suffix; 99 let RenderMethod = "addImmOperands"; 100 let DiagnosticType = !strconcat("Invalid", Name); 101} 102 103class ImmAsmOperand<string prefix, int width, string suffix> : AsmOperandClass { 104 let Name = prefix # "Imm" # width # suffix; 105 let RenderMethod = "addImmOperands"; 106 let DiagnosticType = !strconcat("Invalid", Name); 107} 108 109def ImmZeroAsmOperand : AsmOperandClass { 110 let Name = "ImmZero"; 111 let RenderMethod = "addImmOperands"; 112 let DiagnosticType = !strconcat("Invalid", Name); 113} 114 115// A parse method for (${gpr}) or 0(${gpr}), where the 0 is be silently ignored. 116def ZeroOffsetMemOpOperand : AsmOperandClass { 117 let Name = "ZeroOffsetMemOpOperand"; 118 let RenderMethod = "addRegOperands"; 119 let PredicateMethod = "isGPR"; 120 let ParserMethod = "parseZeroOffsetMemOp"; 121} 122 123class MemOperand<RegisterClass regClass> : RegisterOperand<regClass>{ 124 let OperandType = "OPERAND_MEMORY"; 125} 126 127def GPRMemZeroOffset : MemOperand<GPR> { 128 let ParserMatchClass = ZeroOffsetMemOpOperand; 129 let PrintMethod = "printZeroOffsetMemOp"; 130} 131 132def GPRMem : MemOperand<GPR>; 133 134def SPMem : MemOperand<SP>; 135 136def GPRCMem : MemOperand<GPRC>; 137 138class SImmAsmOperand<int width, string suffix = ""> 139 : ImmAsmOperand<"S", width, suffix> { 140} 141 142class UImmAsmOperand<int width, string suffix = ""> 143 : ImmAsmOperand<"U", width, suffix> { 144} 145 146class RISCVOp<ValueType vt = XLenVT> : Operand<vt> { 147 let OperandNamespace = "RISCVOp"; 148} 149 150class RISCVUImmOp<int bitsNum> : RISCVOp { 151 let ParserMatchClass = UImmAsmOperand<bitsNum>; 152 let DecoderMethod = "decodeUImmOperand<" # bitsNum # ">"; 153 let OperandType = "OPERAND_UIMM" # bitsNum; 154} 155 156class RISCVUImmLeafOp<int bitsNum> : 157 RISCVUImmOp<bitsNum>, ImmLeaf<XLenVT, "return isUInt<" # bitsNum # ">(Imm);">; 158 159class RISCVSImmOp<int bitsNum> : RISCVOp { 160 let ParserMatchClass = SImmAsmOperand<bitsNum>; 161 let EncoderMethod = "getImmOpValue"; 162 let DecoderMethod = "decodeSImmOperand<" # bitsNum # ">"; 163 let OperandType = "OPERAND_SIMM" # bitsNum; 164} 165 166class RISCVSImmLeafOp<int bitsNum> : 167 RISCVSImmOp<bitsNum>, ImmLeaf<XLenVT, "return isInt<" # bitsNum # ">(Imm);">; 168 169def FenceArg : AsmOperandClass { 170 let Name = "FenceArg"; 171 let RenderMethod = "addFenceArgOperands"; 172 let ParserMethod = "parseFenceArg"; 173} 174 175def fencearg : RISCVOp { 176 let ParserMatchClass = FenceArg; 177 let PrintMethod = "printFenceArg"; 178 let DecoderMethod = "decodeUImmOperand<4>"; 179 let OperandType = "OPERAND_UIMM4"; 180} 181 182def UImmLog2XLenAsmOperand : AsmOperandClass { 183 let Name = "UImmLog2XLen"; 184 let RenderMethod = "addImmOperands"; 185 let DiagnosticType = "InvalidUImmLog2XLen"; 186} 187 188def uimmlog2xlen : RISCVOp, ImmLeaf<XLenVT, [{ 189 if (Subtarget->is64Bit()) 190 return isUInt<6>(Imm); 191 return isUInt<5>(Imm); 192}]> { 193 let ParserMatchClass = UImmLog2XLenAsmOperand; 194 // TODO: should ensure invalid shamt is rejected when decoding. 195 let DecoderMethod = "decodeUImmOperand<6>"; 196 let MCOperandPredicate = [{ 197 int64_t Imm; 198 if (!MCOp.evaluateAsConstantImm(Imm)) 199 return false; 200 if (STI.getTargetTriple().isArch64Bit()) 201 return isUInt<6>(Imm); 202 return isUInt<5>(Imm); 203 }]; 204 let OperandType = "OPERAND_UIMMLOG2XLEN"; 205} 206 207def InsnDirectiveOpcode : AsmOperandClass { 208 let Name = "InsnDirectiveOpcode"; 209 let ParserMethod = "parseInsnDirectiveOpcode"; 210 let RenderMethod = "addImmOperands"; 211 let PredicateMethod = "isImm"; 212} 213 214def uimm1 : RISCVUImmLeafOp<1>; 215def uimm2 : RISCVUImmLeafOp<2> { 216 let MCOperandPredicate = [{ 217 int64_t Imm; 218 if (!MCOp.evaluateAsConstantImm(Imm)) 219 return false; 220 return isUInt<2>(Imm); 221 }]; 222} 223def uimm3 : RISCVUImmOp<3>; 224def uimm4 : RISCVUImmOp<4>; 225def uimm5 : RISCVUImmLeafOp<5>; 226def uimm6 : RISCVUImmLeafOp<6>; 227def uimm7_opcode : RISCVUImmOp<7> { 228 let ParserMatchClass = InsnDirectiveOpcode; 229} 230def uimm7 : RISCVUImmOp<7>; 231def uimm8 : RISCVUImmOp<8>; 232def simm12 : RISCVSImmLeafOp<12> { 233 let MCOperandPredicate = [{ 234 int64_t Imm; 235 if (MCOp.evaluateAsConstantImm(Imm)) 236 return isInt<12>(Imm); 237 return MCOp.isBareSymbolRef(); 238 }]; 239} 240 241// A 12-bit signed immediate which cannot fit in 6-bit signed immediate, 242// but even negative value fit in 12-bit. 243def simm12_no6 : ImmLeaf<XLenVT, [{ 244 return isInt<12>(Imm) && !isInt<6>(Imm) && isInt<12>(-Imm);}]>; 245 246// A 13-bit signed immediate where the least significant bit is zero. 247def simm13_lsb0 : Operand<OtherVT> { 248 let ParserMatchClass = SImmAsmOperand<13, "Lsb0">; 249 let PrintMethod = "printBranchOperand"; 250 let EncoderMethod = "getImmOpValueAsr1"; 251 let DecoderMethod = "decodeSImmOperandAndLsl1<13>"; 252 let MCOperandPredicate = [{ 253 int64_t Imm; 254 if (MCOp.evaluateAsConstantImm(Imm)) 255 return isShiftedInt<12, 1>(Imm); 256 return MCOp.isBareSymbolRef(); 257 }]; 258 let OperandType = "OPERAND_PCREL"; 259} 260 261class UImm20Operand : RISCVOp { 262 let EncoderMethod = "getImmOpValue"; 263 let DecoderMethod = "decodeUImmOperand<20>"; 264 let OperandType = "OPERAND_UIMM20"; 265} 266 267class UImm20OperandMaybeSym : UImm20Operand { 268 let MCOperandPredicate = [{ 269 int64_t Imm; 270 if (MCOp.evaluateAsConstantImm(Imm)) 271 return isUInt<20>(Imm); 272 return MCOp.isBareSymbolRef(); 273 }]; 274} 275 276def uimm20_lui : UImm20OperandMaybeSym { 277 let ParserMatchClass = UImmAsmOperand<20, "LUI">; 278} 279def uimm20_auipc : UImm20OperandMaybeSym { 280 let ParserMatchClass = UImmAsmOperand<20, "AUIPC">; 281} 282 283def uimm20 : UImm20Operand { 284 let ParserMatchClass = UImmAsmOperand<20>; 285 let MCOperandPredicate = [{ 286 int64_t Imm; 287 if (!MCOp.evaluateAsConstantImm(Imm)) 288 return false; 289 return isUInt<20>(Imm); 290 }]; 291} 292 293def Simm21Lsb0JALAsmOperand : SImmAsmOperand<21, "Lsb0JAL"> { 294 let ParserMethod = "parseJALOffset"; 295} 296 297// A 21-bit signed immediate where the least significant bit is zero. 298def simm21_lsb0_jal : Operand<OtherVT> { 299 let ParserMatchClass = Simm21Lsb0JALAsmOperand; 300 let PrintMethod = "printBranchOperand"; 301 let EncoderMethod = "getImmOpValueAsr1"; 302 let DecoderMethod = "decodeSImmOperandAndLsl1<21>"; 303 let MCOperandPredicate = [{ 304 int64_t Imm; 305 if (MCOp.evaluateAsConstantImm(Imm)) 306 return isShiftedInt<20, 1>(Imm); 307 return MCOp.isBareSymbolRef(); 308 }]; 309 let OperandType = "OPERAND_PCREL"; 310} 311 312def BareSymbol : AsmOperandClass { 313 let Name = "BareSymbol"; 314 let RenderMethod = "addImmOperands"; 315 let DiagnosticType = "InvalidBareSymbol"; 316 let ParserMethod = "parseBareSymbol"; 317} 318 319// A bare symbol. 320def bare_symbol : Operand<XLenVT> { 321 let ParserMatchClass = BareSymbol; 322} 323 324def CallSymbol : AsmOperandClass { 325 let Name = "CallSymbol"; 326 let RenderMethod = "addImmOperands"; 327 let DiagnosticType = "InvalidCallSymbol"; 328 let ParserMethod = "parseCallSymbol"; 329} 330 331// A bare symbol used in call/tail only. 332def call_symbol : Operand<XLenVT> { 333 let ParserMatchClass = CallSymbol; 334} 335 336def PseudoJumpSymbol : AsmOperandClass { 337 let Name = "PseudoJumpSymbol"; 338 let RenderMethod = "addImmOperands"; 339 let DiagnosticType = "InvalidPseudoJumpSymbol"; 340 let ParserMethod = "parsePseudoJumpSymbol"; 341} 342 343// A bare symbol used for pseudo jumps only. 344def pseudo_jump_symbol : Operand<XLenVT> { 345 let ParserMatchClass = PseudoJumpSymbol; 346} 347 348def TPRelAddSymbol : AsmOperandClass { 349 let Name = "TPRelAddSymbol"; 350 let RenderMethod = "addImmOperands"; 351 let DiagnosticType = "InvalidTPRelAddSymbol"; 352 let ParserMethod = "parseOperandWithModifier"; 353} 354 355// A bare symbol with the %tprel_add variant. 356def tprel_add_symbol : Operand<XLenVT> { 357 let ParserMatchClass = TPRelAddSymbol; 358} 359 360def CSRSystemRegister : AsmOperandClass { 361 let Name = "CSRSystemRegister"; 362 let ParserMethod = "parseCSRSystemRegister"; 363 let DiagnosticType = "InvalidCSRSystemRegister"; 364} 365 366def csr_sysreg : RISCVOp { 367 let ParserMatchClass = CSRSystemRegister; 368 let PrintMethod = "printCSRSystemRegister"; 369 let DecoderMethod = "decodeUImmOperand<12>"; 370 let OperandType = "OPERAND_UIMM12"; 371} 372 373// A parameterized register class alternative to i32imm/i64imm from Target.td. 374def ixlenimm : Operand<XLenVT>; 375 376def ixlenimm_li : Operand<XLenVT> { 377 let ParserMatchClass = ImmXLenAsmOperand<"", "LI">; 378} 379 380// Accepts subset of LI operands, used by LAImm and LLAImm 381def ixlenimm_li_restricted : Operand<XLenVT> { 382 let ParserMatchClass = ImmXLenAsmOperand<"", "LI_Restricted">; 383} 384 385// Standalone (codegen-only) immleaf patterns. 386 387// A 6-bit constant greater than 32. 388def uimm6gt32 : ImmLeaf<XLenVT, [{ 389 return isUInt<6>(Imm) && Imm > 32; 390}]>; 391 392// Addressing modes. 393// Necessary because a frameindex can't be matched directly in a pattern. 394def FrameAddrRegImm : ComplexPattern<iPTR, 2, "SelectFrameAddrRegImm", 395 [frameindex, or, add]>; 396def AddrRegImm : ComplexPattern<iPTR, 2, "SelectAddrRegImm">; 397 398// Return the negation of an immediate value. 399def NegImm : SDNodeXForm<imm, [{ 400 return CurDAG->getTargetConstant(-N->getSExtValue(), SDLoc(N), 401 N->getValueType(0)); 402}]>; 403 404// Return an immediate value minus 32. 405def ImmSub32 : SDNodeXForm<imm, [{ 406 return CurDAG->getTargetConstant(N->getSExtValue() - 32, SDLoc(N), 407 N->getValueType(0)); 408}]>; 409 410// Return an immediate subtracted from XLen. 411def ImmSubFromXLen : SDNodeXForm<imm, [{ 412 uint64_t XLen = Subtarget->getXLen(); 413 return CurDAG->getTargetConstant(XLen - N->getZExtValue(), SDLoc(N), 414 N->getValueType(0)); 415}]>; 416 417// Return an immediate subtracted from 32. 418def ImmSubFrom32 : SDNodeXForm<imm, [{ 419 return CurDAG->getTargetConstant(32 - N->getZExtValue(), SDLoc(N), 420 N->getValueType(0)); 421}]>; 422 423// Check if (add r, imm) can be optimized to (ADDI (ADDI r, imm0), imm1), 424// in which imm = imm0 + imm1 and both imm0 and imm1 are simm12. We make imm0 425// as large as possible and imm1 as small as possible so that we might be able 426// to use c.addi for the small immediate. 427def AddiPair : PatLeaf<(imm), [{ 428 if (!N->hasOneUse()) 429 return false; 430 // The immediate operand must be in range [-4096,-2049] or [2048,4094]. 431 int64_t Imm = N->getSExtValue(); 432 return (-4096 <= Imm && Imm <= -2049) || (2048 <= Imm && Imm <= 4094); 433}]>; 434 435// Return imm - (imm < 0 ? -2048 : 2047). 436def AddiPairImmSmall : SDNodeXForm<imm, [{ 437 int64_t Imm = N->getSExtValue(); 438 int64_t Adj = N->getSExtValue() < 0 ? -2048 : 2047; 439 return CurDAG->getTargetConstant(Imm - Adj, SDLoc(N), 440 N->getValueType(0)); 441}]>; 442 443// Return -2048 if immediate is negative or 2047 if positive. These are the 444// largest simm12 values. 445def AddiPairImmLarge : SDNodeXForm<imm, [{ 446 int64_t Imm = N->getSExtValue() < 0 ? -2048 : 2047; 447 return CurDAG->getTargetConstant(Imm, SDLoc(N), 448 N->getValueType(0)); 449}]>; 450 451def TrailingZeros : SDNodeXForm<imm, [{ 452 return CurDAG->getTargetConstant(llvm::countr_zero(N->getZExtValue()), 453 SDLoc(N), N->getValueType(0)); 454}]>; 455 456def XLenSubTrailingOnes : SDNodeXForm<imm, [{ 457 uint64_t XLen = Subtarget->getXLen(); 458 uint64_t TrailingOnes = llvm::countr_one(N->getZExtValue()); 459 return CurDAG->getTargetConstant(XLen - TrailingOnes, SDLoc(N), 460 N->getValueType(0)); 461}]>; 462 463// Checks if this mask is a non-empty sequence of ones starting at the 464// most/least significant bit with the remainder zero and exceeds simm32/simm12. 465def LeadingOnesMask : PatLeaf<(imm), [{ 466 if (!N->hasOneUse()) 467 return false; 468 return !isInt<32>(N->getSExtValue()) && isMask_64(~N->getSExtValue()); 469}], TrailingZeros>; 470 471def TrailingOnesMask : PatLeaf<(imm), [{ 472 if (!N->hasOneUse()) 473 return false; 474 return !isInt<12>(N->getSExtValue()) && isMask_64(N->getZExtValue()); 475}], XLenSubTrailingOnes>; 476 477// Similar to LeadingOnesMask, but only consider leading ones in the lower 32 478// bits. 479def LeadingOnesWMask : PatLeaf<(imm), [{ 480 if (!N->hasOneUse()) 481 return false; 482 // If the value is a uint32 but not an int32, it must have bit 31 set and 483 // bits 63:32 cleared. After that we're looking for a shifted mask but not 484 // an all ones mask. 485 int64_t Imm = N->getSExtValue(); 486 return !isInt<32>(Imm) && isUInt<32>(Imm) && isShiftedMask_64(Imm) && 487 Imm != UINT64_C(0xffffffff); 488}], TrailingZeros>; 489 490//===----------------------------------------------------------------------===// 491// Instruction Formats 492//===----------------------------------------------------------------------===// 493 494include "RISCVInstrFormats.td" 495 496//===----------------------------------------------------------------------===// 497// Instruction Class Templates 498//===----------------------------------------------------------------------===// 499 500let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 501class BranchCC_rri<bits<3> funct3, string opcodestr> 502 : RVInstB<funct3, OPC_BRANCH, (outs), 503 (ins GPR:$rs1, GPR:$rs2, simm13_lsb0:$imm12), 504 opcodestr, "$rs1, $rs2, $imm12">, 505 Sched<[WriteJmp, ReadJmp, ReadJmp]> { 506 let isBranch = 1; 507 let isTerminator = 1; 508} 509 510let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 511class Load_ri<bits<3> funct3, string opcodestr> 512 : RVInstI<funct3, OPC_LOAD, (outs GPR:$rd), (ins GPRMem:$rs1, simm12:$imm12), 513 opcodestr, "$rd, ${imm12}(${rs1})">; 514 515class HLoad_r<bits<7> funct7, bits<5> funct5, string opcodestr> 516 : RVInstR<funct7, 0b100, OPC_SYSTEM, (outs GPR:$rd), 517 (ins GPRMemZeroOffset:$rs1), opcodestr, "$rd, $rs1"> { 518 let rs2 = funct5; 519} 520} 521 522// Operands for stores are in the order srcreg, base, offset rather than 523// reflecting the order these fields are specified in the instruction 524// encoding. 525let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { 526class Store_rri<bits<3> funct3, string opcodestr> 527 : RVInstS<funct3, OPC_STORE, (outs), 528 (ins GPR:$rs2, GPRMem:$rs1, simm12:$imm12), 529 opcodestr, "$rs2, ${imm12}(${rs1})">; 530 531class HStore_rr<bits<7> funct7, string opcodestr> 532 : RVInstR<funct7, 0b100, OPC_SYSTEM, (outs), 533 (ins GPR:$rs2, GPRMemZeroOffset:$rs1), 534 opcodestr, "$rs2, $rs1"> { 535 let rd = 0; 536} 537} 538 539let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 540class ALU_ri<bits<3> funct3, string opcodestr> 541 : RVInstI<funct3, OPC_OP_IMM, (outs GPR:$rd), (ins GPR:$rs1, simm12:$imm12), 542 opcodestr, "$rd, $rs1, $imm12">, 543 Sched<[WriteIALU, ReadIALU]>; 544 545let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 546class Shift_ri<bits<5> imm11_7, bits<3> funct3, string opcodestr> 547 : RVInstIShift<imm11_7, funct3, OPC_OP_IMM, (outs GPR:$rd), 548 (ins GPR:$rs1, uimmlog2xlen:$shamt), opcodestr, 549 "$rd, $rs1, $shamt">, 550 Sched<[WriteShiftImm, ReadShiftImm]>; 551 552let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 553class ALU_rr<bits<7> funct7, bits<3> funct3, string opcodestr, 554 bit Commutable = 0> 555 : RVInstR<funct7, funct3, OPC_OP, (outs GPR:$rd), (ins GPR:$rs1, GPR:$rs2), 556 opcodestr, "$rd, $rs1, $rs2"> { 557 let isCommutable = Commutable; 558} 559 560let hasNoSchedulingInfo = 1, 561 hasSideEffects = 1, mayLoad = 0, mayStore = 0 in 562class CSR_ir<bits<3> funct3, string opcodestr> 563 : RVInstI<funct3, OPC_SYSTEM, (outs GPR:$rd), (ins csr_sysreg:$imm12, GPR:$rs1), 564 opcodestr, "$rd, $imm12, $rs1">, Sched<[WriteCSR, ReadCSR]>; 565 566let hasNoSchedulingInfo = 1, 567 hasSideEffects = 1, mayLoad = 0, mayStore = 0 in 568class CSR_ii<bits<3> funct3, string opcodestr> 569 : RVInstI<funct3, OPC_SYSTEM, (outs GPR:$rd), 570 (ins csr_sysreg:$imm12, uimm5:$rs1), 571 opcodestr, "$rd, $imm12, $rs1">, Sched<[WriteCSR]>; 572 573let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 574class ShiftW_ri<bits<7> imm11_5, bits<3> funct3, string opcodestr> 575 : RVInstIShiftW<imm11_5, funct3, OPC_OP_IMM_32, (outs GPR:$rd), 576 (ins GPR:$rs1, uimm5:$shamt), opcodestr, 577 "$rd, $rs1, $shamt">, 578 Sched<[WriteShiftImm32, ReadShiftImm32]>; 579 580let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 581class ALUW_rr<bits<7> funct7, bits<3> funct3, string opcodestr, 582 bit Commutable = 0> 583 : RVInstR<funct7, funct3, OPC_OP_32, (outs GPR:$rd), 584 (ins GPR:$rs1, GPR:$rs2), opcodestr, "$rd, $rs1, $rs2"> { 585 let isCommutable = Commutable; 586} 587 588let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in 589class Priv<string opcodestr, bits<7> funct7> 590 : RVInstR<funct7, 0b000, OPC_SYSTEM, (outs), (ins GPR:$rs1, GPR:$rs2), 591 opcodestr, "">; 592 593let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in 594class Priv_rr<string opcodestr, bits<7> funct7> 595 : RVInstR<funct7, 0b000, OPC_SYSTEM, (outs), (ins GPR:$rs1, GPR:$rs2), 596 opcodestr, "$rs1, $rs2"> { 597 let rd = 0; 598} 599 600//===----------------------------------------------------------------------===// 601// Instructions 602//===----------------------------------------------------------------------===// 603 604let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { 605let isReMaterializable = 1, isAsCheapAsAMove = 1, 606 IsSignExtendingOpW = 1 in 607def LUI : RVInstU<OPC_LUI, (outs GPR:$rd), (ins uimm20_lui:$imm20), 608 "lui", "$rd, $imm20">, Sched<[WriteIALU]>; 609 610def AUIPC : RVInstU<OPC_AUIPC, (outs GPR:$rd), (ins uimm20_auipc:$imm20), 611 "auipc", "$rd, $imm20">, Sched<[WriteIALU]>; 612 613def JAL : RVInstJ<OPC_JAL, (outs GPR:$rd), (ins simm21_lsb0_jal:$imm20), 614 "jal", "$rd, $imm20">, Sched<[WriteJal]>; 615 616def JALR : RVInstI<0b000, OPC_JALR, (outs GPR:$rd), 617 (ins GPR:$rs1, simm12:$imm12), 618 "jalr", "$rd, ${imm12}(${rs1})">, 619 Sched<[WriteJalr, ReadJalr]>; 620} // hasSideEffects = 0, mayLoad = 0, mayStore = 0 621 622def BEQ : BranchCC_rri<0b000, "beq">; 623def BNE : BranchCC_rri<0b001, "bne">; 624def BLT : BranchCC_rri<0b100, "blt">; 625def BGE : BranchCC_rri<0b101, "bge">; 626def BLTU : BranchCC_rri<0b110, "bltu">; 627def BGEU : BranchCC_rri<0b111, "bgeu">; 628 629let IsSignExtendingOpW = 1 in { 630def LB : Load_ri<0b000, "lb">, Sched<[WriteLDB, ReadMemBase]>; 631def LH : Load_ri<0b001, "lh">, Sched<[WriteLDH, ReadMemBase]>; 632def LW : Load_ri<0b010, "lw">, Sched<[WriteLDW, ReadMemBase]>; 633def LBU : Load_ri<0b100, "lbu">, Sched<[WriteLDB, ReadMemBase]>; 634def LHU : Load_ri<0b101, "lhu">, Sched<[WriteLDH, ReadMemBase]>; 635} 636 637def SB : Store_rri<0b000, "sb">, Sched<[WriteSTB, ReadStoreData, ReadMemBase]>; 638def SH : Store_rri<0b001, "sh">, Sched<[WriteSTH, ReadStoreData, ReadMemBase]>; 639def SW : Store_rri<0b010, "sw">, Sched<[WriteSTW, ReadStoreData, ReadMemBase]>; 640 641// ADDI isn't always rematerializable, but isReMaterializable will be used as 642// a hint which is verified in isReallyTriviallyReMaterializable. 643let isReMaterializable = 1, isAsCheapAsAMove = 1 in 644def ADDI : ALU_ri<0b000, "addi">; 645 646let IsSignExtendingOpW = 1 in { 647def SLTI : ALU_ri<0b010, "slti">; 648def SLTIU : ALU_ri<0b011, "sltiu">; 649} 650 651let isReMaterializable = 1, isAsCheapAsAMove = 1 in { 652def XORI : ALU_ri<0b100, "xori">; 653def ORI : ALU_ri<0b110, "ori">; 654} 655 656def ANDI : ALU_ri<0b111, "andi">; 657 658def SLLI : Shift_ri<0b00000, 0b001, "slli">; 659def SRLI : Shift_ri<0b00000, 0b101, "srli">; 660def SRAI : Shift_ri<0b01000, 0b101, "srai">; 661 662def ADD : ALU_rr<0b0000000, 0b000, "add", Commutable=1>, 663 Sched<[WriteIALU, ReadIALU, ReadIALU]>; 664def SUB : ALU_rr<0b0100000, 0b000, "sub">, 665 Sched<[WriteIALU, ReadIALU, ReadIALU]>; 666def SLL : ALU_rr<0b0000000, 0b001, "sll">, 667 Sched<[WriteShiftReg, ReadShiftReg, ReadShiftReg]>; 668let IsSignExtendingOpW = 1 in { 669def SLT : ALU_rr<0b0000000, 0b010, "slt">, 670 Sched<[WriteIALU, ReadIALU, ReadIALU]>; 671def SLTU : ALU_rr<0b0000000, 0b011, "sltu">, 672 Sched<[WriteIALU, ReadIALU, ReadIALU]>; 673} 674def XOR : ALU_rr<0b0000000, 0b100, "xor", Commutable=1>, 675 Sched<[WriteIALU, ReadIALU, ReadIALU]>; 676def SRL : ALU_rr<0b0000000, 0b101, "srl">, 677 Sched<[WriteShiftReg, ReadShiftReg, ReadShiftReg]>; 678def SRA : ALU_rr<0b0100000, 0b101, "sra">, 679 Sched<[WriteShiftReg, ReadShiftReg, ReadShiftReg]>; 680def OR : ALU_rr<0b0000000, 0b110, "or", Commutable=1>, 681 Sched<[WriteIALU, ReadIALU, ReadIALU]>; 682def AND : ALU_rr<0b0000000, 0b111, "and", Commutable=1>, 683 Sched<[WriteIALU, ReadIALU, ReadIALU]>; 684 685let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in { 686def FENCE : RVInstI<0b000, OPC_MISC_MEM, (outs), 687 (ins fencearg:$pred, fencearg:$succ), 688 "fence", "$pred, $succ">, Sched<[]> { 689 bits<4> pred; 690 bits<4> succ; 691 692 let rs1 = 0; 693 let rd = 0; 694 let imm12 = {0b0000,pred,succ}; 695} 696 697def FENCE_TSO : RVInstI<0b000, OPC_MISC_MEM, (outs), (ins), "fence.tso", "">, Sched<[]> { 698 let rs1 = 0; 699 let rd = 0; 700 let imm12 = {0b1000,0b0011,0b0011}; 701} 702 703def FENCE_I : RVInstI<0b001, OPC_MISC_MEM, (outs), (ins), "fence.i", "">, Sched<[]> { 704 let rs1 = 0; 705 let rd = 0; 706 let imm12 = 0; 707} 708 709def ECALL : RVInstI<0b000, OPC_SYSTEM, (outs), (ins), "ecall", "">, Sched<[WriteJmp]> { 710 let rs1 = 0; 711 let rd = 0; 712 let imm12 = 0; 713} 714 715def EBREAK : RVInstI<0b000, OPC_SYSTEM, (outs), (ins), "ebreak", "">, 716 Sched<[]> { 717 let rs1 = 0; 718 let rd = 0; 719 let imm12 = 1; 720} 721 722// This is a de facto standard (as set by GNU binutils) 32-bit unimplemented 723// instruction (i.e., it should always trap, if your implementation has invalid 724// instruction traps). 725def UNIMP : RVInstI<0b001, OPC_SYSTEM, (outs), (ins), "unimp", "">, 726 Sched<[]> { 727 let rs1 = 0; 728 let rd = 0; 729 let imm12 = 0b110000000000; 730} 731 732} // hasSideEffects = 1, mayLoad = 0, mayStore = 0 733 734def CSRRW : CSR_ir<0b001, "csrrw">; 735def CSRRS : CSR_ir<0b010, "csrrs">; 736def CSRRC : CSR_ir<0b011, "csrrc">; 737 738def CSRRWI : CSR_ii<0b101, "csrrwi">; 739def CSRRSI : CSR_ii<0b110, "csrrsi">; 740def CSRRCI : CSR_ii<0b111, "csrrci">; 741 742/// RV64I instructions 743 744let Predicates = [IsRV64] in { 745def LWU : Load_ri<0b110, "lwu">, Sched<[WriteLDW, ReadMemBase]>; 746def LD : Load_ri<0b011, "ld">, Sched<[WriteLDD, ReadMemBase]>; 747def SD : Store_rri<0b011, "sd">, Sched<[WriteSTD, ReadStoreData, ReadMemBase]>; 748 749let IsSignExtendingOpW = 1 in { 750let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 751def ADDIW : RVInstI<0b000, OPC_OP_IMM_32, (outs GPR:$rd), 752 (ins GPR:$rs1, simm12:$imm12), 753 "addiw", "$rd, $rs1, $imm12">, 754 Sched<[WriteIALU32, ReadIALU32]>; 755 756def SLLIW : ShiftW_ri<0b0000000, 0b001, "slliw">; 757def SRLIW : ShiftW_ri<0b0000000, 0b101, "srliw">; 758def SRAIW : ShiftW_ri<0b0100000, 0b101, "sraiw">; 759 760def ADDW : ALUW_rr<0b0000000, 0b000, "addw", Commutable=1>, 761 Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>; 762def SUBW : ALUW_rr<0b0100000, 0b000, "subw">, 763 Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>; 764def SLLW : ALUW_rr<0b0000000, 0b001, "sllw">, 765 Sched<[WriteShiftReg32, ReadShiftReg32, ReadShiftReg32]>; 766def SRLW : ALUW_rr<0b0000000, 0b101, "srlw">, 767 Sched<[WriteShiftReg32, ReadShiftReg32, ReadShiftReg32]>; 768def SRAW : ALUW_rr<0b0100000, 0b101, "sraw">, 769 Sched<[WriteShiftReg32, ReadShiftReg32, ReadShiftReg32]>; 770} // IsSignExtendingOpW = 1 771} // Predicates = [IsRV64] 772 773//===----------------------------------------------------------------------===// 774// Privileged instructions 775//===----------------------------------------------------------------------===// 776 777let isBarrier = 1, isReturn = 1, isTerminator = 1 in { 778def SRET : Priv<"sret", 0b0001000>, Sched<[]> { 779 let rd = 0; 780 let rs1 = 0; 781 let rs2 = 0b00010; 782} 783 784def MRET : Priv<"mret", 0b0011000>, Sched<[]> { 785 let rd = 0; 786 let rs1 = 0; 787 let rs2 = 0b00010; 788} 789} // isBarrier = 1, isReturn = 1, isTerminator = 1 790 791def WFI : Priv<"wfi", 0b0001000>, Sched<[]> { 792 let rd = 0; 793 let rs1 = 0; 794 let rs2 = 0b00101; 795} 796 797let Predicates = [HasStdExtSvinval] in { 798def SFENCE_W_INVAL : Priv<"sfence.w.inval", 0b0001100>, Sched<[]> { 799 let rd = 0; 800 let rs1 = 0; 801 let rs2 = 0; 802} 803 804def SFENCE_INVAL_IR : Priv<"sfence.inval.ir", 0b0001100>, Sched<[]> { 805 let rd = 0; 806 let rs1 = 0; 807 let rs2 = 0b00001; 808} 809def SINVAL_VMA : Priv_rr<"sinval.vma", 0b0001011>, Sched<[]>; 810def HINVAL_VVMA : Priv_rr<"hinval.vvma", 0b0010011>, Sched<[]>; 811def HINVAL_GVMA : Priv_rr<"hinval.gvma", 0b0110011>, Sched<[]>; 812} // Predicates = [HasStdExtSvinval] 813 814def SFENCE_VMA : Priv_rr<"sfence.vma", 0b0001001>, Sched<[]>; 815 816let Predicates = [HasStdExtH] in { 817def HFENCE_VVMA : Priv_rr<"hfence.vvma", 0b0010001>, Sched<[]>; 818def HFENCE_GVMA : Priv_rr<"hfence.gvma", 0b0110001>, Sched<[]>; 819 820def HLV_B : HLoad_r<0b0110000, 0b00000, "hlv.b">, Sched<[]>; 821def HLV_BU : HLoad_r<0b0110000, 0b00001, "hlv.bu">, Sched<[]>; 822def HLV_H : HLoad_r<0b0110010, 0b00000, "hlv.h">, Sched<[]>; 823def HLV_HU : HLoad_r<0b0110010, 0b00001, "hlv.hu">, Sched<[]>; 824def HLVX_HU : HLoad_r<0b0110010, 0b00011, "hlvx.hu">, Sched<[]>; 825def HLV_W : HLoad_r<0b0110100, 0b00000, "hlv.w">, Sched<[]>; 826def HLVX_WU : HLoad_r<0b0110100, 0b00011, "hlvx.wu">, Sched<[]>; 827def HSV_B : HStore_rr<0b0110001, "hsv.b">, Sched<[]>; 828def HSV_H : HStore_rr<0b0110011, "hsv.h">, Sched<[]>; 829def HSV_W : HStore_rr<0b0110101, "hsv.w">, Sched<[]>; 830} 831let Predicates = [IsRV64, HasStdExtH] in { 832def HLV_WU : HLoad_r<0b0110100, 0b00001, "hlv.wu">, Sched<[]>; 833def HLV_D : HLoad_r<0b0110110, 0b00000, "hlv.d">, Sched<[]>; 834def HSV_D : HStore_rr<0b0110111, "hsv.d">, Sched<[]>; 835} 836 837//===----------------------------------------------------------------------===// 838// Debug instructions 839//===----------------------------------------------------------------------===// 840 841let isBarrier = 1, isReturn = 1, isTerminator = 1 in { 842def DRET : Priv<"dret", 0b0111101>, Sched<[]> { 843 let rd = 0; 844 let rs1 = 0; 845 let rs2 = 0b10010; 846} 847} // isBarrier = 1, isReturn = 1, isTerminator = 1 848 849//===----------------------------------------------------------------------===// 850// Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20) 851//===----------------------------------------------------------------------===// 852 853def : InstAlias<"nop", (ADDI X0, X0, 0)>; 854 855// Note that the size is 32 because up to 8 32-bit instructions are needed to 856// generate an arbitrary 64-bit immediate. However, the size does not really 857// matter since PseudoLI is currently only used in the AsmParser where it gets 858// expanded to real instructions immediately. 859let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 32, 860 isCodeGenOnly = 0, isAsmParserOnly = 1 in 861def PseudoLI : Pseudo<(outs GPR:$rd), (ins ixlenimm_li:$imm), [], 862 "li", "$rd, $imm">; 863 864def PseudoLB : PseudoLoad<"lb">; 865def PseudoLBU : PseudoLoad<"lbu">; 866def PseudoLH : PseudoLoad<"lh">; 867def PseudoLHU : PseudoLoad<"lhu">; 868def PseudoLW : PseudoLoad<"lw">; 869 870def PseudoSB : PseudoStore<"sb">; 871def PseudoSH : PseudoStore<"sh">; 872def PseudoSW : PseudoStore<"sw">; 873 874let Predicates = [IsRV64] in { 875def PseudoLWU : PseudoLoad<"lwu">; 876def PseudoLD : PseudoLoad<"ld">; 877def PseudoSD : PseudoStore<"sd">; 878} // Predicates = [IsRV64] 879 880def : InstAlias<"li $rd, $imm", (ADDI GPR:$rd, X0, simm12:$imm)>; 881def : InstAlias<"mv $rd, $rs", (ADDI GPR:$rd, GPR:$rs, 0)>; 882def : InstAlias<"not $rd, $rs", (XORI GPR:$rd, GPR:$rs, -1)>; 883def : InstAlias<"neg $rd, $rs", (SUB GPR:$rd, X0, GPR:$rs)>; 884 885let Predicates = [IsRV64] in { 886def : InstAlias<"negw $rd, $rs", (SUBW GPR:$rd, X0, GPR:$rs)>; 887def : InstAlias<"sext.w $rd, $rs", (ADDIW GPR:$rd, GPR:$rs, 0)>; 888} // Predicates = [IsRV64] 889 890def : InstAlias<"seqz $rd, $rs", (SLTIU GPR:$rd, GPR:$rs, 1)>; 891def : InstAlias<"snez $rd, $rs", (SLTU GPR:$rd, X0, GPR:$rs)>; 892def : InstAlias<"sltz $rd, $rs", (SLT GPR:$rd, GPR:$rs, X0)>; 893def : InstAlias<"sgtz $rd, $rs", (SLT GPR:$rd, X0, GPR:$rs)>; 894 895// sgt/sgtu are recognised by the GNU assembler but the canonical slt/sltu 896// form will always be printed. Therefore, set a zero weight. 897def : InstAlias<"sgt $rd, $rs, $rt", (SLT GPR:$rd, GPR:$rt, GPR:$rs), 0>; 898def : InstAlias<"sgtu $rd, $rs, $rt", (SLTU GPR:$rd, GPR:$rt, GPR:$rs), 0>; 899 900def : InstAlias<"beqz $rs, $offset", 901 (BEQ GPR:$rs, X0, simm13_lsb0:$offset)>; 902def : InstAlias<"bnez $rs, $offset", 903 (BNE GPR:$rs, X0, simm13_lsb0:$offset)>; 904def : InstAlias<"blez $rs, $offset", 905 (BGE X0, GPR:$rs, simm13_lsb0:$offset)>; 906def : InstAlias<"bgez $rs, $offset", 907 (BGE GPR:$rs, X0, simm13_lsb0:$offset)>; 908def : InstAlias<"bltz $rs, $offset", 909 (BLT GPR:$rs, X0, simm13_lsb0:$offset)>; 910def : InstAlias<"bgtz $rs, $offset", 911 (BLT X0, GPR:$rs, simm13_lsb0:$offset)>; 912 913// Always output the canonical mnemonic for the pseudo branch instructions. 914// The GNU tools emit the canonical mnemonic for the branch pseudo instructions 915// as well (e.g. "bgt" will be recognised by the assembler but never printed by 916// objdump). Match this behaviour by setting a zero weight. 917def : InstAlias<"bgt $rs, $rt, $offset", 918 (BLT GPR:$rt, GPR:$rs, simm13_lsb0:$offset), 0>; 919def : InstAlias<"ble $rs, $rt, $offset", 920 (BGE GPR:$rt, GPR:$rs, simm13_lsb0:$offset), 0>; 921def : InstAlias<"bgtu $rs, $rt, $offset", 922 (BLTU GPR:$rt, GPR:$rs, simm13_lsb0:$offset), 0>; 923def : InstAlias<"bleu $rs, $rt, $offset", 924 (BGEU GPR:$rt, GPR:$rs, simm13_lsb0:$offset), 0>; 925 926def : InstAlias<"j $offset", (JAL X0, simm21_lsb0_jal:$offset)>; 927def : InstAlias<"jal $offset", (JAL X1, simm21_lsb0_jal:$offset)>; 928 929// Non-zero offset aliases of "jalr" are the lowest weight, followed by the 930// two-register form, then the one-register forms and finally "ret". 931def : InstAlias<"jr $rs", (JALR X0, GPR:$rs, 0), 3>; 932def : InstAlias<"jr ${offset}(${rs})", (JALR X0, GPR:$rs, simm12:$offset)>; 933def : InstAlias<"jalr $rs", (JALR X1, GPR:$rs, 0), 3>; 934def : InstAlias<"jalr ${offset}(${rs})", (JALR X1, GPR:$rs, simm12:$offset)>; 935def : InstAlias<"jalr $rd, $rs", (JALR GPR:$rd, GPR:$rs, 0), 2>; 936def : InstAlias<"ret", (JALR X0, X1, 0), 4>; 937 938// Non-canonical forms for jump targets also accepted by the assembler. 939def : InstAlias<"jr $rs, $offset", (JALR X0, GPR:$rs, simm12:$offset), 0>; 940def : InstAlias<"jalr $rs, $offset", (JALR X1, GPR:$rs, simm12:$offset), 0>; 941def : InstAlias<"jalr $rd, $rs, $offset", (JALR GPR:$rd, GPR:$rs, simm12:$offset), 0>; 942 943def : InstAlias<"fence", (FENCE 0xF, 0xF)>; // 0xF == iorw 944 945let Predicates = [HasStdExtZihintpause] in 946def : InstAlias<"pause", (FENCE 0x1, 0x0)>; // 0x1 == w 947 948def : InstAlias<"rdinstret $rd", (CSRRS GPR:$rd, INSTRET.Encoding, X0)>; 949def : InstAlias<"rdcycle $rd", (CSRRS GPR:$rd, CYCLE.Encoding, X0)>; 950def : InstAlias<"rdtime $rd", (CSRRS GPR:$rd, TIME.Encoding, X0)>; 951 952let Predicates = [IsRV32] in { 953def : InstAlias<"rdinstreth $rd", (CSRRS GPR:$rd, INSTRETH.Encoding, X0)>; 954def : InstAlias<"rdcycleh $rd", (CSRRS GPR:$rd, CYCLEH.Encoding, X0)>; 955def : InstAlias<"rdtimeh $rd", (CSRRS GPR:$rd, TIMEH.Encoding, X0)>; 956} // Predicates = [IsRV32] 957 958def : InstAlias<"csrr $rd, $csr", (CSRRS GPR:$rd, csr_sysreg:$csr, X0)>; 959def : InstAlias<"csrw $csr, $rs", (CSRRW X0, csr_sysreg:$csr, GPR:$rs)>; 960def : InstAlias<"csrs $csr, $rs", (CSRRS X0, csr_sysreg:$csr, GPR:$rs)>; 961def : InstAlias<"csrc $csr, $rs", (CSRRC X0, csr_sysreg:$csr, GPR:$rs)>; 962 963def : InstAlias<"csrwi $csr, $imm", (CSRRWI X0, csr_sysreg:$csr, uimm5:$imm)>; 964def : InstAlias<"csrsi $csr, $imm", (CSRRSI X0, csr_sysreg:$csr, uimm5:$imm)>; 965def : InstAlias<"csrci $csr, $imm", (CSRRCI X0, csr_sysreg:$csr, uimm5:$imm)>; 966 967let EmitPriority = 0 in { 968def : InstAlias<"csrw $csr, $imm", (CSRRWI X0, csr_sysreg:$csr, uimm5:$imm)>; 969def : InstAlias<"csrs $csr, $imm", (CSRRSI X0, csr_sysreg:$csr, uimm5:$imm)>; 970def : InstAlias<"csrc $csr, $imm", (CSRRCI X0, csr_sysreg:$csr, uimm5:$imm)>; 971 972def : InstAlias<"csrrw $rd, $csr, $imm", (CSRRWI GPR:$rd, csr_sysreg:$csr, uimm5:$imm)>; 973def : InstAlias<"csrrs $rd, $csr, $imm", (CSRRSI GPR:$rd, csr_sysreg:$csr, uimm5:$imm)>; 974def : InstAlias<"csrrc $rd, $csr, $imm", (CSRRCI GPR:$rd, csr_sysreg:$csr, uimm5:$imm)>; 975} 976 977def : InstAlias<"sfence.vma", (SFENCE_VMA X0, X0)>; 978def : InstAlias<"sfence.vma $rs", (SFENCE_VMA GPR:$rs, X0)>; 979 980def : InstAlias<"hfence.gvma", (HFENCE_GVMA X0, X0)>; 981def : InstAlias<"hfence.gvma $rs", (HFENCE_GVMA GPR:$rs, X0)>; 982 983def : InstAlias<"hfence.vvma", (HFENCE_VVMA X0, X0)>; 984def : InstAlias<"hfence.vvma $rs", (HFENCE_VVMA GPR:$rs, X0)>; 985 986let Predicates = [HasStdExtZihintntl] in { 987 def : InstAlias<"ntl.p1", (ADD X0, X0, X2)>; 988 def : InstAlias<"ntl.pall", (ADD X0, X0, X3)>; 989 def : InstAlias<"ntl.s1", (ADD X0, X0, X4)>; 990 def : InstAlias<"ntl.all", (ADD X0, X0, X5)>; 991} // Predicates = [HasStdExtZihintntl] 992 993let EmitPriority = 0 in { 994def : InstAlias<"lb $rd, (${rs1})", 995 (LB GPR:$rd, GPR:$rs1, 0)>; 996def : InstAlias<"lh $rd, (${rs1})", 997 (LH GPR:$rd, GPR:$rs1, 0)>; 998def : InstAlias<"lw $rd, (${rs1})", 999 (LW GPR:$rd, GPR:$rs1, 0)>; 1000def : InstAlias<"lbu $rd, (${rs1})", 1001 (LBU GPR:$rd, GPR:$rs1, 0)>; 1002def : InstAlias<"lhu $rd, (${rs1})", 1003 (LHU GPR:$rd, GPR:$rs1, 0)>; 1004 1005def : InstAlias<"sb $rs2, (${rs1})", 1006 (SB GPR:$rs2, GPR:$rs1, 0)>; 1007def : InstAlias<"sh $rs2, (${rs1})", 1008 (SH GPR:$rs2, GPR:$rs1, 0)>; 1009def : InstAlias<"sw $rs2, (${rs1})", 1010 (SW GPR:$rs2, GPR:$rs1, 0)>; 1011 1012def : InstAlias<"add $rd, $rs1, $imm12", 1013 (ADDI GPR:$rd, GPR:$rs1, simm12:$imm12)>; 1014def : InstAlias<"and $rd, $rs1, $imm12", 1015 (ANDI GPR:$rd, GPR:$rs1, simm12:$imm12)>; 1016def : InstAlias<"xor $rd, $rs1, $imm12", 1017 (XORI GPR:$rd, GPR:$rs1, simm12:$imm12)>; 1018def : InstAlias<"or $rd, $rs1, $imm12", 1019 (ORI GPR:$rd, GPR:$rs1, simm12:$imm12)>; 1020def : InstAlias<"sll $rd, $rs1, $shamt", 1021 (SLLI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt)>; 1022def : InstAlias<"srl $rd, $rs1, $shamt", 1023 (SRLI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt)>; 1024def : InstAlias<"sra $rd, $rs1, $shamt", 1025 (SRAI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt)>; 1026let Predicates = [IsRV64] in { 1027def : InstAlias<"lwu $rd, (${rs1})", 1028 (LWU GPR:$rd, GPR:$rs1, 0)>; 1029def : InstAlias<"ld $rd, (${rs1})", 1030 (LD GPR:$rd, GPR:$rs1, 0)>; 1031def : InstAlias<"sd $rs2, (${rs1})", 1032 (SD GPR:$rs2, GPR:$rs1, 0)>; 1033 1034def : InstAlias<"addw $rd, $rs1, $imm12", 1035 (ADDIW GPR:$rd, GPR:$rs1, simm12:$imm12)>; 1036def : InstAlias<"sllw $rd, $rs1, $shamt", 1037 (SLLIW GPR:$rd, GPR:$rs1, uimm5:$shamt)>; 1038def : InstAlias<"srlw $rd, $rs1, $shamt", 1039 (SRLIW GPR:$rd, GPR:$rs1, uimm5:$shamt)>; 1040def : InstAlias<"sraw $rd, $rs1, $shamt", 1041 (SRAIW GPR:$rd, GPR:$rs1, uimm5:$shamt)>; 1042} // Predicates = [IsRV64] 1043def : InstAlias<"slt $rd, $rs1, $imm12", 1044 (SLTI GPR:$rd, GPR:$rs1, simm12:$imm12)>; 1045def : InstAlias<"sltu $rd, $rs1, $imm12", 1046 (SLTIU GPR:$rd, GPR:$rs1, simm12:$imm12)>; 1047} 1048 1049def : MnemonicAlias<"move", "mv">; 1050 1051// The SCALL and SBREAK instructions wererenamed to ECALL and EBREAK in 1052// version 2.1 of the user-level ISA. Like the GNU toolchain, we still accept 1053// the old name for backwards compatibility. 1054def : MnemonicAlias<"scall", "ecall">; 1055def : MnemonicAlias<"sbreak", "ebreak">; 1056 1057// This alias was added to the spec in December 2020. Don't print it by default 1058// to allow assembly we print to be compatible with versions of GNU assembler 1059// that don't support this alias. 1060def : InstAlias<"zext.b $rd, $rs", (ANDI GPR:$rd, GPR:$rs, 0xFF), 0>; 1061 1062let Predicates = [HasStdExtZicfilp] in { 1063def : InstAlias<"lpad $imm20", (AUIPC X0, uimm20:$imm20)>; 1064} 1065 1066//===----------------------------------------------------------------------===// 1067// .insn directive instructions 1068//===----------------------------------------------------------------------===// 1069 1070def AnyRegOperand : AsmOperandClass { 1071 let Name = "AnyRegOperand"; 1072 let RenderMethod = "addRegOperands"; 1073 let PredicateMethod = "isAnyReg"; 1074} 1075 1076def AnyReg : Operand<XLenVT> { 1077 let OperandType = "OPERAND_REGISTER"; 1078 let ParserMatchClass = AnyRegOperand; 1079} 1080 1081// isCodeGenOnly = 1 to hide them from the tablegened assembly parser. 1082let isCodeGenOnly = 1, hasSideEffects = 1, mayLoad = 1, mayStore = 1, 1083 hasNoSchedulingInfo = 1 in { 1084def InsnR : DirectiveInsnR<(outs AnyReg:$rd), (ins uimm7_opcode:$opcode, uimm3:$funct3, 1085 uimm7:$funct7, AnyReg:$rs1, 1086 AnyReg:$rs2), 1087 "$opcode, $funct3, $funct7, $rd, $rs1, $rs2">; 1088def InsnR4 : DirectiveInsnR4<(outs AnyReg:$rd), (ins uimm7_opcode:$opcode, 1089 uimm3:$funct3, 1090 uimm2:$funct2, 1091 AnyReg:$rs1, AnyReg:$rs2, 1092 AnyReg:$rs3), 1093 "$opcode, $funct3, $funct2, $rd, $rs1, $rs2, $rs3">; 1094def InsnI : DirectiveInsnI<(outs AnyReg:$rd), (ins uimm7_opcode:$opcode, uimm3:$funct3, 1095 AnyReg:$rs1, simm12:$imm12), 1096 "$opcode, $funct3, $rd, $rs1, $imm12">; 1097def InsnI_Mem : DirectiveInsnI<(outs AnyReg:$rd), (ins uimm7_opcode:$opcode, 1098 uimm3:$funct3, 1099 AnyReg:$rs1, 1100 simm12:$imm12), 1101 "$opcode, $funct3, $rd, ${imm12}(${rs1})">; 1102def InsnB : DirectiveInsnB<(outs), (ins uimm7_opcode:$opcode, uimm3:$funct3, 1103 AnyReg:$rs1, AnyReg:$rs2, 1104 simm13_lsb0:$imm12), 1105 "$opcode, $funct3, $rs1, $rs2, $imm12">; 1106def InsnU : DirectiveInsnU<(outs AnyReg:$rd), (ins uimm7_opcode:$opcode, 1107 uimm20_lui:$imm20), 1108 "$opcode, $rd, $imm20">; 1109def InsnJ : DirectiveInsnJ<(outs AnyReg:$rd), (ins uimm7_opcode:$opcode, 1110 simm21_lsb0_jal:$imm20), 1111 "$opcode, $rd, $imm20">; 1112def InsnS : DirectiveInsnS<(outs), (ins uimm7_opcode:$opcode, uimm3:$funct3, 1113 AnyReg:$rs2, AnyReg:$rs1, 1114 simm12:$imm12), 1115 "$opcode, $funct3, $rs2, ${imm12}(${rs1})">; 1116} 1117 1118// Use InstAliases to match these so that we can combine the insn and format 1119// into a mnemonic to use as the key for the tablegened asm matcher table. The 1120// parser will take care of creating these fake mnemonics and will only do it 1121// for known formats. 1122let EmitPriority = 0 in { 1123def : InstAlias<".insn_r $opcode, $funct3, $funct7, $rd, $rs1, $rs2", 1124 (InsnR AnyReg:$rd, uimm7_opcode:$opcode, uimm3:$funct3, uimm7:$funct7, 1125 AnyReg:$rs1, AnyReg:$rs2)>; 1126// Accept 4 register form of ".insn r" as alias for ".insn r4". 1127def : InstAlias<".insn_r $opcode, $funct3, $funct2, $rd, $rs1, $rs2, $rs3", 1128 (InsnR4 AnyReg:$rd, uimm7_opcode:$opcode, uimm3:$funct3, uimm2:$funct2, 1129 AnyReg:$rs1, AnyReg:$rs2, AnyReg:$rs3)>; 1130def : InstAlias<".insn_r4 $opcode, $funct3, $funct2, $rd, $rs1, $rs2, $rs3", 1131 (InsnR4 AnyReg:$rd, uimm7_opcode:$opcode, uimm3:$funct3, uimm2:$funct2, 1132 AnyReg:$rs1, AnyReg:$rs2, AnyReg:$rs3)>; 1133def : InstAlias<".insn_i $opcode, $funct3, $rd, $rs1, $imm12", 1134 (InsnI AnyReg:$rd, uimm7_opcode:$opcode, uimm3:$funct3, AnyReg:$rs1, 1135 simm12:$imm12)>; 1136def : InstAlias<".insn_i $opcode, $funct3, $rd, ${imm12}(${rs1})", 1137 (InsnI_Mem AnyReg:$rd, uimm7_opcode:$opcode, uimm3:$funct3, 1138 AnyReg:$rs1, simm12:$imm12)>; 1139def : InstAlias<".insn_b $opcode, $funct3, $rs1, $rs2, $imm12", 1140 (InsnB uimm7_opcode:$opcode, uimm3:$funct3, AnyReg:$rs1, 1141 AnyReg:$rs2, simm13_lsb0:$imm12)>; 1142// Accept sb as an alias for b. 1143def : InstAlias<".insn_sb $opcode, $funct3, $rs1, $rs2, $imm12", 1144 (InsnB uimm7_opcode:$opcode, uimm3:$funct3, AnyReg:$rs1, 1145 AnyReg:$rs2, simm13_lsb0:$imm12)>; 1146def : InstAlias<".insn_u $opcode, $rd, $imm20", 1147 (InsnU AnyReg:$rd, uimm7_opcode:$opcode, uimm20_lui:$imm20)>; 1148def : InstAlias<".insn_j $opcode, $rd, $imm20", 1149 (InsnJ AnyReg:$rd, uimm7_opcode:$opcode, simm21_lsb0_jal:$imm20)>; 1150// Accept uj as an alias for j. 1151def : InstAlias<".insn_uj $opcode, $rd, $imm20", 1152 (InsnJ AnyReg:$rd, uimm7_opcode:$opcode, simm21_lsb0_jal:$imm20)>; 1153def : InstAlias<".insn_s $opcode, $funct3, $rs2, ${imm12}(${rs1})", 1154 (InsnS uimm7_opcode:$opcode, uimm3:$funct3, AnyReg:$rs2, 1155 AnyReg:$rs1, simm12:$imm12)>; 1156} 1157 1158//===----------------------------------------------------------------------===// 1159// Pseudo-instructions and codegen patterns 1160// 1161// Naming convention: For 'generic' pattern classes, we use the naming 1162// convention PatTy1Ty2. For pattern classes which offer a more complex 1163// expansion, prefix the class name, e.g. BccPat. 1164//===----------------------------------------------------------------------===// 1165 1166/// Generic pattern classes 1167 1168class PatGpr<SDPatternOperator OpNode, RVInst Inst, ValueType vt = XLenVT> 1169 : Pat<(vt (OpNode (vt GPR:$rs1))), (Inst GPR:$rs1)>; 1170class PatGprGpr<SDPatternOperator OpNode, RVInst Inst, ValueType vt1 = XLenVT, 1171 ValueType vt2 = XLenVT> 1172 : Pat<(vt1 (OpNode (vt1 GPR:$rs1), (vt2 GPR:$rs2))), (Inst GPR:$rs1, GPR:$rs2)>; 1173 1174class PatGprImm<SDPatternOperator OpNode, RVInst Inst, ImmLeaf ImmType, 1175 ValueType vt = XLenVT> 1176 : Pat<(vt (OpNode (vt GPR:$rs1), ImmType:$imm)), 1177 (Inst GPR:$rs1, ImmType:$imm)>; 1178class PatGprSimm12<SDPatternOperator OpNode, RVInstI Inst> 1179 : PatGprImm<OpNode, Inst, simm12>; 1180class PatGprUimmLog2XLen<SDPatternOperator OpNode, RVInstIShift Inst> 1181 : PatGprImm<OpNode, Inst, uimmlog2xlen>; 1182 1183/// Predicates 1184 1185def assertsexti32 : PatFrag<(ops node:$src), (assertsext node:$src), [{ 1186 return cast<VTSDNode>(N->getOperand(1))->getVT().bitsLE(MVT::i32); 1187}]>; 1188def sexti16 : ComplexPattern<XLenVT, 1, "selectSExtBits<16>">; 1189def sexti32 : ComplexPattern<i64, 1, "selectSExtBits<32>">; 1190def assertzexti32 : PatFrag<(ops node:$src), (assertzext node:$src), [{ 1191 return cast<VTSDNode>(N->getOperand(1))->getVT().bitsLE(MVT::i32); 1192}]>; 1193def zexti32 : ComplexPattern<i64, 1, "selectZExtBits<32>">; 1194def zexti16 : ComplexPattern<XLenVT, 1, "selectZExtBits<16>">; 1195def zexti16i32 : ComplexPattern<i32, 1, "selectZExtBits<16>">; 1196def zexti8 : ComplexPattern<XLenVT, 1, "selectZExtBits<8>">; 1197def zexti8i32 : ComplexPattern<i32, 1, "selectZExtBits<8>">; 1198 1199def ext : PatFrags<(ops node:$A), [(sext node:$A), (zext node:$A)]>; 1200 1201class binop_oneuse<SDPatternOperator operator> 1202 : PatFrag<(ops node:$A, node:$B), 1203 (operator node:$A, node:$B), [{ 1204 return N->hasOneUse(); 1205}]>; 1206 1207def and_oneuse : binop_oneuse<and>; 1208def mul_oneuse : binop_oneuse<mul>; 1209 1210def mul_const_oneuse : PatFrag<(ops node:$A, node:$B), 1211 (mul node:$A, node:$B), [{ 1212 if (auto *N1C = dyn_cast<ConstantSDNode>(N->getOperand(1))) 1213 return N1C->hasOneUse(); 1214 return false; 1215}]>; 1216 1217class unop_oneuse<SDPatternOperator operator> 1218 : PatFrag<(ops node:$A), 1219 (operator node:$A), [{ 1220 return N->hasOneUse(); 1221}]>; 1222 1223def sext_oneuse : unop_oneuse<sext>; 1224def zext_oneuse : unop_oneuse<zext>; 1225def anyext_oneuse : unop_oneuse<anyext>; 1226def ext_oneuse : unop_oneuse<ext>; 1227def fpext_oneuse : unop_oneuse<any_fpextend>; 1228 1229def 33signbits_node : PatLeaf<(i64 GPR:$src), [{ 1230 return CurDAG->ComputeNumSignBits(SDValue(N, 0)) > 32; 1231}]>; 1232 1233/// Simple arithmetic operations 1234 1235def : PatGprGpr<add, ADD>; 1236def : PatGprSimm12<add, ADDI>; 1237def : PatGprGpr<sub, SUB>; 1238def : PatGprGpr<or, OR>; 1239def : PatGprSimm12<or, ORI>; 1240def : PatGprGpr<and, AND>; 1241def : PatGprSimm12<and, ANDI>; 1242def : PatGprGpr<xor, XOR>; 1243def : PatGprSimm12<xor, XORI>; 1244def : PatGprUimmLog2XLen<shl, SLLI>; 1245def : PatGprUimmLog2XLen<srl, SRLI>; 1246def : PatGprUimmLog2XLen<sra, SRAI>; 1247 1248// Select 'or' as ADDI if the immediate bits are known to be 0 in $rs1. This 1249// can improve compressibility. 1250def or_is_add : PatFrag<(ops node:$lhs, node:$rhs), (or node:$lhs, node:$rhs),[{ 1251 KnownBits Known0 = CurDAG->computeKnownBits(N->getOperand(0), 0); 1252 KnownBits Known1 = CurDAG->computeKnownBits(N->getOperand(1), 0); 1253 return KnownBits::haveNoCommonBitsSet(Known0, Known1); 1254}]>; 1255def : PatGprSimm12<or_is_add, ADDI>; 1256 1257// negate of low bit can be done via two (compressible) shifts. The negate 1258// is never compressible since rs1 and rd can't be the same register. 1259def : Pat<(XLenVT (sub 0, (and_oneuse GPR:$rs, 1))), 1260 (SRAI (SLLI $rs, (ImmSubFromXLen (XLenVT 1))), 1261 (ImmSubFromXLen (XLenVT 1)))>; 1262 1263// AND with leading/trailing ones mask exceeding simm32/simm12. 1264def : Pat<(i64 (and GPR:$rs, LeadingOnesMask:$mask)), 1265 (SLLI (SRLI $rs, LeadingOnesMask:$mask), LeadingOnesMask:$mask)>; 1266def : Pat<(XLenVT (and GPR:$rs, TrailingOnesMask:$mask)), 1267 (SRLI (SLLI $rs, TrailingOnesMask:$mask), TrailingOnesMask:$mask)>; 1268 1269// Match both a plain shift and one where the shift amount is masked (this is 1270// typically introduced when the legalizer promotes the shift amount and 1271// zero-extends it). For RISC-V, the mask is unnecessary as shifts in the base 1272// ISA only read the least significant 5 bits (RV32I) or 6 bits (RV64I). 1273def shiftMaskXLen : ComplexPattern<XLenVT, 1, "selectShiftMaskXLen", [], [], 0>; 1274def shiftMask32 : ComplexPattern<i64, 1, "selectShiftMask32", [], [], 0>; 1275 1276class shiftop<SDPatternOperator operator> 1277 : PatFrag<(ops node:$val, node:$count), 1278 (operator node:$val, (XLenVT (shiftMaskXLen node:$count)))>; 1279class shiftopw<SDPatternOperator operator> 1280 : PatFrag<(ops node:$val, node:$count), 1281 (operator node:$val, (i64 (shiftMask32 node:$count)))>; 1282 1283def : PatGprGpr<shiftop<shl>, SLL>; 1284def : PatGprGpr<shiftop<srl>, SRL>; 1285def : PatGprGpr<shiftop<sra>, SRA>; 1286 1287// This is a special case of the ADD instruction used to facilitate the use of a 1288// fourth operand to emit a relocation on a symbol relating to this instruction. 1289// The relocation does not affect any bits of the instruction itself but is used 1290// as a hint to the linker. 1291let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 0 in 1292def PseudoAddTPRel : Pseudo<(outs GPR:$rd), 1293 (ins GPR:$rs1, GPR:$rs2, tprel_add_symbol:$src), [], 1294 "add", "$rd, $rs1, $rs2, $src">; 1295 1296/// FrameIndex calculations 1297 1298def : Pat<(FrameAddrRegImm (iPTR GPR:$rs1), simm12:$imm12), 1299 (ADDI GPR:$rs1, simm12:$imm12)>; 1300 1301/// HI and ADD_LO address nodes. 1302 1303def : Pat<(riscv_hi tglobaladdr:$in), (LUI tglobaladdr:$in)>; 1304def : Pat<(riscv_hi tblockaddress:$in), (LUI tblockaddress:$in)>; 1305def : Pat<(riscv_hi tjumptable:$in), (LUI tjumptable:$in)>; 1306def : Pat<(riscv_hi tconstpool:$in), (LUI tconstpool:$in)>; 1307 1308def : Pat<(riscv_add_lo GPR:$hi, tglobaladdr:$lo), 1309 (ADDI GPR:$hi, tglobaladdr:$lo)>; 1310def : Pat<(riscv_add_lo GPR:$hi, tblockaddress:$lo), 1311 (ADDI GPR:$hi, tblockaddress:$lo)>; 1312def : Pat<(riscv_add_lo GPR:$hi, tjumptable:$lo), 1313 (ADDI GPR:$hi, tjumptable:$lo)>; 1314def : Pat<(riscv_add_lo GPR:$hi, tconstpool:$lo), 1315 (ADDI GPR:$hi, tconstpool:$lo)>; 1316 1317/// TLS address nodes. 1318 1319def : Pat<(riscv_hi tglobaltlsaddr:$in), (LUI tglobaltlsaddr:$in)>; 1320def : Pat<(riscv_add_tprel GPR:$rs1, GPR:$rs2, tglobaltlsaddr:$src), 1321 (PseudoAddTPRel GPR:$rs1, GPR:$rs2, tglobaltlsaddr:$src)>; 1322def : Pat<(riscv_add_lo GPR:$src, tglobaltlsaddr:$lo), 1323 (ADDI GPR:$src, tglobaltlsaddr:$lo)>; 1324 1325/// Setcc 1326 1327def : PatGprGpr<setlt, SLT>; 1328def : PatGprSimm12<setlt, SLTI>; 1329def : PatGprGpr<setult, SLTU>; 1330def : PatGprSimm12<setult, SLTIU>; 1331 1332// RISC-V doesn't have general instructions for integer setne/seteq, but we can 1333// check for equality with 0. These ComplexPatterns rewrite the setne/seteq into 1334// something that can be compared with 0. 1335// These ComplexPatterns must be used in pairs. 1336def riscv_setne : ComplexPattern<XLenVT, 1, "selectSETNE", [setcc]>; 1337def riscv_seteq : ComplexPattern<XLenVT, 1, "selectSETEQ", [setcc]>; 1338 1339// Define pattern expansions for setcc operations that aren't directly 1340// handled by a RISC-V instruction. 1341def : Pat<(riscv_seteq (XLenVT GPR:$rs1)), (SLTIU GPR:$rs1, 1)>; 1342def : Pat<(riscv_setne (XLenVT GPR:$rs1)), (SLTU (XLenVT X0), GPR:$rs1)>; 1343def : Pat<(XLenVT (setne (XLenVT GPR:$rs1), -1)), (SLTIU GPR:$rs1, -1)>; 1344 1345def IntCCtoRISCVCC : SDNodeXForm<riscv_selectcc, [{ 1346 ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get(); 1347 RISCVCC::CondCode BrCC = getRISCVCCForIntCC(CC); 1348 return CurDAG->getTargetConstant(BrCC, SDLoc(N), Subtarget->getXLenVT()); 1349}]>; 1350 1351def riscv_selectcc_frag : PatFrag<(ops node:$lhs, node:$rhs, node:$cc, 1352 node:$truev, node:$falsev), 1353 (riscv_selectcc node:$lhs, node:$rhs, 1354 node:$cc, node:$truev, 1355 node:$falsev), [{}], 1356 IntCCtoRISCVCC>; 1357 1358let Predicates = [HasShortForwardBranchOpt], isSelect = 1, 1359 Constraints = "$dst = $falsev", isCommutable = 1, Size = 8 in { 1360// This instruction moves $truev to $dst when the condition is true. It will 1361// be expanded to control flow in RISCVExpandPseudoInsts. 1362def PseudoCCMOVGPR : Pseudo<(outs GPR:$dst), 1363 (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, 1364 GPR:$falsev, GPR:$truev), 1365 [(set GPR:$dst, 1366 (riscv_selectcc_frag:$cc (XLenVT GPR:$lhs), 1367 GPR:$rhs, cond, 1368 (XLenVT GPR:$truev), 1369 GPR:$falsev))]>, 1370 Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, 1371 ReadSFBALU, ReadSFBALU]>; 1372} 1373 1374// This should always expand to a branch+c.mv so the size is 6 or 4 if the 1375// branch is compressible. 1376let Predicates = [HasConditionalMoveFusion, NoShortForwardBranchOpt], 1377 Constraints = "$dst = $falsev", isCommutable = 1, Size = 6 in { 1378// This instruction moves $truev to $dst when the condition is true. It will 1379// be expanded to control flow in RISCVExpandPseudoInsts. 1380// We use GPRNoX0 because c.mv cannot encode X0. 1381def PseudoCCMOVGPRNoX0 : Pseudo<(outs GPRNoX0:$dst), 1382 (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, 1383 GPRNoX0:$falsev, GPRNoX0:$truev), 1384 [(set GPRNoX0:$dst, 1385 (riscv_selectcc_frag:$cc (XLenVT GPR:$lhs), 1386 (XLenVT GPR:$rhs), 1387 cond, (XLenVT GPRNoX0:$truev), 1388 (XLenVT GPRNoX0:$falsev)))]>, 1389 Sched<[]>; 1390} 1391 1392// Conditional binops, that updates update $dst to (op rs1, rs2) when condition 1393// is true. Returns $falsev otherwise. Selected by optimizeSelect. 1394// TODO: Can we use DefaultOperands on the regular binop to accomplish this more 1395// like how ARM does predication? 1396let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 8, 1397 Constraints = "$dst = $falsev" in { 1398def PseudoCCADD : Pseudo<(outs GPR:$dst), 1399 (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, 1400 GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, 1401 Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, 1402 ReadSFBALU, ReadSFBALU, ReadSFBALU]>; 1403def PseudoCCSUB : Pseudo<(outs GPR:$dst), 1404 (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, 1405 GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, 1406 Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, 1407 ReadSFBALU, ReadSFBALU, ReadSFBALU]>; 1408def PseudoCCSLL : Pseudo<(outs GPR:$dst), 1409 (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, 1410 GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, 1411 Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, 1412 ReadSFBALU, ReadSFBALU]>; 1413def PseudoCCSRL : Pseudo<(outs GPR:$dst), 1414 (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, 1415 GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, 1416 Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, 1417 ReadSFBALU, ReadSFBALU]>; 1418def PseudoCCSRA : Pseudo<(outs GPR:$dst), 1419 (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, 1420 GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, 1421 Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, 1422 ReadSFBALU, ReadSFBALU]>; 1423def PseudoCCAND : Pseudo<(outs GPR:$dst), 1424 (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, 1425 GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, 1426 Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, 1427 ReadSFBALU, ReadSFBALU, ReadSFBALU]>; 1428def PseudoCCOR : Pseudo<(outs GPR:$dst), 1429 (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, 1430 GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, 1431 Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, 1432 ReadSFBALU, ReadSFBALU, ReadSFBALU]>; 1433def PseudoCCXOR : Pseudo<(outs GPR:$dst), 1434 (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, 1435 GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, 1436 Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, 1437 ReadSFBALU, ReadSFBALU, ReadSFBALU]>; 1438 1439def PseudoCCADDI : Pseudo<(outs GPR:$dst), 1440 (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, 1441 GPR:$falsev, GPR:$rs1, simm12:$rs2), []>, 1442 Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, 1443 ReadSFBALU]>; 1444def PseudoCCSLLI : Pseudo<(outs GPR:$dst), 1445 (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, 1446 GPR:$falsev, GPR:$rs1, simm12:$rs2), []>, 1447 Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, 1448 ReadSFBALU]>; 1449def PseudoCCSRLI : Pseudo<(outs GPR:$dst), 1450 (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, 1451 GPR:$falsev, GPR:$rs1, simm12:$rs2), []>, 1452 Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, 1453 ReadSFBALU]>; 1454def PseudoCCSRAI : Pseudo<(outs GPR:$dst), 1455 (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, 1456 GPR:$falsev, GPR:$rs1, simm12:$rs2), []>, 1457 Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, 1458 ReadSFBALU]>; 1459def PseudoCCANDI : Pseudo<(outs GPR:$dst), 1460 (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, 1461 GPR:$falsev, GPR:$rs1, simm12:$rs2), []>, 1462 Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, 1463 ReadSFBALU]>; 1464def PseudoCCORI : Pseudo<(outs GPR:$dst), 1465 (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, 1466 GPR:$falsev, GPR:$rs1, simm12:$rs2), []>, 1467 Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, 1468 ReadSFBALU]>; 1469def PseudoCCXORI : Pseudo<(outs GPR:$dst), 1470 (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, 1471 GPR:$falsev, GPR:$rs1, simm12:$rs2), []>, 1472 Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, 1473 ReadSFBALU]>; 1474 1475// RV64I instructions 1476def PseudoCCADDW : Pseudo<(outs GPR:$dst), 1477 (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, 1478 GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, 1479 Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, 1480 ReadSFBALU, ReadSFBALU, ReadSFBALU]>; 1481def PseudoCCSUBW : Pseudo<(outs GPR:$dst), 1482 (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, 1483 GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, 1484 Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, 1485 ReadSFBALU, ReadSFBALU, ReadSFBALU]>; 1486def PseudoCCSLLW : Pseudo<(outs GPR:$dst), 1487 (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, 1488 GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, 1489 Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, 1490 ReadSFBALU, ReadSFBALU]>; 1491def PseudoCCSRLW : Pseudo<(outs GPR:$dst), 1492 (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, 1493 GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, 1494 Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, 1495 ReadSFBALU, ReadSFBALU]>; 1496def PseudoCCSRAW : Pseudo<(outs GPR:$dst), 1497 (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, 1498 GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, 1499 Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, 1500 ReadSFBALU, ReadSFBALU]>; 1501 1502def PseudoCCADDIW : Pseudo<(outs GPR:$dst), 1503 (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, 1504 GPR:$falsev, GPR:$rs1, simm12:$rs2), []>, 1505 Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, 1506 ReadSFBALU]>; 1507def PseudoCCSLLIW : Pseudo<(outs GPR:$dst), 1508 (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, 1509 GPR:$falsev, GPR:$rs1, simm12:$rs2), []>, 1510 Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, 1511 ReadSFBALU]>; 1512def PseudoCCSRLIW : Pseudo<(outs GPR:$dst), 1513 (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, 1514 GPR:$falsev, GPR:$rs1, simm12:$rs2), []>, 1515 Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, 1516 ReadSFBALU]>; 1517def PseudoCCSRAIW : Pseudo<(outs GPR:$dst), 1518 (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, 1519 GPR:$falsev, GPR:$rs1, simm12:$rs2), []>, 1520 Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU, 1521 ReadSFBALU]>; 1522 1523// Zbb/Zbkb instructions 1524def PseudoCCANDN : Pseudo<(outs GPR:$dst), 1525 (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, 1526 GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, 1527 Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, 1528 ReadSFBALU, ReadSFBALU, ReadSFBALU]>; 1529def PseudoCCORN : Pseudo<(outs GPR:$dst), 1530 (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, 1531 GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, 1532 Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, 1533 ReadSFBALU, ReadSFBALU, ReadSFBALU]>; 1534def PseudoCCXNOR : Pseudo<(outs GPR:$dst), 1535 (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, 1536 GPR:$falsev, GPR:$rs1, GPR:$rs2), []>, 1537 Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, 1538 ReadSFBALU, ReadSFBALU, ReadSFBALU]>; 1539} 1540 1541multiclass SelectCC_GPR_rrirr<DAGOperand valty, ValueType vt> { 1542 let usesCustomInserter = 1 in 1543 def _Using_CC_GPR : Pseudo<(outs valty:$dst), 1544 (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc, 1545 valty:$truev, valty:$falsev), 1546 [(set valty:$dst, 1547 (riscv_selectcc_frag:$cc (XLenVT GPR:$lhs), GPR:$rhs, cond, 1548 (vt valty:$truev), valty:$falsev))]>; 1549 // Explicitly select 0 in the condition to X0. The register coalescer doesn't 1550 // always do it. 1551 def : Pat<(riscv_selectcc_frag:$cc (XLenVT GPR:$lhs), 0, cond, (vt valty:$truev), 1552 valty:$falsev), 1553 (!cast<Instruction>(NAME#"_Using_CC_GPR") GPR:$lhs, (XLenVT X0), 1554 (IntCCtoRISCVCC $cc), valty:$truev, valty:$falsev)>; 1555} 1556 1557let Predicates = [NoConditionalMoveFusion] in 1558defm Select_GPR : SelectCC_GPR_rrirr<GPR, XLenVT>; 1559 1560class SelectCompressOpt<CondCode Cond> 1561 : Pat<(riscv_selectcc_frag:$select (XLenVT GPR:$lhs), simm12_no6:$Constant, Cond, 1562 (XLenVT GPR:$truev), GPR:$falsev), 1563 (Select_GPR_Using_CC_GPR (ADDI GPR:$lhs, (NegImm simm12:$Constant)), (XLenVT X0), 1564 (IntCCtoRISCVCC $select), GPR:$truev, GPR:$falsev)>; 1565 1566def OptForMinSize : Predicate<"MF ? MF->getFunction().hasMinSize() : false">; 1567 1568let Predicates = [HasStdExtC, OptForMinSize] in { 1569 def : SelectCompressOpt<SETEQ>; 1570 def : SelectCompressOpt<SETNE>; 1571} 1572 1573/// Branches and jumps 1574 1575// Match `riscv_brcc` and lower to the appropriate RISC-V branch instruction. 1576multiclass BccPat<CondCode Cond, RVInstB Inst> { 1577 def : Pat<(riscv_brcc (XLenVT GPR:$rs1), GPR:$rs2, Cond, bb:$imm12), 1578 (Inst GPR:$rs1, GPR:$rs2, simm13_lsb0:$imm12)>; 1579 // Explicitly select 0 to X0. The register coalescer doesn't always do it. 1580 def : Pat<(riscv_brcc (XLenVT GPR:$rs1), 0, Cond, bb:$imm12), 1581 (Inst GPR:$rs1, (XLenVT X0), simm13_lsb0:$imm12)>; 1582} 1583 1584class BrccCompressOpt<CondCode Cond, RVInstB Inst> 1585 : Pat<(riscv_brcc GPR:$lhs, simm12_no6:$Constant, Cond, bb:$place), 1586 (Inst (ADDI GPR:$lhs, (NegImm simm12:$Constant)), (XLenVT X0), bb:$place)>; 1587 1588defm : BccPat<SETEQ, BEQ>; 1589defm : BccPat<SETNE, BNE>; 1590defm : BccPat<SETLT, BLT>; 1591defm : BccPat<SETGE, BGE>; 1592defm : BccPat<SETULT, BLTU>; 1593defm : BccPat<SETUGE, BGEU>; 1594 1595let Predicates = [HasStdExtC, OptForMinSize] in { 1596 def : BrccCompressOpt<SETEQ, BEQ>; 1597 def : BrccCompressOpt<SETNE, BNE>; 1598} 1599 1600class LongBccPseudo : Pseudo<(outs), 1601 (ins GPR:$rs1, GPR:$rs2, simm21_lsb0_jal:$imm20), 1602 []> { 1603 let Size = 8; 1604 let isBarrier = 1; 1605 let isBranch = 1; 1606 let hasSideEffects = 0; 1607 let mayStore = 0; 1608 let mayLoad = 0; 1609 let isAsmParserOnly = 1; 1610 let hasNoSchedulingInfo = 1; 1611} 1612 1613def PseudoLongBEQ : LongBccPseudo; 1614def PseudoLongBNE : LongBccPseudo; 1615def PseudoLongBLT : LongBccPseudo; 1616def PseudoLongBGE : LongBccPseudo; 1617def PseudoLongBLTU : LongBccPseudo; 1618def PseudoLongBGEU : LongBccPseudo; 1619 1620let isBarrier = 1, isBranch = 1, isTerminator = 1 in 1621def PseudoBR : Pseudo<(outs), (ins simm21_lsb0_jal:$imm20), [(br bb:$imm20)]>, 1622 PseudoInstExpansion<(JAL X0, simm21_lsb0_jal:$imm20)>; 1623 1624let isBarrier = 1, isBranch = 1, isIndirectBranch = 1, isTerminator = 1 in 1625def PseudoBRIND : Pseudo<(outs), (ins GPRJALR:$rs1, simm12:$imm12), []>, 1626 PseudoInstExpansion<(JALR X0, GPR:$rs1, simm12:$imm12)>; 1627 1628def : Pat<(brind GPRJALR:$rs1), (PseudoBRIND GPRJALR:$rs1, 0)>; 1629def : Pat<(brind (add GPRJALR:$rs1, simm12:$imm12)), 1630 (PseudoBRIND GPRJALR:$rs1, simm12:$imm12)>; 1631 1632// PseudoCALLReg is a generic pseudo instruction for calls which will eventually 1633// expand to auipc and jalr while encoding, with any given register used as the 1634// destination. 1635// Define AsmString to print "call" when compile with -S flag. 1636// Define isCodeGenOnly = 0 to support parsing assembly "call" instruction. 1637let isCall = 1, isBarrier = 1, isCodeGenOnly = 0, Size = 8, hasSideEffects = 0, 1638 mayStore = 0, mayLoad = 0 in 1639def PseudoCALLReg : Pseudo<(outs GPR:$rd), (ins call_symbol:$func), [], 1640 "call", "$rd, $func">, 1641 Sched<[WriteIALU, WriteJalr, ReadJalr]>; 1642 1643// PseudoCALL is a pseudo instruction which will eventually expand to auipc 1644// and jalr while encoding. This is desirable, as an auipc+jalr pair with 1645// R_RISCV_CALL and R_RISCV_RELAX relocations can be be relaxed by the linker 1646// if the offset fits in a signed 21-bit immediate. 1647// Define AsmString to print "call" when compile with -S flag. 1648// Define isCodeGenOnly = 0 to support parsing assembly "call" instruction. 1649let isCall = 1, Defs = [X1], isCodeGenOnly = 0, Size = 8 in 1650def PseudoCALL : Pseudo<(outs), (ins call_symbol:$func), [], 1651 "call", "$func">, 1652 Sched<[WriteIALU, WriteJalr, ReadJalr]>; 1653 1654def : Pat<(riscv_call tglobaladdr:$func), (PseudoCALL tglobaladdr:$func)>; 1655def : Pat<(riscv_call texternalsym:$func), (PseudoCALL texternalsym:$func)>; 1656 1657def : Pat<(riscv_sret_glue), (SRET (XLenVT X0), (XLenVT X0))>; 1658def : Pat<(riscv_mret_glue), (MRET (XLenVT X0), (XLenVT X0))>; 1659 1660let isCall = 1, Defs = [X1] in 1661def PseudoCALLIndirect : Pseudo<(outs), (ins GPRJALR:$rs1), 1662 [(riscv_call GPRJALR:$rs1)]>, 1663 PseudoInstExpansion<(JALR X1, GPR:$rs1, 0)>; 1664 1665let isBarrier = 1, isReturn = 1, isTerminator = 1 in 1666def PseudoRET : Pseudo<(outs), (ins), [(riscv_ret_glue)]>, 1667 PseudoInstExpansion<(JALR X0, X1, 0)>; 1668 1669// PseudoTAIL is a pseudo instruction similar to PseudoCALL and will eventually 1670// expand to auipc and jalr while encoding. 1671// Define AsmString to print "tail" when compile with -S flag. 1672let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [X2], 1673 Size = 8, isCodeGenOnly = 0 in 1674def PseudoTAIL : Pseudo<(outs), (ins call_symbol:$dst), [], 1675 "tail", "$dst">, 1676 Sched<[WriteIALU, WriteJalr, ReadJalr]>; 1677 1678let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [X2] in 1679def PseudoTAILIndirect : Pseudo<(outs), (ins GPRTC:$rs1), 1680 [(riscv_tail GPRTC:$rs1)]>, 1681 PseudoInstExpansion<(JALR X0, GPR:$rs1, 0)>; 1682 1683def : Pat<(riscv_tail (iPTR tglobaladdr:$dst)), 1684 (PseudoTAIL tglobaladdr:$dst)>; 1685def : Pat<(riscv_tail (iPTR texternalsym:$dst)), 1686 (PseudoTAIL texternalsym:$dst)>; 1687 1688let isCall = 0, isBarrier = 1, isBranch = 1, isTerminator = 1, Size = 8, 1689 isCodeGenOnly = 0, hasSideEffects = 0, mayStore = 0, mayLoad = 0 in 1690def PseudoJump : Pseudo<(outs GPR:$rd), (ins pseudo_jump_symbol:$target), [], 1691 "jump", "$target, $rd">, 1692 Sched<[WriteIALU, WriteJalr, ReadJalr]>; 1693 1694// Pseudo for a rematerializable constant materialization sequence. 1695// This is an experimental feature enabled by 1696// -riscv-use-rematerializable-movimm in RISCVISelDAGToDAG.cpp 1697// It will be expanded after register allocation. 1698// FIXME: The scheduling information does not reflect the multiple instructions. 1699let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 8, isCodeGenOnly = 1, 1700 isPseudo = 1, isReMaterializable = 1, IsSignExtendingOpW = 1 in 1701def PseudoMovImm : Pseudo<(outs GPR:$dst), (ins i32imm:$imm), []>, 1702 Sched<[WriteIALU]>; 1703 1704let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 8, isCodeGenOnly = 0, 1705 isAsmParserOnly = 1 in 1706def PseudoLLA : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], 1707 "lla", "$dst, $src">; 1708 1709// Refer to comment on PseudoLI for explanation of Size=32 1710let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 8, isCodeGenOnly = 0, 1711 isAsmParserOnly = 1 in 1712def PseudoLLAImm : Pseudo<(outs GPR:$dst), (ins ixlenimm_li_restricted:$imm), [], 1713 "lla", "$dst, $imm">; 1714def : Pat<(riscv_lla tglobaladdr:$in), (PseudoLLA tglobaladdr:$in)>; 1715def : Pat<(riscv_lla tblockaddress:$in), (PseudoLLA tblockaddress:$in)>; 1716def : Pat<(riscv_lla tjumptable:$in), (PseudoLLA tjumptable:$in)>; 1717def : Pat<(riscv_lla tconstpool:$in), (PseudoLLA tconstpool:$in)>; 1718 1719let hasSideEffects = 0, mayLoad = 1, mayStore = 0, Size = 8, isCodeGenOnly = 0, 1720 isAsmParserOnly = 1 in 1721def PseudoLGA : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], 1722 "lga", "$dst, $src">; 1723 1724let hasSideEffects = 0, mayLoad = 1, mayStore = 0, Size = 8, isCodeGenOnly = 0, 1725 isAsmParserOnly = 1 in 1726def PseudoLA : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], 1727 "la", "$dst, $src">; 1728 1729// Refer to comment on PseudoLI for explanation of Size=32 1730let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 32, 1731 isCodeGenOnly = 0, isAsmParserOnly = 1 in 1732def PseudoLAImm : Pseudo<(outs GPR:$rd), (ins ixlenimm_li_restricted:$imm), [], 1733 "la", "$rd, $imm">; 1734 1735let hasSideEffects = 0, mayLoad = 1, mayStore = 0, Size = 8, isCodeGenOnly = 0, 1736 isAsmParserOnly = 1 in 1737def PseudoLA_TLS_IE : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], 1738 "la.tls.ie", "$dst, $src">; 1739 1740let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 8, isCodeGenOnly = 0, 1741 isAsmParserOnly = 1 in 1742def PseudoLA_TLS_GD : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], 1743 "la.tls.gd", "$dst, $src">; 1744 1745 1746/// Sign/Zero Extends 1747 1748// There are single-instruction versions of these in Zbb, so disable these 1749// Pseudos if that extension is present. 1750let hasSideEffects = 0, mayLoad = 0, 1751 mayStore = 0, isCodeGenOnly = 0, isAsmParserOnly = 1 in { 1752def PseudoSEXT_B : Pseudo<(outs GPR:$rd), (ins GPR:$rs), [], "sext.b", "$rd, $rs">; 1753def PseudoSEXT_H : Pseudo<(outs GPR:$rd), (ins GPR:$rs), [], "sext.h", "$rd, $rs">; 1754// rv64's sext.w is defined above, using InstAlias<"sext.w ... 1755// zext.b is defined above, using InstAlias<"zext.b ... 1756def PseudoZEXT_H : Pseudo<(outs GPR:$rd), (ins GPR:$rs), [], "zext.h", "$rd, $rs">; 1757} // hasSideEffects = 0, ... 1758 1759let Predicates = [IsRV64], hasSideEffects = 0, mayLoad = 0, mayStore = 0, 1760 isCodeGenOnly = 0, isAsmParserOnly = 1 in { 1761def PseudoZEXT_W : Pseudo<(outs GPR:$rd), (ins GPR:$rs), [], "zext.w", "$rd, $rs">; 1762} // Predicates = [IsRV64], ... 1763 1764/// Loads 1765 1766class LdPat<PatFrag LoadOp, RVInst Inst, ValueType vt = XLenVT> 1767 : Pat<(vt (LoadOp (AddrRegImm (XLenVT GPR:$rs1), simm12:$imm12))), 1768 (Inst GPR:$rs1, simm12:$imm12)>; 1769 1770def : LdPat<sextloadi8, LB>; 1771def : LdPat<extloadi8, LBU>; // Prefer unsigned due to no c.lb in Zcb. 1772def : LdPat<sextloadi16, LH>; 1773def : LdPat<extloadi16, LH>; 1774def : LdPat<load, LW, i32>; 1775def : LdPat<zextloadi8, LBU>; 1776def : LdPat<zextloadi16, LHU>; 1777 1778/// Stores 1779 1780class StPat<PatFrag StoreOp, RVInst Inst, RegisterClass StTy, 1781 ValueType vt> 1782 : Pat<(StoreOp (vt StTy:$rs2), (AddrRegImm (XLenVT GPR:$rs1), 1783 simm12:$imm12)), 1784 (Inst StTy:$rs2, GPR:$rs1, simm12:$imm12)>; 1785 1786def : StPat<truncstorei8, SB, GPR, XLenVT>; 1787def : StPat<truncstorei16, SH, GPR, XLenVT>; 1788def : StPat<store, SW, GPR, i32>; 1789 1790/// Fences 1791 1792// Refer to Table A.6 in the version 2.3 draft of the RISC-V Instruction Set 1793// Manual: Volume I. 1794 1795// fence acquire -> fence r, rw 1796def : Pat<(atomic_fence (XLenVT 4), (timm)), (FENCE 0b10, 0b11)>; 1797// fence release -> fence rw, w 1798def : Pat<(atomic_fence (XLenVT 5), (timm)), (FENCE 0b11, 0b1)>; 1799// fence acq_rel -> fence.tso 1800def : Pat<(atomic_fence (XLenVT 6), (timm)), (FENCE_TSO)>; 1801// fence seq_cst -> fence rw, rw 1802def : Pat<(atomic_fence (XLenVT 7), (timm)), (FENCE 0b11, 0b11)>; 1803 1804// Lowering for atomic load and store is defined in RISCVInstrInfoA.td. 1805// Although these are lowered to fence+load/store instructions defined in the 1806// base RV32I/RV64I ISA, this lowering is only used when the A extension is 1807// present. This is necessary as it isn't valid to mix __atomic_* libcalls 1808// with inline atomic operations for the same object. 1809 1810/// Access to system registers 1811 1812// Helpers for defining specific operations. They are defined for each system 1813// register separately. Side effect is not used because dependencies are 1814// expressed via use-def properties. 1815 1816class ReadSysReg<SysReg SR, list<Register> Regs> 1817 : Pseudo<(outs GPR:$rd), (ins), 1818 [(set GPR:$rd, (XLenVT (riscv_read_csr (XLenVT SR.Encoding))))]>, 1819 PseudoInstExpansion<(CSRRS GPR:$rd, SR.Encoding, X0)> { 1820 let hasSideEffects = 0; 1821 let Uses = Regs; 1822} 1823 1824class WriteSysReg<SysReg SR, list<Register> Regs> 1825 : Pseudo<(outs), (ins GPR:$val), 1826 [(riscv_write_csr (XLenVT SR.Encoding), (XLenVT GPR:$val))]>, 1827 PseudoInstExpansion<(CSRRW X0, SR.Encoding, GPR:$val)> { 1828 let hasSideEffects = 0; 1829 let Defs = Regs; 1830} 1831 1832class WriteSysRegImm<SysReg SR, list<Register> Regs> 1833 : Pseudo<(outs), (ins uimm5:$val), 1834 [(riscv_write_csr (XLenVT SR.Encoding), uimm5:$val)]>, 1835 PseudoInstExpansion<(CSRRWI X0, SR.Encoding, uimm5:$val)> { 1836 let hasSideEffects = 0; 1837 let Defs = Regs; 1838} 1839 1840class SwapSysReg<SysReg SR, list<Register> Regs> 1841 : Pseudo<(outs GPR:$rd), (ins GPR:$val), 1842 [(set GPR:$rd, (riscv_swap_csr (XLenVT SR.Encoding), (XLenVT GPR:$val)))]>, 1843 PseudoInstExpansion<(CSRRW GPR:$rd, SR.Encoding, GPR:$val)> { 1844 let hasSideEffects = 0; 1845 let Uses = Regs; 1846 let Defs = Regs; 1847} 1848 1849class SwapSysRegImm<SysReg SR, list<Register> Regs> 1850 : Pseudo<(outs GPR:$rd), (ins uimm5:$val), 1851 [(set GPR:$rd, (XLenVT (riscv_swap_csr (XLenVT SR.Encoding), uimm5:$val)))]>, 1852 PseudoInstExpansion<(CSRRWI GPR:$rd, SR.Encoding, uimm5:$val)> { 1853 let hasSideEffects = 0; 1854 let Uses = Regs; 1855 let Defs = Regs; 1856} 1857 1858def ReadFRM : ReadSysReg<SysRegFRM, [FRM]>; 1859def WriteFRM : WriteSysReg<SysRegFRM, [FRM]>; 1860def WriteFRMImm : WriteSysRegImm<SysRegFRM, [FRM]>; 1861def SwapFRMImm : SwapSysRegImm<SysRegFRM, [FRM]>; 1862 1863def WriteVXRMImm : WriteSysRegImm<SysRegVXRM, [VXRM]>; 1864 1865let hasSideEffects = true in { 1866def ReadFFLAGS : ReadSysReg<SysRegFFLAGS, [FFLAGS]>; 1867def WriteFFLAGS : WriteSysReg<SysRegFFLAGS, [FFLAGS]>; 1868} 1869/// Other pseudo-instructions 1870 1871// Pessimistically assume the stack pointer will be clobbered 1872let Defs = [X2], Uses = [X2] in { 1873def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2), 1874 [(callseq_start timm:$amt1, timm:$amt2)]>; 1875def ADJCALLSTACKUP : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2), 1876 [(callseq_end timm:$amt1, timm:$amt2)]>; 1877} // Defs = [X2], Uses = [X2] 1878 1879/// RV64 patterns 1880 1881let Predicates = [IsRV64, NotHasStdExtZba] in { 1882def : Pat<(i64 (and GPR:$rs1, 0xffffffff)), (SRLI (SLLI GPR:$rs1, 32), 32)>; 1883 1884// If we're shifting a 32-bit zero extended value left by 0-31 bits, use 2 1885// shifts instead of 3. This can occur when unsigned is used to index an array. 1886def : Pat<(i64 (shl (and GPR:$rs1, 0xffffffff), uimm5:$shamt)), 1887 (SRLI (SLLI GPR:$rs1, 32), (ImmSubFrom32 uimm5:$shamt))>; 1888} 1889 1890class binop_allhusers<SDPatternOperator operator> 1891 : PatFrag<(ops node:$lhs, node:$rhs), 1892 (XLenVT (operator node:$lhs, node:$rhs)), [{ 1893 return hasAllHUsers(Node); 1894}]>; 1895 1896// PatFrag to allow ADDW/SUBW/MULW/SLLW to be selected from i64 add/sub/mul/shl 1897// if only the lower 32 bits of their result is used. 1898class binop_allwusers<SDPatternOperator operator> 1899 : PatFrag<(ops node:$lhs, node:$rhs), 1900 (i64 (operator node:$lhs, node:$rhs)), [{ 1901 return hasAllWUsers(Node); 1902}]>; 1903 1904def sexti32_allwusers : PatFrag<(ops node:$src), 1905 (sext_inreg node:$src, i32), [{ 1906 return hasAllWUsers(Node); 1907}]>; 1908 1909def ImmSExt32 : SDNodeXForm<imm, [{ 1910 return CurDAG->getTargetConstant(SignExtend64<32>(N->getSExtValue()), 1911 SDLoc(N), N->getValueType(0)); 1912}]>; 1913// Look for constants where the upper 32 bits are 0, but sign extending bit 31 1914// would be an simm12. 1915def u32simm12 : ImmLeaf<XLenVT, [{ 1916 return isUInt<32>(Imm) && isInt<12>(SignExtend64<32>(Imm)); 1917}], ImmSExt32>; 1918 1919let Predicates = [IsRV64] in { 1920 1921def : Pat<(i64 (and GPR:$rs, LeadingOnesWMask:$mask)), 1922 (SLLI (SRLIW $rs, LeadingOnesWMask:$mask), LeadingOnesWMask:$mask)>; 1923 1924/// sext and zext 1925 1926// Sign extend is not needed if all users are W instructions. 1927def : Pat<(sexti32_allwusers GPR:$rs1), (XLenVT GPR:$rs1)>; 1928 1929def : Pat<(sext_inreg GPR:$rs1, i32), (ADDIW GPR:$rs1, 0)>; 1930 1931/// ALU operations 1932 1933def : Pat<(i64 (srl (and GPR:$rs1, 0xffffffff), uimm5:$shamt)), 1934 (SRLIW GPR:$rs1, uimm5:$shamt)>; 1935def : Pat<(i64 (srl (shl GPR:$rs1, (i64 32)), uimm6gt32:$shamt)), 1936 (SRLIW GPR:$rs1, (ImmSub32 uimm6gt32:$shamt))>; 1937def : Pat<(sra (sext_inreg GPR:$rs1, i32), uimm5:$shamt), 1938 (SRAIW GPR:$rs1, uimm5:$shamt)>; 1939def : Pat<(i64 (sra (shl GPR:$rs1, (i64 32)), uimm6gt32:$shamt)), 1940 (SRAIW GPR:$rs1, (ImmSub32 uimm6gt32:$shamt))>; 1941 1942def : PatGprGpr<shiftopw<riscv_sllw>, SLLW>; 1943def : PatGprGpr<shiftopw<riscv_srlw>, SRLW>; 1944def : PatGprGpr<shiftopw<riscv_sraw>, SRAW>; 1945 1946// Select W instructions if only the lower 32 bits of the result are used. 1947def : PatGprGpr<binop_allwusers<add>, ADDW>; 1948def : PatGprSimm12<binop_allwusers<add>, ADDIW>; 1949def : PatGprGpr<binop_allwusers<sub>, SUBW>; 1950def : PatGprImm<binop_allwusers<shl>, SLLIW, uimm5>; 1951 1952// If this is a shr of a value sign extended from i32, and all the users only 1953// use the lower 32 bits, we can use an sraiw to remove the sext_inreg. This 1954// occurs because SimplifyDemandedBits prefers srl over sra. 1955def : Pat<(binop_allwusers<srl> (sext_inreg GPR:$rs1, i32), uimm5:$shamt), 1956 (SRAIW GPR:$rs1, uimm5:$shamt)>; 1957 1958// Use binop_allwusers to recover immediates that may have been broken by 1959// SimplifyDemandedBits. 1960def : Pat<(binop_allwusers<and> GPR:$rs1, u32simm12:$imm), 1961 (ANDI GPR:$rs1, u32simm12:$imm)>; 1962 1963def : Pat<(binop_allwusers<or> GPR:$rs1, u32simm12:$imm), 1964 (ORI GPR:$rs1, u32simm12:$imm)>; 1965 1966def : Pat<(binop_allwusers<xor> GPR:$rs1, u32simm12:$imm), 1967 (XORI GPR:$rs1, u32simm12:$imm)>; 1968/// Loads 1969 1970def : LdPat<sextloadi32, LW, i64>; 1971def : LdPat<extloadi32, LW, i64>; 1972def : LdPat<zextloadi32, LWU, i64>; 1973def : LdPat<load, LD, i64>; 1974 1975/// Stores 1976 1977def : StPat<truncstorei32, SW, GPR, i64>; 1978def : StPat<store, SD, GPR, i64>; 1979} // Predicates = [IsRV64] 1980 1981/// readcyclecounter 1982// On RV64, we can directly read the 64-bit "cycle" CSR. 1983let Predicates = [IsRV64] in 1984def : Pat<(i64 (readcyclecounter)), (CSRRS CYCLE.Encoding, (XLenVT X0))>; 1985// On RV32, ReadCycleWide will be expanded to the suggested loop reading both 1986// halves of the 64-bit "cycle" CSR. 1987let Predicates = [IsRV32], usesCustomInserter = 1, hasNoSchedulingInfo = 1 in 1988def ReadCycleWide : Pseudo<(outs GPR:$lo, GPR:$hi), (ins), 1989 [(set GPR:$lo, GPR:$hi, (riscv_read_cycle_wide))], 1990 "", "">; 1991 1992/// traps 1993 1994// We lower `trap` to `unimp`, as this causes a hard exception on nearly all 1995// systems. 1996def : Pat<(trap), (UNIMP)>; 1997 1998// We lower `debugtrap` to `ebreak`, as this will get the attention of the 1999// debugger if possible. 2000def : Pat<(debugtrap), (EBREAK)>; 2001 2002let Predicates = [IsRV64], Uses = [X5], 2003 Defs = [X1, X6, X7, X28, X29, X30, X31] in 2004def HWASAN_CHECK_MEMACCESS_SHORTGRANULES 2005 : Pseudo<(outs), (ins GPRJALR:$ptr, i32imm:$accessinfo), 2006 [(int_hwasan_check_memaccess_shortgranules (i64 X5), GPRJALR:$ptr, 2007 (i32 timm:$accessinfo))]>; 2008 2009// This gets lowered into a 20-byte instruction sequence (at most) 2010let hasSideEffects = 0, mayLoad = 1, mayStore = 0, 2011 Defs = [ X6, X7, X28, X29, X30, X31 ], Size = 20 in { 2012def KCFI_CHECK 2013 : Pseudo<(outs), (ins GPRJALR:$ptr, i32imm:$type), []>, Sched<[]>; 2014} 2015 2016/// Simple optimization 2017def : Pat<(XLenVT (add GPR:$rs1, (AddiPair:$rs2))), 2018 (ADDI (ADDI GPR:$rs1, (AddiPairImmLarge AddiPair:$rs2)), 2019 (AddiPairImmSmall GPR:$rs2))>; 2020 2021let Predicates = [IsRV64] in { 2022// Select W instructions if only the lower 32-bits of the result are used. 2023def : Pat<(binop_allwusers<add> GPR:$rs1, (AddiPair:$rs2)), 2024 (ADDIW (ADDIW GPR:$rs1, (AddiPairImmLarge AddiPair:$rs2)), 2025 (AddiPairImmSmall AddiPair:$rs2))>; 2026} 2027 2028let Predicates = [HasShortForwardBranchOpt] in 2029def : Pat<(XLenVT (abs GPR:$rs1)), 2030 (PseudoCCSUB (XLenVT GPR:$rs1), (XLenVT X0), /* COND_LT */ 2, 2031 (XLenVT GPR:$rs1), (XLenVT X0), (XLenVT GPR:$rs1))>; 2032let Predicates = [HasShortForwardBranchOpt, IsRV64] in 2033def : Pat<(sext_inreg (abs 33signbits_node:$rs1), i32), 2034 (PseudoCCSUBW (i64 GPR:$rs1), (i64 X0), /* COND_LT */ 2, 2035 (i64 GPR:$rs1), (i64 X0), (i64 GPR:$rs1))>; 2036 2037//===----------------------------------------------------------------------===// 2038// Experimental RV64 i32 legalization patterns. 2039//===----------------------------------------------------------------------===// 2040 2041def simm12i32 : ImmLeaf<i32, [{return isInt<12>(Imm);}]>; 2042 2043// Convert from i32 immediate to i64 target immediate to make SelectionDAG type 2044// checking happy so we can use ADDIW which expects an XLen immediate. 2045def as_i64imm : SDNodeXForm<imm, [{ 2046 return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i64); 2047}]>; 2048 2049def zext_is_sext : PatFrag<(ops node:$src), (zext node:$src), [{ 2050 KnownBits Known = CurDAG->computeKnownBits(N->getOperand(0), 0); 2051 return Known.isNonNegative(); 2052}]>; 2053 2054let Predicates = [IsRV64] in { 2055def : LdPat<sextloadi8, LB, i32>; 2056def : LdPat<extloadi8, LBU, i32>; // Prefer unsigned due to no c.lb in Zcb. 2057def : LdPat<sextloadi16, LH, i32>; 2058def : LdPat<extloadi16, LH, i32>; 2059def : LdPat<zextloadi8, LBU, i32>; 2060def : LdPat<zextloadi16, LHU, i32>; 2061 2062def : StPat<truncstorei8, SB, GPR, i32>; 2063def : StPat<truncstorei16, SH, GPR, i32>; 2064 2065def : Pat<(anyext GPR:$src), (COPY GPR:$src)>; 2066def : Pat<(sext GPR:$src), (ADDIW GPR:$src, 0)>; 2067def : Pat<(trunc GPR:$src), (COPY GPR:$src)>; 2068 2069def : PatGprGpr<add, ADDW, i32, i32>; 2070def : PatGprGpr<sub, SUBW, i32, i32>; 2071def : PatGprGpr<and, AND, i32, i32>; 2072def : PatGprGpr<or, OR, i32, i32>; 2073def : PatGprGpr<xor, XOR, i32, i32>; 2074def : PatGprGpr<shiftopw<shl>, SLLW, i32, i64>; 2075def : PatGprGpr<shiftopw<srl>, SRLW, i32, i64>; 2076def : PatGprGpr<shiftopw<sra>, SRAW, i32, i64>; 2077 2078def : Pat<(i32 (add GPR:$rs1, simm12i32:$imm)), 2079 (ADDIW GPR:$rs1, (i64 (as_i64imm $imm)))>; 2080def : Pat<(i32 (and GPR:$rs1, simm12i32:$imm)), 2081 (ANDI GPR:$rs1, (i64 (as_i64imm $imm)))>; 2082def : Pat<(i32 (or GPR:$rs1, simm12i32:$imm)), 2083 (ORI GPR:$rs1, (i64 (as_i64imm $imm)))>; 2084def : Pat<(i32 (xor GPR:$rs1, simm12i32:$imm)), 2085 (XORI GPR:$rs1, (i64 (as_i64imm $imm)))>; 2086 2087def : PatGprImm<shl, SLLIW, uimm5, i32>; 2088def : PatGprImm<srl, SRLIW, uimm5, i32>; 2089def : PatGprImm<sra, SRAIW, uimm5, i32>; 2090 2091def : Pat<(i32 (and GPR:$rs, TrailingOnesMask:$mask)), 2092 (SRLI (SLLI $rs, (i64 (XLenSubTrailingOnes $mask))), 2093 (i64 (XLenSubTrailingOnes $mask)))>; 2094 2095// Use sext if the sign bit of the input is 0. 2096def : Pat<(zext_is_sext GPR:$src), (ADDIW GPR:$src, 0)>; 2097} 2098 2099let Predicates = [IsRV64, NotHasStdExtZba] in { 2100def : Pat<(zext GPR:$src), (SRLI (SLLI GPR:$src, 32), 32)>; 2101 2102// If we're shifting a 32-bit zero extended value left by 0-31 bits, use 2 2103// shifts instead of 3. This can occur when unsigned is used to index an array. 2104def : Pat<(shl (zext GPR:$rs), uimm5:$shamt), 2105 (SRLI (SLLI GPR:$rs, 32), (ImmSubFrom32 uimm5:$shamt))>; 2106} 2107 2108//===----------------------------------------------------------------------===// 2109// Standard extensions 2110//===----------------------------------------------------------------------===// 2111 2112// Multiply and Division 2113include "RISCVInstrInfoM.td" 2114 2115// Atomic 2116include "RISCVInstrInfoA.td" 2117include "RISCVInstrInfoZa.td" 2118 2119// Scalar FP 2120include "RISCVInstrInfoF.td" 2121include "RISCVInstrInfoD.td" 2122include "RISCVInstrInfoZfh.td" 2123include "RISCVInstrInfoZfbfmin.td" 2124include "RISCVInstrInfoZfa.td" 2125 2126// Scalar bitmanip and cryptography 2127include "RISCVInstrInfoZb.td" 2128include "RISCVInstrInfoZk.td" 2129 2130// Vector 2131include "RISCVInstrInfoV.td" 2132include "RISCVInstrInfoZvk.td" 2133 2134// Compressed 2135include "RISCVInstrInfoC.td" 2136include "RISCVInstrInfoZc.td" 2137include "RISCVInstrInfoZcmop.td" 2138 2139// Integer 2140include "RISCVInstrInfoZimop.td" 2141include "RISCVInstrInfoZicbo.td" 2142include "RISCVInstrInfoZicond.td" 2143include "RISCVInstrInfoZicfiss.td" 2144 2145//===----------------------------------------------------------------------===// 2146// Vendor extensions 2147//===----------------------------------------------------------------------===// 2148 2149include "RISCVInstrInfoXVentana.td" 2150include "RISCVInstrInfoXTHead.td" 2151include "RISCVInstrInfoXSf.td" 2152include "RISCVInstrInfoXCV.td" 2153 2154//===----------------------------------------------------------------------===// 2155// Global ISel 2156//===----------------------------------------------------------------------===// 2157 2158include "RISCVInstrGISel.td" 2159