1//===-- RISCVInstrInfo.td - Target Description for RISCV ---*- 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 SDTCisSameAs<0, 4>, 27 SDTCisSameAs<4, 5>]>; 28def SDT_RISCVBrCC : SDTypeProfile<0, 4, [SDTCisSameAs<0, 1>, 29 SDTCisVT<2, OtherVT>, 30 SDTCisVT<3, OtherVT>]>; 31def SDT_RISCVReadCSR : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisInt<1>]>; 32def SDT_RISCVWriteCSR : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisInt<1>]>; 33def SDT_RISCVSwapCSR : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisInt<1>, 34 SDTCisInt<2>]>; 35def SDT_RISCVReadCycleWide : SDTypeProfile<2, 0, [SDTCisVT<0, i32>, 36 SDTCisVT<1, i32>]>; 37def SDT_RISCVIntUnaryOpW : SDTypeProfile<1, 1, [ 38 SDTCisSameAs<0, 1>, SDTCisVT<0, i64> 39]>; 40def SDT_RISCVIntBinOpW : SDTypeProfile<1, 2, [ 41 SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisVT<0, i64> 42]>; 43def SDT_RISCVIntShiftDOpW : SDTypeProfile<1, 3, [ 44 SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisVT<0, i64>, SDTCisVT<3, i64> 45]>; 46 47// Target-independent nodes, but with target-specific formats. 48def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_CallSeqStart, 49 [SDNPHasChain, SDNPOutGlue]>; 50def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_CallSeqEnd, 51 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 52 53// Target-dependent nodes. 54def riscv_call : SDNode<"RISCVISD::CALL", SDT_RISCVCall, 55 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 56 SDNPVariadic]>; 57def riscv_ret_flag : SDNode<"RISCVISD::RET_FLAG", SDTNone, 58 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 59def riscv_uret_flag : SDNode<"RISCVISD::URET_FLAG", SDTNone, 60 [SDNPHasChain, SDNPOptInGlue]>; 61def riscv_sret_flag : SDNode<"RISCVISD::SRET_FLAG", SDTNone, 62 [SDNPHasChain, SDNPOptInGlue]>; 63def riscv_mret_flag : SDNode<"RISCVISD::MRET_FLAG", SDTNone, 64 [SDNPHasChain, SDNPOptInGlue]>; 65def riscv_selectcc : SDNode<"RISCVISD::SELECT_CC", SDT_RISCVSelectCC>; 66def riscv_brcc : SDNode<"RISCVISD::BR_CC", SDT_RISCVBrCC, 67 [SDNPHasChain]>; 68def riscv_tail : SDNode<"RISCVISD::TAIL", SDT_RISCVCall, 69 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 70 SDNPVariadic]>; 71def riscv_sllw : SDNode<"RISCVISD::SLLW", SDT_RISCVIntBinOpW>; 72def riscv_sraw : SDNode<"RISCVISD::SRAW", SDT_RISCVIntBinOpW>; 73def riscv_srlw : SDNode<"RISCVISD::SRLW", SDT_RISCVIntBinOpW>; 74def riscv_read_csr : SDNode<"RISCVISD::READ_CSR", SDT_RISCVReadCSR, 75 [SDNPHasChain]>; 76def riscv_write_csr : SDNode<"RISCVISD::WRITE_CSR", SDT_RISCVWriteCSR, 77 [SDNPHasChain]>; 78def riscv_swap_csr : SDNode<"RISCVISD::SWAP_CSR", SDT_RISCVSwapCSR, 79 [SDNPHasChain]>; 80 81def riscv_read_cycle_wide : SDNode<"RISCVISD::READ_CYCLE_WIDE", 82 SDT_RISCVReadCycleWide, 83 [SDNPHasChain, SDNPSideEffect]>; 84 85//===----------------------------------------------------------------------===// 86// Operand and SDNode transformation definitions. 87//===----------------------------------------------------------------------===// 88 89class ImmXLenAsmOperand<string prefix, string suffix = ""> : AsmOperandClass { 90 let Name = prefix # "ImmXLen" # suffix; 91 let RenderMethod = "addImmOperands"; 92 let DiagnosticType = !strconcat("Invalid", Name); 93} 94 95class ImmAsmOperand<string prefix, int width, string suffix> : AsmOperandClass { 96 let Name = prefix # "Imm" # width # suffix; 97 let RenderMethod = "addImmOperands"; 98 let DiagnosticType = !strconcat("Invalid", Name); 99} 100 101def ImmZeroAsmOperand : AsmOperandClass { 102 let Name = "ImmZero"; 103 let RenderMethod = "addImmOperands"; 104 let DiagnosticType = !strconcat("Invalid", Name); 105} 106 107class SImmAsmOperand<int width, string suffix = ""> 108 : ImmAsmOperand<"S", width, suffix> { 109} 110 111class UImmAsmOperand<int width, string suffix = ""> 112 : ImmAsmOperand<"U", width, suffix> { 113} 114 115def FenceArg : AsmOperandClass { 116 let Name = "FenceArg"; 117 let RenderMethod = "addFenceArgOperands"; 118 let DiagnosticType = "InvalidFenceArg"; 119} 120 121def fencearg : Operand<XLenVT> { 122 let ParserMatchClass = FenceArg; 123 let PrintMethod = "printFenceArg"; 124 let DecoderMethod = "decodeUImmOperand<4>"; 125 let OperandType = "OPERAND_UIMM4"; 126 let OperandNamespace = "RISCVOp"; 127} 128 129def UImmLog2XLenAsmOperand : AsmOperandClass { 130 let Name = "UImmLog2XLen"; 131 let RenderMethod = "addImmOperands"; 132 let DiagnosticType = "InvalidUImmLog2XLen"; 133} 134 135def uimmlog2xlen : Operand<XLenVT>, ImmLeaf<XLenVT, [{ 136 if (Subtarget->is64Bit()) 137 return isUInt<6>(Imm); 138 return isUInt<5>(Imm); 139}]> { 140 let ParserMatchClass = UImmLog2XLenAsmOperand; 141 // TODO: should ensure invalid shamt is rejected when decoding. 142 let DecoderMethod = "decodeUImmOperand<6>"; 143 let MCOperandPredicate = [{ 144 int64_t Imm; 145 if (!MCOp.evaluateAsConstantImm(Imm)) 146 return false; 147 if (STI.getTargetTriple().isArch64Bit()) 148 return isUInt<6>(Imm); 149 return isUInt<5>(Imm); 150 }]; 151 let OperandType = "OPERAND_UIMMLOG2XLEN"; 152 let OperandNamespace = "RISCVOp"; 153} 154 155def uimm5 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isUInt<5>(Imm);}]> { 156 let ParserMatchClass = UImmAsmOperand<5>; 157 let DecoderMethod = "decodeUImmOperand<5>"; 158 let OperandType = "OPERAND_UIMM5"; 159 let OperandNamespace = "RISCVOp"; 160} 161 162def simm12 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isInt<12>(Imm);}]> { 163 let ParserMatchClass = SImmAsmOperand<12>; 164 let EncoderMethod = "getImmOpValue"; 165 let DecoderMethod = "decodeSImmOperand<12>"; 166 let MCOperandPredicate = [{ 167 int64_t Imm; 168 if (MCOp.evaluateAsConstantImm(Imm)) 169 return isInt<12>(Imm); 170 return MCOp.isBareSymbolRef(); 171 }]; 172 let OperandType = "OPERAND_SIMM12"; 173 let OperandNamespace = "RISCVOp"; 174} 175 176// A 13-bit signed immediate where the least significant bit is zero. 177def simm13_lsb0 : Operand<OtherVT> { 178 let ParserMatchClass = SImmAsmOperand<13, "Lsb0">; 179 let PrintMethod = "printBranchOperand"; 180 let EncoderMethod = "getImmOpValueAsr1"; 181 let DecoderMethod = "decodeSImmOperandAndLsl1<13>"; 182 let MCOperandPredicate = [{ 183 int64_t Imm; 184 if (MCOp.evaluateAsConstantImm(Imm)) 185 return isShiftedInt<12, 1>(Imm); 186 return MCOp.isBareSymbolRef(); 187 }]; 188 let OperandType = "OPERAND_PCREL"; 189} 190 191class UImm20Operand : Operand<XLenVT> { 192 let EncoderMethod = "getImmOpValue"; 193 let DecoderMethod = "decodeUImmOperand<20>"; 194 let MCOperandPredicate = [{ 195 int64_t Imm; 196 if (MCOp.evaluateAsConstantImm(Imm)) 197 return isUInt<20>(Imm); 198 return MCOp.isBareSymbolRef(); 199 }]; 200 let OperandType = "OPERAND_UIMM20"; 201 let OperandNamespace = "RISCVOp"; 202} 203 204def uimm20_lui : UImm20Operand { 205 let ParserMatchClass = UImmAsmOperand<20, "LUI">; 206} 207def uimm20_auipc : UImm20Operand { 208 let ParserMatchClass = UImmAsmOperand<20, "AUIPC">; 209} 210 211def Simm21Lsb0JALAsmOperand : SImmAsmOperand<21, "Lsb0JAL"> { 212 let ParserMethod = "parseJALOffset"; 213} 214 215// A 21-bit signed immediate where the least significant bit is zero. 216def simm21_lsb0_jal : Operand<OtherVT> { 217 let ParserMatchClass = Simm21Lsb0JALAsmOperand; 218 let PrintMethod = "printBranchOperand"; 219 let EncoderMethod = "getImmOpValueAsr1"; 220 let DecoderMethod = "decodeSImmOperandAndLsl1<21>"; 221 let MCOperandPredicate = [{ 222 int64_t Imm; 223 if (MCOp.evaluateAsConstantImm(Imm)) 224 return isShiftedInt<20, 1>(Imm); 225 return MCOp.isBareSymbolRef(); 226 }]; 227 let OperandType = "OPERAND_PCREL"; 228} 229 230def BareSymbol : AsmOperandClass { 231 let Name = "BareSymbol"; 232 let RenderMethod = "addImmOperands"; 233 let DiagnosticType = "InvalidBareSymbol"; 234 let ParserMethod = "parseBareSymbol"; 235} 236 237// A bare symbol. 238def bare_symbol : Operand<XLenVT> { 239 let ParserMatchClass = BareSymbol; 240} 241 242def CallSymbol : AsmOperandClass { 243 let Name = "CallSymbol"; 244 let RenderMethod = "addImmOperands"; 245 let DiagnosticType = "InvalidCallSymbol"; 246 let ParserMethod = "parseCallSymbol"; 247} 248 249// A bare symbol used in call/tail only. 250def call_symbol : Operand<XLenVT> { 251 let ParserMatchClass = CallSymbol; 252} 253 254def PseudoJumpSymbol : AsmOperandClass { 255 let Name = "PseudoJumpSymbol"; 256 let RenderMethod = "addImmOperands"; 257 let DiagnosticType = "InvalidPseudoJumpSymbol"; 258 let ParserMethod = "parsePseudoJumpSymbol"; 259} 260 261// A bare symbol used for pseudo jumps only. 262def pseudo_jump_symbol : Operand<XLenVT> { 263 let ParserMatchClass = PseudoJumpSymbol; 264} 265 266def TPRelAddSymbol : AsmOperandClass { 267 let Name = "TPRelAddSymbol"; 268 let RenderMethod = "addImmOperands"; 269 let DiagnosticType = "InvalidTPRelAddSymbol"; 270 let ParserMethod = "parseOperandWithModifier"; 271} 272 273// A bare symbol with the %tprel_add variant. 274def tprel_add_symbol : Operand<XLenVT> { 275 let ParserMatchClass = TPRelAddSymbol; 276} 277 278def CSRSystemRegister : AsmOperandClass { 279 let Name = "CSRSystemRegister"; 280 let ParserMethod = "parseCSRSystemRegister"; 281 let DiagnosticType = "InvalidCSRSystemRegister"; 282} 283 284def csr_sysreg : Operand<XLenVT> { 285 let ParserMatchClass = CSRSystemRegister; 286 let PrintMethod = "printCSRSystemRegister"; 287 let DecoderMethod = "decodeUImmOperand<12>"; 288 let OperandType = "OPERAND_UIMM12"; 289 let OperandNamespace = "RISCVOp"; 290} 291 292// A parameterized register class alternative to i32imm/i64imm from Target.td. 293def ixlenimm : Operand<XLenVT>; 294 295def ixlenimm_li : Operand<XLenVT> { 296 let ParserMatchClass = ImmXLenAsmOperand<"", "LI">; 297} 298 299// Standalone (codegen-only) immleaf patterns. 300 301// A 12-bit signed immediate plus one where the imm range will be -2047~2048. 302def simm12_plus1 : ImmLeaf<XLenVT, 303 [{return (isInt<12>(Imm) && Imm != -2048) || Imm == 2048;}]>; 304 305// A 6-bit constant greater than 32. 306def uimm6gt32 : ImmLeaf<XLenVT, [{ 307 return isUInt<6>(Imm) && Imm > 32; 308}]>; 309 310// Addressing modes. 311// Necessary because a frameindex can't be matched directly in a pattern. 312def AddrFI : ComplexPattern<iPTR, 1, "SelectAddrFI", [frameindex], []>; 313def BaseAddr : ComplexPattern<iPTR, 1, "SelectBaseAddr">; 314 315// Return the negation of an immediate value. 316def NegImm : SDNodeXForm<imm, [{ 317 return CurDAG->getTargetConstant(-N->getSExtValue(), SDLoc(N), 318 N->getValueType(0)); 319}]>; 320 321// Return an immediate value minus 32. 322def ImmSub32 : SDNodeXForm<imm, [{ 323 return CurDAG->getTargetConstant(N->getSExtValue() - 32, SDLoc(N), 324 N->getValueType(0)); 325}]>; 326 327// Return an immediate value plus 32. 328def ImmPlus32 : SDNodeXForm<imm, [{ 329 return CurDAG->getTargetConstant(N->getSExtValue() + 32, SDLoc(N), 330 N->getValueType(0)); 331}]>; 332 333// Return an immediate subtracted from XLen. 334def ImmSubFromXLen : SDNodeXForm<imm, [{ 335 uint64_t XLen = Subtarget->getXLen(); 336 return CurDAG->getTargetConstant(XLen - N->getZExtValue(), SDLoc(N), 337 N->getValueType(0)); 338}]>; 339 340// Return an immediate subtracted from 32. 341def ImmSubFrom32 : SDNodeXForm<imm, [{ 342 return CurDAG->getTargetConstant(32 - N->getZExtValue(), SDLoc(N), 343 N->getValueType(0)); 344}]>; 345 346// Check if (add r, imm) can be optimized to (ADDI (ADDI r, imm0), imm1), 347// in which imm = imm0 + imm1 and both imm0 and imm1 are simm12. 348def AddiPair : PatLeaf<(imm), [{ 349 if (!N->hasOneUse()) 350 return false; 351 // The immediate operand must be in range [-4096,-2049] or [2048,4094]. 352 int64_t Imm = N->getSExtValue(); 353 return (-4096 <= Imm && Imm <= -2049) || (2048 <= Imm && Imm <= 4094); 354}]>; 355 356// Return imm/2. 357def AddiPairImmA : SDNodeXForm<imm, [{ 358 return CurDAG->getTargetConstant(N->getSExtValue() / 2, SDLoc(N), 359 N->getValueType(0)); 360}]>; 361 362// Return imm - imm/2. 363def AddiPairImmB : SDNodeXForm<imm, [{ 364 int64_t Imm = N->getSExtValue(); 365 return CurDAG->getTargetConstant(Imm - Imm / 2, SDLoc(N), 366 N->getValueType(0)); 367}]>; 368 369//===----------------------------------------------------------------------===// 370// Instruction Formats 371//===----------------------------------------------------------------------===// 372 373include "RISCVInstrFormats.td" 374 375//===----------------------------------------------------------------------===// 376// Instruction Class Templates 377//===----------------------------------------------------------------------===// 378 379let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 380class BranchCC_rri<bits<3> funct3, string opcodestr> 381 : RVInstB<funct3, OPC_BRANCH, (outs), 382 (ins GPR:$rs1, GPR:$rs2, simm13_lsb0:$imm12), 383 opcodestr, "$rs1, $rs2, $imm12">, 384 Sched<[WriteJmp, ReadJmp, ReadJmp]> { 385 let isBranch = 1; 386 let isTerminator = 1; 387} 388 389let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in 390class Load_ri<bits<3> funct3, string opcodestr> 391 : RVInstI<funct3, OPC_LOAD, (outs GPR:$rd), (ins GPR:$rs1, simm12:$imm12), 392 opcodestr, "$rd, ${imm12}(${rs1})">; 393 394// Operands for stores are in the order srcreg, base, offset rather than 395// reflecting the order these fields are specified in the instruction 396// encoding. 397let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 398class Store_rri<bits<3> funct3, string opcodestr> 399 : RVInstS<funct3, OPC_STORE, (outs), 400 (ins GPR:$rs2, GPR:$rs1, simm12:$imm12), 401 opcodestr, "$rs2, ${imm12}(${rs1})">; 402 403let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 404class ALU_ri<bits<3> funct3, string opcodestr> 405 : RVInstI<funct3, OPC_OP_IMM, (outs GPR:$rd), (ins GPR:$rs1, simm12:$imm12), 406 opcodestr, "$rd, $rs1, $imm12">, 407 Sched<[WriteIALU, ReadIALU]>; 408 409let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 410class Shift_ri<bits<5> imm11_7, bits<3> funct3, string opcodestr> 411 : RVInstIShift<imm11_7, funct3, OPC_OP_IMM, (outs GPR:$rd), 412 (ins GPR:$rs1, uimmlog2xlen:$shamt), opcodestr, 413 "$rd, $rs1, $shamt">, 414 Sched<[WriteShiftImm, ReadShiftImm]>; 415 416let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 417class ALU_rr<bits<7> funct7, bits<3> funct3, string opcodestr> 418 : RVInstR<funct7, funct3, OPC_OP, (outs GPR:$rd), (ins GPR:$rs1, GPR:$rs2), 419 opcodestr, "$rd, $rs1, $rs2">; 420 421let hasNoSchedulingInfo = 1, 422 hasSideEffects = 1, mayLoad = 0, mayStore = 0 in 423class CSR_ir<bits<3> funct3, string opcodestr> 424 : RVInstI<funct3, OPC_SYSTEM, (outs GPR:$rd), (ins csr_sysreg:$imm12, GPR:$rs1), 425 opcodestr, "$rd, $imm12, $rs1">, Sched<[WriteCSR, ReadCSR]>; 426 427let hasNoSchedulingInfo = 1, 428 hasSideEffects = 1, mayLoad = 0, mayStore = 0 in 429class CSR_ii<bits<3> funct3, string opcodestr> 430 : RVInstI<funct3, OPC_SYSTEM, (outs GPR:$rd), 431 (ins csr_sysreg:$imm12, uimm5:$rs1), 432 opcodestr, "$rd, $imm12, $rs1">, Sched<[WriteCSR]>; 433 434let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 435class ShiftW_ri<bits<7> imm11_5, bits<3> funct3, string opcodestr> 436 : RVInstIShiftW<imm11_5, funct3, OPC_OP_IMM_32, (outs GPR:$rd), 437 (ins GPR:$rs1, uimm5:$shamt), opcodestr, 438 "$rd, $rs1, $shamt">, 439 Sched<[WriteShiftImm32, ReadShiftImm32]>; 440 441let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 442class ALUW_rr<bits<7> funct7, bits<3> funct3, string opcodestr> 443 : RVInstR<funct7, funct3, OPC_OP_32, (outs GPR:$rd), 444 (ins GPR:$rs1, GPR:$rs2), opcodestr, "$rd, $rs1, $rs2">; 445 446let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in 447class Priv<string opcodestr, bits<7> funct7> 448 : RVInstR<funct7, 0b000, OPC_SYSTEM, (outs), (ins GPR:$rs1, GPR:$rs2), 449 opcodestr, "">; 450 451//===----------------------------------------------------------------------===// 452// Instructions 453//===----------------------------------------------------------------------===// 454 455let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { 456let isReMaterializable = 1, isAsCheapAsAMove = 1 in 457def LUI : RVInstU<OPC_LUI, (outs GPR:$rd), (ins uimm20_lui:$imm20), 458 "lui", "$rd, $imm20">, Sched<[WriteIALU]>; 459 460def AUIPC : RVInstU<OPC_AUIPC, (outs GPR:$rd), (ins uimm20_auipc:$imm20), 461 "auipc", "$rd, $imm20">, Sched<[WriteIALU]>; 462 463let isCall = 1 in 464def JAL : RVInstJ<OPC_JAL, (outs GPR:$rd), (ins simm21_lsb0_jal:$imm20), 465 "jal", "$rd, $imm20">, Sched<[WriteJal]>; 466 467let isCall = 1 in 468def JALR : RVInstI<0b000, OPC_JALR, (outs GPR:$rd), 469 (ins GPR:$rs1, simm12:$imm12), 470 "jalr", "$rd, ${imm12}(${rs1})">, 471 Sched<[WriteJalr, ReadJalr]>; 472} // hasSideEffects = 0, mayLoad = 0, mayStore = 0 473 474def BEQ : BranchCC_rri<0b000, "beq">; 475def BNE : BranchCC_rri<0b001, "bne">; 476def BLT : BranchCC_rri<0b100, "blt">; 477def BGE : BranchCC_rri<0b101, "bge">; 478def BLTU : BranchCC_rri<0b110, "bltu">; 479def BGEU : BranchCC_rri<0b111, "bgeu">; 480 481def LB : Load_ri<0b000, "lb">, Sched<[WriteLDB, ReadMemBase]>; 482def LH : Load_ri<0b001, "lh">, Sched<[WriteLDH, ReadMemBase]>; 483def LW : Load_ri<0b010, "lw">, Sched<[WriteLDW, ReadMemBase]>; 484def LBU : Load_ri<0b100, "lbu">, Sched<[WriteLDB, ReadMemBase]>; 485def LHU : Load_ri<0b101, "lhu">, Sched<[WriteLDH, ReadMemBase]>; 486 487def SB : Store_rri<0b000, "sb">, Sched<[WriteSTB, ReadStoreData, ReadMemBase]>; 488def SH : Store_rri<0b001, "sh">, Sched<[WriteSTH, ReadStoreData, ReadMemBase]>; 489def SW : Store_rri<0b010, "sw">, Sched<[WriteSTW, ReadStoreData, ReadMemBase]>; 490 491// ADDI isn't always rematerializable, but isReMaterializable will be used as 492// a hint which is verified in isReallyTriviallyReMaterializable. 493let isReMaterializable = 1, isAsCheapAsAMove = 1 in 494def ADDI : ALU_ri<0b000, "addi">; 495 496def SLTI : ALU_ri<0b010, "slti">; 497def SLTIU : ALU_ri<0b011, "sltiu">; 498 499let isReMaterializable = 1, isAsCheapAsAMove = 1 in { 500def XORI : ALU_ri<0b100, "xori">; 501def ORI : ALU_ri<0b110, "ori">; 502} 503 504def ANDI : ALU_ri<0b111, "andi">; 505 506def SLLI : Shift_ri<0b00000, 0b001, "slli">; 507def SRLI : Shift_ri<0b00000, 0b101, "srli">; 508def SRAI : Shift_ri<0b01000, 0b101, "srai">; 509 510def ADD : ALU_rr<0b0000000, 0b000, "add">, Sched<[WriteIALU, ReadIALU, ReadIALU]>; 511def SUB : ALU_rr<0b0100000, 0b000, "sub">, Sched<[WriteIALU, ReadIALU, ReadIALU]>; 512def SLL : ALU_rr<0b0000000, 0b001, "sll">, Sched<[WriteShiftReg, ReadShiftReg, ReadShiftReg]>; 513def SLT : ALU_rr<0b0000000, 0b010, "slt">, Sched<[WriteIALU, ReadIALU, ReadIALU]>; 514def SLTU : ALU_rr<0b0000000, 0b011, "sltu">, Sched<[WriteIALU, ReadIALU, ReadIALU]>; 515def XOR : ALU_rr<0b0000000, 0b100, "xor">, Sched<[WriteIALU, ReadIALU, ReadIALU]>; 516def SRL : ALU_rr<0b0000000, 0b101, "srl">, Sched<[WriteShiftReg, ReadShiftReg, ReadShiftReg]>; 517def SRA : ALU_rr<0b0100000, 0b101, "sra">, Sched<[WriteShiftReg, ReadShiftReg, ReadShiftReg]>; 518def OR : ALU_rr<0b0000000, 0b110, "or">, Sched<[WriteIALU, ReadIALU, ReadIALU]>; 519def AND : ALU_rr<0b0000000, 0b111, "and">, Sched<[WriteIALU, ReadIALU, ReadIALU]>; 520 521let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in { 522def FENCE : RVInstI<0b000, OPC_MISC_MEM, (outs), 523 (ins fencearg:$pred, fencearg:$succ), 524 "fence", "$pred, $succ">, Sched<[]> { 525 bits<4> pred; 526 bits<4> succ; 527 528 let rs1 = 0; 529 let rd = 0; 530 let imm12 = {0b0000,pred,succ}; 531} 532 533def FENCE_TSO : RVInstI<0b000, OPC_MISC_MEM, (outs), (ins), "fence.tso", "">, Sched<[]> { 534 let rs1 = 0; 535 let rd = 0; 536 let imm12 = {0b1000,0b0011,0b0011}; 537} 538 539def FENCE_I : RVInstI<0b001, OPC_MISC_MEM, (outs), (ins), "fence.i", "">, Sched<[]> { 540 let rs1 = 0; 541 let rd = 0; 542 let imm12 = 0; 543} 544 545def ECALL : RVInstI<0b000, OPC_SYSTEM, (outs), (ins), "ecall", "">, Sched<[WriteJmp]> { 546 let rs1 = 0; 547 let rd = 0; 548 let imm12 = 0; 549} 550 551def EBREAK : RVInstI<0b000, OPC_SYSTEM, (outs), (ins), "ebreak", "">, 552 Sched<[]> { 553 let rs1 = 0; 554 let rd = 0; 555 let imm12 = 1; 556} 557 558// This is a de facto standard (as set by GNU binutils) 32-bit unimplemented 559// instruction (i.e., it should always trap, if your implementation has invalid 560// instruction traps). 561def UNIMP : RVInstI<0b001, OPC_SYSTEM, (outs), (ins), "unimp", "">, 562 Sched<[]> { 563 let rs1 = 0; 564 let rd = 0; 565 let imm12 = 0b110000000000; 566} 567} // hasSideEffects = 1, mayLoad = 0, mayStore = 0 568 569def CSRRW : CSR_ir<0b001, "csrrw">; 570def CSRRS : CSR_ir<0b010, "csrrs">; 571def CSRRC : CSR_ir<0b011, "csrrc">; 572 573def CSRRWI : CSR_ii<0b101, "csrrwi">; 574def CSRRSI : CSR_ii<0b110, "csrrsi">; 575def CSRRCI : CSR_ii<0b111, "csrrci">; 576 577/// RV64I instructions 578 579let Predicates = [IsRV64] in { 580def LWU : Load_ri<0b110, "lwu">, Sched<[WriteLDWU, ReadMemBase]>; 581def LD : Load_ri<0b011, "ld">, Sched<[WriteLDD, ReadMemBase]>; 582def SD : Store_rri<0b011, "sd">, Sched<[WriteSTD, ReadStoreData, ReadMemBase]>; 583 584let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 585def ADDIW : RVInstI<0b000, OPC_OP_IMM_32, (outs GPR:$rd), 586 (ins GPR:$rs1, simm12:$imm12), 587 "addiw", "$rd, $rs1, $imm12">, 588 Sched<[WriteIALU32, ReadIALU32]>; 589 590def SLLIW : ShiftW_ri<0b0000000, 0b001, "slliw">; 591def SRLIW : ShiftW_ri<0b0000000, 0b101, "srliw">; 592def SRAIW : ShiftW_ri<0b0100000, 0b101, "sraiw">; 593 594def ADDW : ALUW_rr<0b0000000, 0b000, "addw">, 595 Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>; 596def SUBW : ALUW_rr<0b0100000, 0b000, "subw">, 597 Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>; 598def SLLW : ALUW_rr<0b0000000, 0b001, "sllw">, 599 Sched<[WriteShiftReg32, ReadShiftReg32, ReadShiftReg32]>; 600def SRLW : ALUW_rr<0b0000000, 0b101, "srlw">, 601 Sched<[WriteShiftReg32, ReadShiftReg32, ReadShiftReg32]>; 602def SRAW : ALUW_rr<0b0100000, 0b101, "sraw">, 603 Sched<[WriteShiftReg32, ReadShiftReg32, ReadShiftReg32]>; 604} // Predicates = [IsRV64] 605 606//===----------------------------------------------------------------------===// 607// Privileged instructions 608//===----------------------------------------------------------------------===// 609 610let isBarrier = 1, isReturn = 1, isTerminator = 1 in { 611def URET : Priv<"uret", 0b0000000>, Sched<[]> { 612 let rd = 0; 613 let rs1 = 0; 614 let rs2 = 0b00010; 615} 616 617def SRET : Priv<"sret", 0b0001000>, Sched<[]> { 618 let rd = 0; 619 let rs1 = 0; 620 let rs2 = 0b00010; 621} 622 623def MRET : Priv<"mret", 0b0011000>, Sched<[]> { 624 let rd = 0; 625 let rs1 = 0; 626 let rs2 = 0b00010; 627} 628} // isBarrier = 1, isReturn = 1, isTerminator = 1 629 630def WFI : Priv<"wfi", 0b0001000>, Sched<[]> { 631 let rd = 0; 632 let rs1 = 0; 633 let rs2 = 0b00101; 634} 635 636let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in 637def SFENCE_VMA : RVInstR<0b0001001, 0b000, OPC_SYSTEM, (outs), 638 (ins GPR:$rs1, GPR:$rs2), 639 "sfence.vma", "$rs1, $rs2">, Sched<[]> { 640 let rd = 0; 641} 642 643//===----------------------------------------------------------------------===// 644// Debug instructions 645//===----------------------------------------------------------------------===// 646 647let isBarrier = 1, isReturn = 1, isTerminator = 1 in { 648def DRET : Priv<"dret", 0b0111101>, Sched<[]> { 649 let rd = 0; 650 let rs1 = 0; 651 let rs2 = 0b10010; 652} 653} // isBarrier = 1, isReturn = 1, isTerminator = 1 654 655//===----------------------------------------------------------------------===// 656// Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20) 657//===----------------------------------------------------------------------===// 658 659def : InstAlias<"nop", (ADDI X0, X0, 0)>; 660 661// Note that the size is 32 because up to 8 32-bit instructions are needed to 662// generate an arbitrary 64-bit immediate. However, the size does not really 663// matter since PseudoLI is currently only used in the AsmParser where it gets 664// expanded to real instructions immediately. 665let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 32, 666 isCodeGenOnly = 0, isAsmParserOnly = 1 in 667def PseudoLI : Pseudo<(outs GPR:$rd), (ins ixlenimm_li:$imm), [], 668 "li", "$rd, $imm">; 669 670def PseudoLB : PseudoLoad<"lb">; 671def PseudoLBU : PseudoLoad<"lbu">; 672def PseudoLH : PseudoLoad<"lh">; 673def PseudoLHU : PseudoLoad<"lhu">; 674def PseudoLW : PseudoLoad<"lw">; 675 676def PseudoSB : PseudoStore<"sb">; 677def PseudoSH : PseudoStore<"sh">; 678def PseudoSW : PseudoStore<"sw">; 679 680let Predicates = [IsRV64] in { 681def PseudoLWU : PseudoLoad<"lwu">; 682def PseudoLD : PseudoLoad<"ld">; 683def PseudoSD : PseudoStore<"sd">; 684} // Predicates = [IsRV64] 685 686def : InstAlias<"mv $rd, $rs", (ADDI GPR:$rd, GPR:$rs, 0)>; 687def : InstAlias<"not $rd, $rs", (XORI GPR:$rd, GPR:$rs, -1)>; 688def : InstAlias<"neg $rd, $rs", (SUB GPR:$rd, X0, GPR:$rs)>; 689 690let Predicates = [IsRV64] in { 691def : InstAlias<"negw $rd, $rs", (SUBW GPR:$rd, X0, GPR:$rs)>; 692def : InstAlias<"sext.w $rd, $rs", (ADDIW GPR:$rd, GPR:$rs, 0)>; 693} // Predicates = [IsRV64] 694 695def : InstAlias<"seqz $rd, $rs", (SLTIU GPR:$rd, GPR:$rs, 1)>; 696def : InstAlias<"snez $rd, $rs", (SLTU GPR:$rd, X0, GPR:$rs)>; 697def : InstAlias<"sltz $rd, $rs", (SLT GPR:$rd, GPR:$rs, X0)>; 698def : InstAlias<"sgtz $rd, $rs", (SLT GPR:$rd, X0, GPR:$rs)>; 699 700// sgt/sgtu are recognised by the GNU assembler but the canonical slt/sltu 701// form will always be printed. Therefore, set a zero weight. 702def : InstAlias<"sgt $rd, $rs, $rt", (SLT GPR:$rd, GPR:$rt, GPR:$rs), 0>; 703def : InstAlias<"sgtu $rd, $rs, $rt", (SLTU GPR:$rd, GPR:$rt, GPR:$rs), 0>; 704 705def : InstAlias<"beqz $rs, $offset", 706 (BEQ GPR:$rs, X0, simm13_lsb0:$offset)>; 707def : InstAlias<"bnez $rs, $offset", 708 (BNE GPR:$rs, X0, simm13_lsb0:$offset)>; 709def : InstAlias<"blez $rs, $offset", 710 (BGE X0, GPR:$rs, simm13_lsb0:$offset)>; 711def : InstAlias<"bgez $rs, $offset", 712 (BGE GPR:$rs, X0, simm13_lsb0:$offset)>; 713def : InstAlias<"bltz $rs, $offset", 714 (BLT GPR:$rs, X0, simm13_lsb0:$offset)>; 715def : InstAlias<"bgtz $rs, $offset", 716 (BLT X0, GPR:$rs, simm13_lsb0:$offset)>; 717 718// Always output the canonical mnemonic for the pseudo branch instructions. 719// The GNU tools emit the canonical mnemonic for the branch pseudo instructions 720// as well (e.g. "bgt" will be recognised by the assembler but never printed by 721// objdump). Match this behaviour by setting a zero weight. 722def : InstAlias<"bgt $rs, $rt, $offset", 723 (BLT GPR:$rt, GPR:$rs, simm13_lsb0:$offset), 0>; 724def : InstAlias<"ble $rs, $rt, $offset", 725 (BGE GPR:$rt, GPR:$rs, simm13_lsb0:$offset), 0>; 726def : InstAlias<"bgtu $rs, $rt, $offset", 727 (BLTU GPR:$rt, GPR:$rs, simm13_lsb0:$offset), 0>; 728def : InstAlias<"bleu $rs, $rt, $offset", 729 (BGEU GPR:$rt, GPR:$rs, simm13_lsb0:$offset), 0>; 730 731def : InstAlias<"j $offset", (JAL X0, simm21_lsb0_jal:$offset)>; 732def : InstAlias<"jal $offset", (JAL X1, simm21_lsb0_jal:$offset)>; 733 734// Non-zero offset aliases of "jalr" are the lowest weight, followed by the 735// two-register form, then the one-register forms and finally "ret". 736def : InstAlias<"jr $rs", (JALR X0, GPR:$rs, 0), 3>; 737def : InstAlias<"jr ${offset}(${rs})", (JALR X0, GPR:$rs, simm12:$offset)>; 738def : InstAlias<"jalr $rs", (JALR X1, GPR:$rs, 0), 3>; 739def : InstAlias<"jalr ${offset}(${rs})", (JALR X1, GPR:$rs, simm12:$offset)>; 740def : InstAlias<"jalr $rd, $rs", (JALR GPR:$rd, GPR:$rs, 0), 2>; 741def : InstAlias<"ret", (JALR X0, X1, 0), 4>; 742 743// Non-canonical forms for jump targets also accepted by the assembler. 744def : InstAlias<"jr $rs, $offset", (JALR X0, GPR:$rs, simm12:$offset), 0>; 745def : InstAlias<"jalr $rs, $offset", (JALR X1, GPR:$rs, simm12:$offset), 0>; 746def : InstAlias<"jalr $rd, $rs, $offset", (JALR GPR:$rd, GPR:$rs, simm12:$offset), 0>; 747 748def : InstAlias<"fence", (FENCE 0xF, 0xF)>; // 0xF == iorw 749 750def : InstAlias<"rdinstret $rd", (CSRRS GPR:$rd, INSTRET.Encoding, X0)>; 751def : InstAlias<"rdcycle $rd", (CSRRS GPR:$rd, CYCLE.Encoding, X0)>; 752def : InstAlias<"rdtime $rd", (CSRRS GPR:$rd, TIME.Encoding, X0)>; 753 754let Predicates = [IsRV32] in { 755def : InstAlias<"rdinstreth $rd", (CSRRS GPR:$rd, INSTRETH.Encoding, X0)>; 756def : InstAlias<"rdcycleh $rd", (CSRRS GPR:$rd, CYCLEH.Encoding, X0)>; 757def : InstAlias<"rdtimeh $rd", (CSRRS GPR:$rd, TIMEH.Encoding, X0)>; 758} // Predicates = [IsRV32] 759 760def : InstAlias<"csrr $rd, $csr", (CSRRS GPR:$rd, csr_sysreg:$csr, X0)>; 761def : InstAlias<"csrw $csr, $rs", (CSRRW X0, csr_sysreg:$csr, GPR:$rs)>; 762def : InstAlias<"csrs $csr, $rs", (CSRRS X0, csr_sysreg:$csr, GPR:$rs)>; 763def : InstAlias<"csrc $csr, $rs", (CSRRC X0, csr_sysreg:$csr, GPR:$rs)>; 764 765def : InstAlias<"csrwi $csr, $imm", (CSRRWI X0, csr_sysreg:$csr, uimm5:$imm)>; 766def : InstAlias<"csrsi $csr, $imm", (CSRRSI X0, csr_sysreg:$csr, uimm5:$imm)>; 767def : InstAlias<"csrci $csr, $imm", (CSRRCI X0, csr_sysreg:$csr, uimm5:$imm)>; 768 769let EmitPriority = 0 in { 770def : InstAlias<"csrw $csr, $imm", (CSRRWI X0, csr_sysreg:$csr, uimm5:$imm)>; 771def : InstAlias<"csrs $csr, $imm", (CSRRSI X0, csr_sysreg:$csr, uimm5:$imm)>; 772def : InstAlias<"csrc $csr, $imm", (CSRRCI X0, csr_sysreg:$csr, uimm5:$imm)>; 773 774def : InstAlias<"csrrw $rd, $csr, $imm", (CSRRWI GPR:$rd, csr_sysreg:$csr, uimm5:$imm)>; 775def : InstAlias<"csrrs $rd, $csr, $imm", (CSRRSI GPR:$rd, csr_sysreg:$csr, uimm5:$imm)>; 776def : InstAlias<"csrrc $rd, $csr, $imm", (CSRRCI GPR:$rd, csr_sysreg:$csr, uimm5:$imm)>; 777} 778 779def : InstAlias<"sfence.vma", (SFENCE_VMA X0, X0)>; 780def : InstAlias<"sfence.vma $rs", (SFENCE_VMA GPR:$rs, X0)>; 781 782let EmitPriority = 0 in { 783def : InstAlias<"lb $rd, (${rs1})", 784 (LB GPR:$rd, GPR:$rs1, 0)>; 785def : InstAlias<"lh $rd, (${rs1})", 786 (LH GPR:$rd, GPR:$rs1, 0)>; 787def : InstAlias<"lw $rd, (${rs1})", 788 (LW GPR:$rd, GPR:$rs1, 0)>; 789def : InstAlias<"lbu $rd, (${rs1})", 790 (LBU GPR:$rd, GPR:$rs1, 0)>; 791def : InstAlias<"lhu $rd, (${rs1})", 792 (LHU GPR:$rd, GPR:$rs1, 0)>; 793 794def : InstAlias<"sb $rs2, (${rs1})", 795 (SB GPR:$rs2, GPR:$rs1, 0)>; 796def : InstAlias<"sh $rs2, (${rs1})", 797 (SH GPR:$rs2, GPR:$rs1, 0)>; 798def : InstAlias<"sw $rs2, (${rs1})", 799 (SW GPR:$rs2, GPR:$rs1, 0)>; 800 801def : InstAlias<"add $rd, $rs1, $imm12", 802 (ADDI GPR:$rd, GPR:$rs1, simm12:$imm12)>; 803def : InstAlias<"and $rd, $rs1, $imm12", 804 (ANDI GPR:$rd, GPR:$rs1, simm12:$imm12)>; 805def : InstAlias<"xor $rd, $rs1, $imm12", 806 (XORI GPR:$rd, GPR:$rs1, simm12:$imm12)>; 807def : InstAlias<"or $rd, $rs1, $imm12", 808 (ORI GPR:$rd, GPR:$rs1, simm12:$imm12)>; 809def : InstAlias<"sll $rd, $rs1, $shamt", 810 (SLLI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt)>; 811def : InstAlias<"srl $rd, $rs1, $shamt", 812 (SRLI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt)>; 813def : InstAlias<"sra $rd, $rs1, $shamt", 814 (SRAI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt)>; 815let Predicates = [IsRV64] in { 816def : InstAlias<"lwu $rd, (${rs1})", 817 (LWU GPR:$rd, GPR:$rs1, 0)>; 818def : InstAlias<"ld $rd, (${rs1})", 819 (LD GPR:$rd, GPR:$rs1, 0)>; 820def : InstAlias<"sd $rs2, (${rs1})", 821 (SD GPR:$rs2, GPR:$rs1, 0)>; 822 823def : InstAlias<"addw $rd, $rs1, $imm12", 824 (ADDIW GPR:$rd, GPR:$rs1, simm12:$imm12)>; 825def : InstAlias<"sllw $rd, $rs1, $shamt", 826 (SLLIW GPR:$rd, GPR:$rs1, uimm5:$shamt)>; 827def : InstAlias<"srlw $rd, $rs1, $shamt", 828 (SRLIW GPR:$rd, GPR:$rs1, uimm5:$shamt)>; 829def : InstAlias<"sraw $rd, $rs1, $shamt", 830 (SRAIW GPR:$rd, GPR:$rs1, uimm5:$shamt)>; 831} // Predicates = [IsRV64] 832def : InstAlias<"slt $rd, $rs1, $imm12", 833 (SLTI GPR:$rd, GPR:$rs1, simm12:$imm12)>; 834def : InstAlias<"sltu $rd, $rs1, $imm12", 835 (SLTIU GPR:$rd, GPR:$rs1, simm12:$imm12)>; 836} 837 838def : MnemonicAlias<"move", "mv">; 839 840// The SCALL and SBREAK instructions wererenamed to ECALL and EBREAK in 841// version 2.1 of the user-level ISA. Like the GNU toolchain, we still accept 842// the old name for backwards compatibility. 843def : MnemonicAlias<"scall", "ecall">; 844def : MnemonicAlias<"sbreak", "ebreak">; 845 846// This alias was added to the spec in December 2020. Don't print it by default 847// to allow assembly we print to be compatible with versions of GNU assembler 848// that don't support this alias. 849def : InstAlias<"zext.b $rd, $rs", (ANDI GPR:$rd, GPR:$rs, 0xFF), 0>; 850 851//===----------------------------------------------------------------------===// 852// Pseudo-instructions and codegen patterns 853// 854// Naming convention: For 'generic' pattern classes, we use the naming 855// convention PatTy1Ty2. For pattern classes which offer a more complex 856// expansion, prefix the class name, e.g. BccPat. 857//===----------------------------------------------------------------------===// 858 859/// Generic pattern classes 860 861class PatGpr<SDPatternOperator OpNode, RVInst Inst> 862 : Pat<(OpNode GPR:$rs1), (Inst GPR:$rs1)>; 863class PatGprGpr<SDPatternOperator OpNode, RVInst Inst> 864 : Pat<(OpNode GPR:$rs1, GPR:$rs2), (Inst GPR:$rs1, GPR:$rs2)>; 865 866class PatGprImm<SDPatternOperator OpNode, RVInst Inst, ImmLeaf ImmType> 867 : Pat<(XLenVT (OpNode (XLenVT GPR:$rs1), ImmType:$imm)), 868 (Inst GPR:$rs1, ImmType:$imm)>; 869class PatGprSimm12<SDPatternOperator OpNode, RVInstI Inst> 870 : PatGprImm<OpNode, Inst, simm12>; 871class PatGprUimmLog2XLen<SDPatternOperator OpNode, RVInstIShift Inst> 872 : PatGprImm<OpNode, Inst, uimmlog2xlen>; 873 874/// Predicates 875 876def IsOrAdd: PatFrag<(ops node:$A, node:$B), (or node:$A, node:$B), [{ 877 return isOrEquivalentToAdd(N); 878}]>; 879def assertsexti32 : PatFrag<(ops node:$src), (assertsext node:$src), [{ 880 return cast<VTSDNode>(N->getOperand(1))->getVT().bitsLE(MVT::i32); 881}]>; 882def sexti32 : ComplexPattern<i64, 1, "selectSExti32">; 883def assertzexti32 : PatFrag<(ops node:$src), (assertzext node:$src), [{ 884 return cast<VTSDNode>(N->getOperand(1))->getVT().bitsLE(MVT::i32); 885}]>; 886def zexti32 : ComplexPattern<i64, 1, "selectZExti32">; 887 888def add_oneuse : PatFrag<(ops node:$A, node:$B), (add node:$A, node:$B), [{ 889 return N->hasOneUse(); 890}]>; 891 892def mul_oneuse : PatFrag<(ops node:$A, node:$B), (mul node:$A, node:$B), [{ 893 return N->hasOneUse(); 894}]>; 895 896/// Simple arithmetic operations 897 898def : PatGprGpr<add, ADD>; 899def : PatGprSimm12<add, ADDI>; 900def : PatGprGpr<sub, SUB>; 901def : PatGprGpr<or, OR>; 902def : PatGprSimm12<or, ORI>; 903def : PatGprGpr<and, AND>; 904def : PatGprSimm12<and, ANDI>; 905def : PatGprGpr<xor, XOR>; 906def : PatGprSimm12<xor, XORI>; 907def : PatGprUimmLog2XLen<shl, SLLI>; 908def : PatGprUimmLog2XLen<srl, SRLI>; 909def : PatGprUimmLog2XLen<sra, SRAI>; 910 911// Match both a plain shift and one where the shift amount is masked (this is 912// typically introduced when the legalizer promotes the shift amount and 913// zero-extends it). For RISC-V, the mask is unnecessary as shifts in the base 914// ISA only read the least significant 5 bits (RV32I) or 6 bits (RV64I). 915def shiftMaskXLen : ComplexPattern<XLenVT, 1, "selectShiftMaskXLen", [], [], 0>; 916def shiftMask32 : ComplexPattern<i64, 1, "selectShiftMask32", [], [], 0>; 917 918class shiftop<SDPatternOperator operator> 919 : PatFrag<(ops node:$val, node:$count), 920 (operator node:$val, (XLenVT (shiftMaskXLen node:$count)))>; 921class shiftopw<SDPatternOperator operator> 922 : PatFrag<(ops node:$val, node:$count), 923 (operator node:$val, (i64 (shiftMask32 node:$count)))>; 924 925def : PatGprGpr<shiftop<shl>, SLL>; 926def : PatGprGpr<shiftop<srl>, SRL>; 927def : PatGprGpr<shiftop<sra>, SRA>; 928 929// This is a special case of the ADD instruction used to facilitate the use of a 930// fourth operand to emit a relocation on a symbol relating to this instruction. 931// The relocation does not affect any bits of the instruction itself but is used 932// as a hint to the linker. 933let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 0 in 934def PseudoAddTPRel : Pseudo<(outs GPR:$rd), 935 (ins GPR:$rs1, GPR:$rs2, tprel_add_symbol:$src), [], 936 "add", "$rd, $rs1, $rs2, $src">; 937 938/// FrameIndex calculations 939 940def : Pat<(add (XLenVT AddrFI:$Rs), simm12:$imm12), 941 (ADDI (XLenVT AddrFI:$Rs), simm12:$imm12)>; 942def : Pat<(IsOrAdd (XLenVT AddrFI:$Rs), simm12:$imm12), 943 (ADDI (XLenVT AddrFI:$Rs), simm12:$imm12)>; 944 945/// Setcc 946 947def : PatGprGpr<setlt, SLT>; 948def : PatGprSimm12<setlt, SLTI>; 949def : PatGprGpr<setult, SLTU>; 950def : PatGprSimm12<setult, SLTIU>; 951 952// Define pattern expansions for setcc operations that aren't directly 953// handled by a RISC-V instruction. 954def : Pat<(seteq GPR:$rs1, 0), (SLTIU GPR:$rs1, 1)>; 955def : Pat<(seteq GPR:$rs1, GPR:$rs2), (SLTIU (XOR GPR:$rs1, GPR:$rs2), 1)>; 956def : Pat<(seteq GPR:$rs1, simm12_plus1:$imm12), 957 (SLTIU (ADDI GPR:$rs1, (NegImm simm12_plus1:$imm12)), 1)>; 958def : Pat<(setne GPR:$rs1, 0), (SLTU X0, GPR:$rs1)>; 959def : Pat<(setne GPR:$rs1, GPR:$rs2), (SLTU X0, (XOR GPR:$rs1, GPR:$rs2))>; 960def : Pat<(setne GPR:$rs1, simm12_plus1:$imm12), 961 (SLTU X0, (ADDI GPR:$rs1, (NegImm simm12_plus1:$imm12)))>; 962def : Pat<(setugt GPR:$rs1, GPR:$rs2), (SLTU GPR:$rs2, GPR:$rs1)>; 963def : Pat<(setuge GPR:$rs1, GPR:$rs2), (XORI (SLTU GPR:$rs1, GPR:$rs2), 1)>; 964def : Pat<(setule GPR:$rs1, GPR:$rs2), (XORI (SLTU GPR:$rs2, GPR:$rs1), 1)>; 965def : Pat<(setgt GPR:$rs1, GPR:$rs2), (SLT GPR:$rs2, GPR:$rs1)>; 966def : Pat<(setge GPR:$rs1, GPR:$rs2), (XORI (SLT GPR:$rs1, GPR:$rs2), 1)>; 967def : Pat<(setle GPR:$rs1, GPR:$rs2), (XORI (SLT GPR:$rs2, GPR:$rs1), 1)>; 968 969let usesCustomInserter = 1 in 970class SelectCC_rrirr<RegisterClass valty, RegisterClass cmpty> 971 : Pseudo<(outs valty:$dst), 972 (ins cmpty:$lhs, cmpty:$rhs, ixlenimm:$imm, 973 valty:$truev, valty:$falsev), 974 [(set valty:$dst, (riscv_selectcc cmpty:$lhs, cmpty:$rhs, 975 (XLenVT timm:$imm), valty:$truev, valty:$falsev))]>; 976 977def Select_GPR_Using_CC_GPR : SelectCC_rrirr<GPR, GPR>; 978 979/// Branches and jumps 980 981// Match `riscv_brcc` and lower to the appropriate RISC-V branch instruction. 982class BccPat<CondCode Cond, RVInstB Inst> 983 : Pat<(riscv_brcc GPR:$rs1, GPR:$rs2, Cond, bb:$imm12), 984 (Inst GPR:$rs1, GPR:$rs2, simm13_lsb0:$imm12)>; 985 986def : BccPat<SETEQ, BEQ>; 987def : BccPat<SETNE, BNE>; 988def : BccPat<SETLT, BLT>; 989def : BccPat<SETGE, BGE>; 990def : BccPat<SETULT, BLTU>; 991def : BccPat<SETUGE, BGEU>; 992 993let isBarrier = 1, isBranch = 1, isTerminator = 1 in 994def PseudoBR : Pseudo<(outs), (ins simm21_lsb0_jal:$imm20), [(br bb:$imm20)]>, 995 PseudoInstExpansion<(JAL X0, simm21_lsb0_jal:$imm20)>; 996 997let isBarrier = 1, isBranch = 1, isIndirectBranch = 1, isTerminator = 1 in 998def PseudoBRIND : Pseudo<(outs), (ins GPRJALR:$rs1, simm12:$imm12), []>, 999 PseudoInstExpansion<(JALR X0, GPR:$rs1, simm12:$imm12)>; 1000 1001def : Pat<(brind GPRJALR:$rs1), (PseudoBRIND GPRJALR:$rs1, 0)>; 1002def : Pat<(brind (add GPRJALR:$rs1, simm12:$imm12)), 1003 (PseudoBRIND GPRJALR:$rs1, simm12:$imm12)>; 1004 1005// PseudoCALLReg is a generic pseudo instruction for calls which will eventually 1006// expand to auipc and jalr while encoding, with any given register used as the 1007// destination. 1008// Define AsmString to print "call" when compile with -S flag. 1009// Define isCodeGenOnly = 0 to support parsing assembly "call" instruction. 1010let isCall = 1, isBarrier = 1, isCodeGenOnly = 0, hasSideEffects = 0, 1011 mayStore = 0, mayLoad = 0 in 1012def PseudoCALLReg : Pseudo<(outs GPR:$rd), (ins call_symbol:$func), []> { 1013 let AsmString = "call\t$rd, $func"; 1014} 1015 1016// PseudoCALL is a pseudo instruction which will eventually expand to auipc 1017// and jalr while encoding. This is desirable, as an auipc+jalr pair with 1018// R_RISCV_CALL and R_RISCV_RELAX relocations can be be relaxed by the linker 1019// if the offset fits in a signed 21-bit immediate. 1020// Define AsmString to print "call" when compile with -S flag. 1021// Define isCodeGenOnly = 0 to support parsing assembly "call" instruction. 1022let isCall = 1, Defs = [X1], isCodeGenOnly = 0 in 1023def PseudoCALL : Pseudo<(outs), (ins call_symbol:$func), []> { 1024 let AsmString = "call\t$func"; 1025} 1026 1027def : Pat<(riscv_call tglobaladdr:$func), (PseudoCALL tglobaladdr:$func)>; 1028def : Pat<(riscv_call texternalsym:$func), (PseudoCALL texternalsym:$func)>; 1029 1030def : Pat<(riscv_uret_flag), (URET X0, X0)>; 1031def : Pat<(riscv_sret_flag), (SRET X0, X0)>; 1032def : Pat<(riscv_mret_flag), (MRET X0, X0)>; 1033 1034let isCall = 1, Defs = [X1] in 1035def PseudoCALLIndirect : Pseudo<(outs), (ins GPRJALR:$rs1), 1036 [(riscv_call GPRJALR:$rs1)]>, 1037 PseudoInstExpansion<(JALR X1, GPR:$rs1, 0)>; 1038 1039let isBarrier = 1, isReturn = 1, isTerminator = 1 in 1040def PseudoRET : Pseudo<(outs), (ins), [(riscv_ret_flag)]>, 1041 PseudoInstExpansion<(JALR X0, X1, 0)>; 1042 1043// PseudoTAIL is a pseudo instruction similar to PseudoCALL and will eventually 1044// expand to auipc and jalr while encoding. 1045// Define AsmString to print "tail" when compile with -S flag. 1046let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [X2], 1047 isCodeGenOnly = 0 in 1048def PseudoTAIL : Pseudo<(outs), (ins call_symbol:$dst), []> { 1049 let AsmString = "tail\t$dst"; 1050} 1051 1052let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [X2] in 1053def PseudoTAILIndirect : Pseudo<(outs), (ins GPRTC:$rs1), 1054 [(riscv_tail GPRTC:$rs1)]>, 1055 PseudoInstExpansion<(JALR X0, GPR:$rs1, 0)>; 1056 1057def : Pat<(riscv_tail (iPTR tglobaladdr:$dst)), 1058 (PseudoTAIL texternalsym:$dst)>; 1059def : Pat<(riscv_tail (iPTR texternalsym:$dst)), 1060 (PseudoTAIL texternalsym:$dst)>; 1061 1062let isCall = 0, isBarrier = 1, isBranch = 1, isTerminator = 1, 1063 isCodeGenOnly = 0, hasSideEffects = 0, mayStore = 0, mayLoad = 0 in 1064def PseudoJump : Pseudo<(outs GPR:$rd), (ins pseudo_jump_symbol:$target), []> { 1065 let AsmString = "jump\t$target, $rd"; 1066} 1067 1068let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 0, 1069 isAsmParserOnly = 1 in 1070def PseudoLLA : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], 1071 "lla", "$dst, $src">; 1072 1073let hasSideEffects = 0, mayLoad = 1, mayStore = 0, isCodeGenOnly = 0, 1074 isAsmParserOnly = 1 in 1075def PseudoLA : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], 1076 "la", "$dst, $src">; 1077 1078let hasSideEffects = 0, mayLoad = 1, mayStore = 0, isCodeGenOnly = 0, 1079 isAsmParserOnly = 1 in 1080def PseudoLA_TLS_IE : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], 1081 "la.tls.ie", "$dst, $src">; 1082 1083let hasSideEffects = 0, mayLoad = 1, mayStore = 0, isCodeGenOnly = 0, 1084 isAsmParserOnly = 1 in 1085def PseudoLA_TLS_GD : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [], 1086 "la.tls.gd", "$dst, $src">; 1087 1088 1089/// Sign/Zero Extends 1090 1091// There are single-instruction versions of these in Zbb, so disable these 1092// Pseudos if that extension is present. 1093let hasSideEffects = 0, mayLoad = 0, 1094 mayStore = 0, isCodeGenOnly = 0, isAsmParserOnly = 1 in { 1095def PseudoSEXT_B : Pseudo<(outs GPR:$rd), (ins GPR:$rs), [], "sext.b", "$rd, $rs">; 1096def PseudoSEXT_H : Pseudo<(outs GPR:$rd), (ins GPR:$rs), [], "sext.h", "$rd, $rs">; 1097// rv64's sext.w is defined above, using InstAlias<"sext.w ... 1098// zext.b is defined above, using InstAlias<"zext.b ... 1099def PseudoZEXT_H : Pseudo<(outs GPR:$rd), (ins GPR:$rs), [], "zext.h", "$rd, $rs">; 1100} // hasSideEffects = 0, ... 1101 1102let Predicates = [IsRV64], hasSideEffects = 0, mayLoad = 0, mayStore = 0, 1103 isCodeGenOnly = 0, isAsmParserOnly = 1 in { 1104def PseudoZEXT_W : Pseudo<(outs GPR:$rd), (ins GPR:$rs), [], "zext.w", "$rd, $rs">; 1105} // Predicates = [IsRV64], ... 1106 1107/// Loads 1108 1109multiclass LdPat<PatFrag LoadOp, RVInst Inst, ValueType vt = XLenVT> { 1110 def : Pat<(vt (LoadOp BaseAddr:$rs1)), (Inst BaseAddr:$rs1, 0)>; 1111 def : Pat<(vt (LoadOp (add BaseAddr:$rs1, simm12:$imm12))), 1112 (Inst BaseAddr:$rs1, simm12:$imm12)>; 1113 def : Pat<(vt (LoadOp (IsOrAdd AddrFI:$rs1, simm12:$imm12))), 1114 (Inst AddrFI:$rs1, simm12:$imm12)>; 1115} 1116 1117defm : LdPat<sextloadi8, LB>; 1118defm : LdPat<extloadi8, LB>; 1119defm : LdPat<sextloadi16, LH>; 1120defm : LdPat<extloadi16, LH>; 1121defm : LdPat<load, LW, i32>, Requires<[IsRV32]>; 1122defm : LdPat<zextloadi8, LBU>; 1123defm : LdPat<zextloadi16, LHU>; 1124 1125/// Stores 1126 1127multiclass StPat<PatFrag StoreOp, RVInst Inst, RegisterClass StTy, 1128 ValueType vt> { 1129 def : Pat<(StoreOp (vt StTy:$rs2), BaseAddr:$rs1), 1130 (Inst StTy:$rs2, BaseAddr:$rs1, 0)>; 1131 def : Pat<(StoreOp (vt StTy:$rs2), (add BaseAddr:$rs1, simm12:$imm12)), 1132 (Inst StTy:$rs2, BaseAddr:$rs1, simm12:$imm12)>; 1133 def : Pat<(StoreOp (vt StTy:$rs2), (IsOrAdd AddrFI:$rs1, simm12:$imm12)), 1134 (Inst StTy:$rs2, AddrFI:$rs1, simm12:$imm12)>; 1135} 1136 1137defm : StPat<truncstorei8, SB, GPR, XLenVT>; 1138defm : StPat<truncstorei16, SH, GPR, XLenVT>; 1139defm : StPat<store, SW, GPR, i32>, Requires<[IsRV32]>; 1140 1141/// Fences 1142 1143// Refer to Table A.6 in the version 2.3 draft of the RISC-V Instruction Set 1144// Manual: Volume I. 1145 1146// fence acquire -> fence r, rw 1147def : Pat<(atomic_fence (XLenVT 4), (timm)), (FENCE 0b10, 0b11)>; 1148// fence release -> fence rw, w 1149def : Pat<(atomic_fence (XLenVT 5), (timm)), (FENCE 0b11, 0b1)>; 1150// fence acq_rel -> fence.tso 1151def : Pat<(atomic_fence (XLenVT 6), (timm)), (FENCE_TSO)>; 1152// fence seq_cst -> fence rw, rw 1153def : Pat<(atomic_fence (XLenVT 7), (timm)), (FENCE 0b11, 0b11)>; 1154 1155// Lowering for atomic load and store is defined in RISCVInstrInfoA.td. 1156// Although these are lowered to fence+load/store instructions defined in the 1157// base RV32I/RV64I ISA, this lowering is only used when the A extension is 1158// present. This is necessary as it isn't valid to mix __atomic_* libcalls 1159// with inline atomic operations for the same object. 1160 1161/// Access to system registers 1162 1163// Helpers for defining specific operations. They are defined for each system 1164// register separately. Side effect is not used because dependencies are 1165// expressed via use-def properties. 1166 1167class ReadSysReg<SysReg SR, list<Register> Regs> 1168 : Pseudo<(outs GPR:$rd), (ins), 1169 [(set GPR:$rd, (riscv_read_csr (XLenVT SR.Encoding)))]>, 1170 PseudoInstExpansion<(CSRRS GPR:$rd, SR.Encoding, X0)> { 1171 let hasSideEffects = 0; 1172 let Uses = Regs; 1173} 1174 1175class WriteSysReg<SysReg SR, list<Register> Regs> 1176 : Pseudo<(outs), (ins GPR:$val), 1177 [(riscv_write_csr (XLenVT SR.Encoding), GPR:$val)]>, 1178 PseudoInstExpansion<(CSRRW X0, SR.Encoding, GPR:$val)> { 1179 let hasSideEffects = 0; 1180 let Defs = Regs; 1181} 1182 1183class WriteSysRegImm<SysReg SR, list<Register> Regs> 1184 : Pseudo<(outs), (ins uimm5:$val), 1185 [(riscv_write_csr (XLenVT SR.Encoding), uimm5:$val)]>, 1186 PseudoInstExpansion<(CSRRWI X0, SR.Encoding, uimm5:$val)> { 1187 let hasSideEffects = 0; 1188 let Defs = Regs; 1189} 1190 1191class SwapSysReg<SysReg SR, list<Register> Regs> 1192 : Pseudo<(outs GPR:$rd), (ins GPR:$val), 1193 [(set GPR:$rd, (riscv_swap_csr (XLenVT SR.Encoding), GPR:$val))]>, 1194 PseudoInstExpansion<(CSRRW GPR:$rd, SR.Encoding, GPR:$val)> { 1195 let hasSideEffects = 0; 1196 let Uses = Regs; 1197 let Defs = Regs; 1198} 1199 1200class SwapSysRegImm<SysReg SR, list<Register> Regs> 1201 : Pseudo<(outs GPR:$rd), (ins uimm5:$val), 1202 [(set GPR:$rd, (riscv_swap_csr (XLenVT SR.Encoding), uimm5:$val))]>, 1203 PseudoInstExpansion<(CSRRWI GPR:$rd, SR.Encoding, uimm5:$val)> { 1204 let hasSideEffects = 0; 1205 let Uses = Regs; 1206 let Defs = Regs; 1207} 1208 1209def ReadFRM : ReadSysReg<SysRegFRM, [FRM]>; 1210def WriteFRM : WriteSysReg<SysRegFRM, [FRM]>; 1211def WriteFRMImm : WriteSysRegImm<SysRegFRM, [FRM]>; 1212 1213/// Other pseudo-instructions 1214 1215// Pessimistically assume the stack pointer will be clobbered 1216let Defs = [X2], Uses = [X2] in { 1217def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2), 1218 [(callseq_start timm:$amt1, timm:$amt2)]>; 1219def ADJCALLSTACKUP : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2), 1220 [(callseq_end timm:$amt1, timm:$amt2)]>; 1221} // Defs = [X2], Uses = [X2] 1222 1223/// RV64 patterns 1224 1225let Predicates = [IsRV64, NotHasStdExtZba] in { 1226def : Pat<(i64 (and GPR:$rs1, 0xffffffff)), (SRLI (SLLI GPR:$rs1, 32), 32)>; 1227 1228// If we're shifting a 32-bit zero extended value left by 0-31 bits, use 2 1229// shifts instead of 3. This can occur when unsigned is used to index an array. 1230def : Pat<(i64 (shl (and GPR:$rs1, 0xffffffff), uimm5:$shamt)), 1231 (SRLI (SLLI GPR:$rs1, 32), (ImmSubFrom32 uimm5:$shamt))>; 1232} 1233 1234let Predicates = [IsRV64] in { 1235 1236/// sext and zext 1237 1238def : Pat<(sext_inreg GPR:$rs1, i32), (ADDIW GPR:$rs1, 0)>; 1239 1240/// ALU operations 1241 1242def : Pat<(sext_inreg (add GPR:$rs1, GPR:$rs2), i32), 1243 (ADDW GPR:$rs1, GPR:$rs2)>; 1244def : Pat<(sext_inreg (add GPR:$rs1, simm12:$imm12), i32), 1245 (ADDIW GPR:$rs1, simm12:$imm12)>; 1246def : Pat<(sext_inreg (sub GPR:$rs1, GPR:$rs2), i32), 1247 (SUBW GPR:$rs1, GPR:$rs2)>; 1248def : Pat<(sext_inreg (shl GPR:$rs1, uimm5:$shamt), i32), 1249 (SLLIW GPR:$rs1, uimm5:$shamt)>; 1250def : Pat<(i64 (srl (and GPR:$rs1, 0xffffffff), uimm5:$shamt)), 1251 (SRLIW GPR:$rs1, uimm5:$shamt)>; 1252def : Pat<(i64 (srl (shl GPR:$rs1, (i64 32)), uimm6gt32:$shamt)), 1253 (SRLIW GPR:$rs1, (ImmSub32 uimm6gt32:$shamt))>; 1254def : Pat<(sra (sext_inreg GPR:$rs1, i32), uimm5:$shamt), 1255 (SRAIW GPR:$rs1, uimm5:$shamt)>; 1256def : Pat<(i64 (sra (shl GPR:$rs1, (i64 32)), uimm6gt32:$shamt)), 1257 (SRAIW GPR:$rs1, (ImmSub32 uimm6gt32:$shamt))>; 1258 1259def : PatGprGpr<shiftopw<riscv_sllw>, SLLW>; 1260def : PatGprGpr<shiftopw<riscv_srlw>, SRLW>; 1261def : PatGprGpr<shiftopw<riscv_sraw>, SRAW>; 1262 1263/// Loads 1264 1265defm : LdPat<sextloadi32, LW, i64>; 1266defm : LdPat<extloadi32, LW, i64>; 1267defm : LdPat<zextloadi32, LWU, i64>; 1268defm : LdPat<load, LD, i64>; 1269 1270/// Stores 1271 1272defm : StPat<truncstorei32, SW, GPR, i64>; 1273defm : StPat<store, SD, GPR, i64>; 1274} // Predicates = [IsRV64] 1275 1276/// readcyclecounter 1277// On RV64, we can directly read the 64-bit "cycle" CSR. 1278let Predicates = [IsRV64] in 1279def : Pat<(i64 (readcyclecounter)), (CSRRS CYCLE.Encoding, X0)>; 1280// On RV32, ReadCycleWide will be expanded to the suggested loop reading both 1281// halves of the 64-bit "cycle" CSR. 1282let Predicates = [IsRV32], usesCustomInserter = 1, hasNoSchedulingInfo = 1 in 1283def ReadCycleWide : Pseudo<(outs GPR:$lo, GPR:$hi), (ins), 1284 [(set GPR:$lo, GPR:$hi, (riscv_read_cycle_wide))], 1285 "", "">; 1286 1287/// traps 1288 1289// We lower `trap` to `unimp`, as this causes a hard exception on nearly all 1290// systems. 1291def : Pat<(trap), (UNIMP)>; 1292 1293// We lower `debugtrap` to `ebreak`, as this will get the attention of the 1294// debugger if possible. 1295def : Pat<(debugtrap), (EBREAK)>; 1296 1297/// Simple optimization 1298def : Pat<(add GPR:$rs1, (AddiPair:$rs2)), 1299 (ADDI (ADDI GPR:$rs1, (AddiPairImmB AddiPair:$rs2)), 1300 (AddiPairImmA GPR:$rs2))>; 1301 1302let Predicates = [IsRV64] in { 1303def : Pat<(sext_inreg (add_oneuse GPR:$rs1, (AddiPair:$rs2)), i32), 1304 (ADDIW (ADDIW GPR:$rs1, (AddiPairImmB AddiPair:$rs2)), 1305 (AddiPairImmA AddiPair:$rs2))>; 1306} 1307 1308//===----------------------------------------------------------------------===// 1309// Standard extensions 1310//===----------------------------------------------------------------------===// 1311 1312include "RISCVInstrInfoM.td" 1313include "RISCVInstrInfoA.td" 1314include "RISCVInstrInfoF.td" 1315include "RISCVInstrInfoD.td" 1316include "RISCVInstrInfoC.td" 1317include "RISCVInstrInfoB.td" 1318include "RISCVInstrInfoV.td" 1319include "RISCVInstrInfoZfh.td" 1320