1 //===-- RISCVAsmParser.cpp - Parse RISC-V assembly to MCInst instructions -===// 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 #include "MCTargetDesc/RISCVAsmBackend.h" 10 #include "MCTargetDesc/RISCVBaseInfo.h" 11 #include "MCTargetDesc/RISCVInstPrinter.h" 12 #include "MCTargetDesc/RISCVMCExpr.h" 13 #include "MCTargetDesc/RISCVMCTargetDesc.h" 14 #include "MCTargetDesc/RISCVMatInt.h" 15 #include "MCTargetDesc/RISCVTargetStreamer.h" 16 #include "TargetInfo/RISCVTargetInfo.h" 17 #include "llvm/ADT/STLExtras.h" 18 #include "llvm/ADT/SmallBitVector.h" 19 #include "llvm/ADT/SmallVector.h" 20 #include "llvm/ADT/Statistic.h" 21 #include "llvm/ADT/StringExtras.h" 22 #include "llvm/MC/MCAssembler.h" 23 #include "llvm/MC/MCContext.h" 24 #include "llvm/MC/MCExpr.h" 25 #include "llvm/MC/MCInst.h" 26 #include "llvm/MC/MCInstBuilder.h" 27 #include "llvm/MC/MCInstrInfo.h" 28 #include "llvm/MC/MCObjectFileInfo.h" 29 #include "llvm/MC/MCParser/MCAsmLexer.h" 30 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 31 #include "llvm/MC/MCParser/MCTargetAsmParser.h" 32 #include "llvm/MC/MCRegisterInfo.h" 33 #include "llvm/MC/MCStreamer.h" 34 #include "llvm/MC/MCSubtargetInfo.h" 35 #include "llvm/MC/MCValue.h" 36 #include "llvm/MC/TargetRegistry.h" 37 #include "llvm/Support/Casting.h" 38 #include "llvm/Support/CommandLine.h" 39 #include "llvm/Support/MathExtras.h" 40 #include "llvm/Support/RISCVAttributes.h" 41 #include "llvm/Support/RISCVISAInfo.h" 42 43 #include <limits> 44 45 using namespace llvm; 46 47 #define DEBUG_TYPE "riscv-asm-parser" 48 49 STATISTIC(RISCVNumInstrsCompressed, 50 "Number of RISC-V Compressed instructions emitted"); 51 52 static cl::opt<bool> AddBuildAttributes("riscv-add-build-attributes", 53 cl::init(false)); 54 55 namespace llvm { 56 extern const SubtargetFeatureKV RISCVFeatureKV[RISCV::NumSubtargetFeatures]; 57 } // namespace llvm 58 59 namespace { 60 struct RISCVOperand; 61 62 struct ParserOptionsSet { 63 bool IsPicEnabled; 64 }; 65 66 class RISCVAsmParser : public MCTargetAsmParser { 67 // This tracks the parsing of the 4 operands that make up the vtype portion 68 // of vset(i)vli instructions which are separated by commas. The state names 69 // represent the next expected operand with Done meaning no other operands are 70 // expected. 71 enum VTypeState { 72 VTypeState_SEW, 73 VTypeState_LMUL, 74 VTypeState_TailPolicy, 75 VTypeState_MaskPolicy, 76 VTypeState_Done, 77 }; 78 79 SmallVector<FeatureBitset, 4> FeatureBitStack; 80 81 SmallVector<ParserOptionsSet, 4> ParserOptionsStack; 82 ParserOptionsSet ParserOptions; 83 84 SMLoc getLoc() const { return getParser().getTok().getLoc(); } 85 bool isRV64() const { return getSTI().hasFeature(RISCV::Feature64Bit); } 86 bool isRVE() const { return getSTI().hasFeature(RISCV::FeatureRVE); } 87 88 RISCVTargetStreamer &getTargetStreamer() { 89 assert(getParser().getStreamer().getTargetStreamer() && 90 "do not have a target streamer"); 91 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer(); 92 return static_cast<RISCVTargetStreamer &>(TS); 93 } 94 95 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, 96 unsigned Kind) override; 97 unsigned checkTargetMatchPredicate(MCInst &Inst) override; 98 99 bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo, 100 int64_t Lower, int64_t Upper, 101 const Twine &Msg); 102 bool generateImmOutOfRangeError(SMLoc ErrorLoc, int64_t Lower, int64_t Upper, 103 const Twine &Msg); 104 105 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 106 OperandVector &Operands, MCStreamer &Out, 107 uint64_t &ErrorInfo, 108 bool MatchingInlineAsm) override; 109 110 bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override; 111 ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, 112 SMLoc &EndLoc) override; 113 114 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 115 SMLoc NameLoc, OperandVector &Operands) override; 116 117 ParseStatus parseDirective(AsmToken DirectiveID) override; 118 119 bool parseVTypeToken(StringRef Identifier, VTypeState &State, unsigned &Sew, 120 unsigned &Lmul, bool &Fractional, bool &TailAgnostic, 121 bool &MaskAgnostic); 122 bool generateVTypeError(SMLoc ErrorLoc); 123 124 // Helper to actually emit an instruction to the MCStreamer. Also, when 125 // possible, compression of the instruction is performed. 126 void emitToStreamer(MCStreamer &S, const MCInst &Inst); 127 128 // Helper to emit a combination of LUI, ADDI(W), and SLLI instructions that 129 // synthesize the desired immedate value into the destination register. 130 void emitLoadImm(MCRegister DestReg, int64_t Value, MCStreamer &Out); 131 132 // Helper to emit a combination of AUIPC and SecondOpcode. Used to implement 133 // helpers such as emitLoadLocalAddress and emitLoadAddress. 134 void emitAuipcInstPair(MCOperand DestReg, MCOperand TmpReg, 135 const MCExpr *Symbol, RISCVMCExpr::VariantKind VKHi, 136 unsigned SecondOpcode, SMLoc IDLoc, MCStreamer &Out); 137 138 // Helper to emit pseudo instruction "lla" used in PC-rel addressing. 139 void emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 140 141 // Helper to emit pseudo instruction "lga" used in GOT-rel addressing. 142 void emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 143 144 // Helper to emit pseudo instruction "la" used in GOT/PC-rel addressing. 145 void emitLoadAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 146 147 // Helper to emit pseudo instruction "la.tls.ie" used in initial-exec TLS 148 // addressing. 149 void emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 150 151 // Helper to emit pseudo instruction "la.tls.gd" used in global-dynamic TLS 152 // addressing. 153 void emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 154 155 // Helper to emit pseudo load/store instruction with a symbol. 156 void emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode, SMLoc IDLoc, 157 MCStreamer &Out, bool HasTmpReg); 158 159 // Helper to emit pseudo sign/zero extend instruction. 160 void emitPseudoExtend(MCInst &Inst, bool SignExtend, int64_t Width, 161 SMLoc IDLoc, MCStreamer &Out); 162 163 // Helper to emit pseudo vmsge{u}.vx instruction. 164 void emitVMSGE(MCInst &Inst, unsigned Opcode, SMLoc IDLoc, MCStreamer &Out); 165 166 // Checks that a PseudoAddTPRel is using x4/tp in its second input operand. 167 // Enforcing this using a restricted register class for the second input 168 // operand of PseudoAddTPRel results in a poor diagnostic due to the fact 169 // 'add' is an overloaded mnemonic. 170 bool checkPseudoAddTPRel(MCInst &Inst, OperandVector &Operands); 171 172 // Checks that a PseudoTLSDESCCall is using x5/t0 in its output operand. 173 // Enforcing this using a restricted register class for the output 174 // operand of PseudoTLSDESCCall results in a poor diagnostic due to the fact 175 // 'jalr' is an overloaded mnemonic. 176 bool checkPseudoTLSDESCCall(MCInst &Inst, OperandVector &Operands); 177 178 // Check instruction constraints. 179 bool validateInstruction(MCInst &Inst, OperandVector &Operands); 180 181 /// Helper for processing MC instructions that have been successfully matched 182 /// by MatchAndEmitInstruction. Modifications to the emitted instructions, 183 /// like the expansion of pseudo instructions (e.g., "li"), can be performed 184 /// in this method. 185 bool processInstruction(MCInst &Inst, SMLoc IDLoc, OperandVector &Operands, 186 MCStreamer &Out); 187 188 // Auto-generated instruction matching functions 189 #define GET_ASSEMBLER_HEADER 190 #include "RISCVGenAsmMatcher.inc" 191 192 ParseStatus parseCSRSystemRegister(OperandVector &Operands); 193 ParseStatus parseFPImm(OperandVector &Operands); 194 ParseStatus parseImmediate(OperandVector &Operands); 195 ParseStatus parseRegister(OperandVector &Operands, bool AllowParens = false); 196 ParseStatus parseMemOpBaseReg(OperandVector &Operands); 197 ParseStatus parseZeroOffsetMemOp(OperandVector &Operands); 198 ParseStatus parseOperandWithModifier(OperandVector &Operands); 199 ParseStatus parseBareSymbol(OperandVector &Operands); 200 ParseStatus parseCallSymbol(OperandVector &Operands); 201 ParseStatus parsePseudoJumpSymbol(OperandVector &Operands); 202 ParseStatus parseJALOffset(OperandVector &Operands); 203 ParseStatus parseVTypeI(OperandVector &Operands); 204 ParseStatus parseMaskReg(OperandVector &Operands); 205 ParseStatus parseInsnDirectiveOpcode(OperandVector &Operands); 206 ParseStatus parseInsnCDirectiveOpcode(OperandVector &Operands); 207 ParseStatus parseGPRAsFPR(OperandVector &Operands); 208 template <bool IsRV64Inst> ParseStatus parseGPRPair(OperandVector &Operands); 209 ParseStatus parseGPRPair(OperandVector &Operands, bool IsRV64Inst); 210 ParseStatus parseFRMArg(OperandVector &Operands); 211 ParseStatus parseFenceArg(OperandVector &Operands); 212 ParseStatus parseReglist(OperandVector &Operands); 213 ParseStatus parseRegReg(OperandVector &Operands); 214 ParseStatus parseRetval(OperandVector &Operands); 215 ParseStatus parseZcmpSpimm(OperandVector &Operands); 216 217 bool parseOperand(OperandVector &Operands, StringRef Mnemonic); 218 219 bool parseDirectiveOption(); 220 bool parseDirectiveAttribute(); 221 bool parseDirectiveInsn(SMLoc L); 222 bool parseDirectiveVariantCC(); 223 224 /// Helper to reset target features for a new arch string. It 225 /// also records the new arch string that is expanded by RISCVISAInfo 226 /// and reports error for invalid arch string. 227 bool resetToArch(StringRef Arch, SMLoc Loc, std::string &Result, 228 bool FromOptionDirective); 229 230 void setFeatureBits(uint64_t Feature, StringRef FeatureString) { 231 if (!(getSTI().hasFeature(Feature))) { 232 MCSubtargetInfo &STI = copySTI(); 233 setAvailableFeatures( 234 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); 235 } 236 } 237 238 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) { 239 if (getSTI().hasFeature(Feature)) { 240 MCSubtargetInfo &STI = copySTI(); 241 setAvailableFeatures( 242 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); 243 } 244 } 245 246 void pushFeatureBits() { 247 assert(FeatureBitStack.size() == ParserOptionsStack.size() && 248 "These two stacks must be kept synchronized"); 249 FeatureBitStack.push_back(getSTI().getFeatureBits()); 250 ParserOptionsStack.push_back(ParserOptions); 251 } 252 253 bool popFeatureBits() { 254 assert(FeatureBitStack.size() == ParserOptionsStack.size() && 255 "These two stacks must be kept synchronized"); 256 if (FeatureBitStack.empty()) 257 return true; 258 259 FeatureBitset FeatureBits = FeatureBitStack.pop_back_val(); 260 copySTI().setFeatureBits(FeatureBits); 261 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits)); 262 263 ParserOptions = ParserOptionsStack.pop_back_val(); 264 265 return false; 266 } 267 268 std::unique_ptr<RISCVOperand> defaultMaskRegOp() const; 269 std::unique_ptr<RISCVOperand> defaultFRMArgOp() const; 270 std::unique_ptr<RISCVOperand> defaultFRMArgLegacyOp() const; 271 272 public: 273 enum RISCVMatchResultTy { 274 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY, 275 Match_RequiresEvenGPRs, 276 #define GET_OPERAND_DIAGNOSTIC_TYPES 277 #include "RISCVGenAsmMatcher.inc" 278 #undef GET_OPERAND_DIAGNOSTIC_TYPES 279 }; 280 281 static bool classifySymbolRef(const MCExpr *Expr, 282 RISCVMCExpr::VariantKind &Kind); 283 static bool isSymbolDiff(const MCExpr *Expr); 284 285 RISCVAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, 286 const MCInstrInfo &MII, const MCTargetOptions &Options) 287 : MCTargetAsmParser(Options, STI, MII) { 288 MCAsmParserExtension::Initialize(Parser); 289 290 Parser.addAliasForDirective(".half", ".2byte"); 291 Parser.addAliasForDirective(".hword", ".2byte"); 292 Parser.addAliasForDirective(".word", ".4byte"); 293 Parser.addAliasForDirective(".dword", ".8byte"); 294 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 295 296 auto ABIName = StringRef(Options.ABIName); 297 if (ABIName.ends_with("f") && !getSTI().hasFeature(RISCV::FeatureStdExtF)) { 298 errs() << "Hard-float 'f' ABI can't be used for a target that " 299 "doesn't support the F instruction set extension (ignoring " 300 "target-abi)\n"; 301 } else if (ABIName.ends_with("d") && 302 !getSTI().hasFeature(RISCV::FeatureStdExtD)) { 303 errs() << "Hard-float 'd' ABI can't be used for a target that " 304 "doesn't support the D instruction set extension (ignoring " 305 "target-abi)\n"; 306 } 307 308 // Use computeTargetABI to check if ABIName is valid. If invalid, output 309 // error message. 310 RISCVABI::computeTargetABI(STI.getTargetTriple(), STI.getFeatureBits(), 311 ABIName); 312 313 const MCObjectFileInfo *MOFI = Parser.getContext().getObjectFileInfo(); 314 ParserOptions.IsPicEnabled = MOFI->isPositionIndependent(); 315 316 if (AddBuildAttributes) 317 getTargetStreamer().emitTargetAttributes(STI, /*EmitStackAlign*/ false); 318 } 319 }; 320 321 /// RISCVOperand - Instances of this class represent a parsed machine 322 /// instruction 323 struct RISCVOperand final : public MCParsedAsmOperand { 324 325 enum class KindTy { 326 Token, 327 Register, 328 Immediate, 329 FPImmediate, 330 SystemRegister, 331 VType, 332 FRM, 333 Fence, 334 Rlist, 335 Spimm, 336 RegReg, 337 } Kind; 338 339 struct RegOp { 340 MCRegister RegNum; 341 bool IsGPRAsFPR; 342 }; 343 344 struct ImmOp { 345 const MCExpr *Val; 346 bool IsRV64; 347 }; 348 349 struct FPImmOp { 350 uint64_t Val; 351 }; 352 353 struct SysRegOp { 354 const char *Data; 355 unsigned Length; 356 unsigned Encoding; 357 // FIXME: Add the Encoding parsed fields as needed for checks, 358 // e.g.: read/write or user/supervisor/machine privileges. 359 }; 360 361 struct VTypeOp { 362 unsigned Val; 363 }; 364 365 struct FRMOp { 366 RISCVFPRndMode::RoundingMode FRM; 367 }; 368 369 struct FenceOp { 370 unsigned Val; 371 }; 372 373 struct RlistOp { 374 unsigned Val; 375 }; 376 377 struct SpimmOp { 378 unsigned Val; 379 }; 380 381 struct RegRegOp { 382 MCRegister Reg1; 383 MCRegister Reg2; 384 }; 385 386 SMLoc StartLoc, EndLoc; 387 union { 388 StringRef Tok; 389 RegOp Reg; 390 ImmOp Imm; 391 FPImmOp FPImm; 392 struct SysRegOp SysReg; 393 struct VTypeOp VType; 394 struct FRMOp FRM; 395 struct FenceOp Fence; 396 struct RlistOp Rlist; 397 struct SpimmOp Spimm; 398 struct RegRegOp RegReg; 399 }; 400 401 RISCVOperand(KindTy K) : Kind(K) {} 402 403 public: 404 RISCVOperand(const RISCVOperand &o) : MCParsedAsmOperand() { 405 Kind = o.Kind; 406 StartLoc = o.StartLoc; 407 EndLoc = o.EndLoc; 408 switch (Kind) { 409 case KindTy::Register: 410 Reg = o.Reg; 411 break; 412 case KindTy::Immediate: 413 Imm = o.Imm; 414 break; 415 case KindTy::FPImmediate: 416 FPImm = o.FPImm; 417 break; 418 case KindTy::Token: 419 Tok = o.Tok; 420 break; 421 case KindTy::SystemRegister: 422 SysReg = o.SysReg; 423 break; 424 case KindTy::VType: 425 VType = o.VType; 426 break; 427 case KindTy::FRM: 428 FRM = o.FRM; 429 break; 430 case KindTy::Fence: 431 Fence = o.Fence; 432 break; 433 case KindTy::Rlist: 434 Rlist = o.Rlist; 435 break; 436 case KindTy::Spimm: 437 Spimm = o.Spimm; 438 break; 439 case KindTy::RegReg: 440 RegReg = o.RegReg; 441 break; 442 } 443 } 444 445 bool isToken() const override { return Kind == KindTy::Token; } 446 bool isReg() const override { return Kind == KindTy::Register; } 447 bool isV0Reg() const { 448 return Kind == KindTy::Register && Reg.RegNum == RISCV::V0; 449 } 450 bool isAnyReg() const { 451 return Kind == KindTy::Register && 452 (RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(Reg.RegNum) || 453 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(Reg.RegNum) || 454 RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(Reg.RegNum)); 455 } 456 bool isAnyRegC() const { 457 return Kind == KindTy::Register && 458 (RISCVMCRegisterClasses[RISCV::GPRCRegClassID].contains( 459 Reg.RegNum) || 460 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains( 461 Reg.RegNum)); 462 } 463 bool isImm() const override { return Kind == KindTy::Immediate; } 464 bool isMem() const override { return false; } 465 bool isSystemRegister() const { return Kind == KindTy::SystemRegister; } 466 bool isRegReg() const { return Kind == KindTy::RegReg; } 467 bool isRlist() const { return Kind == KindTy::Rlist; } 468 bool isSpimm() const { return Kind == KindTy::Spimm; } 469 470 bool isGPR() const { 471 return Kind == KindTy::Register && 472 RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(Reg.RegNum); 473 } 474 475 bool isGPRAsFPR() const { return isGPR() && Reg.IsGPRAsFPR; } 476 477 bool isGPRPair() const { 478 return Kind == KindTy::Register && 479 RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].contains( 480 Reg.RegNum); 481 } 482 483 static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm, 484 RISCVMCExpr::VariantKind &VK) { 485 if (auto *RE = dyn_cast<RISCVMCExpr>(Expr)) { 486 VK = RE->getKind(); 487 return RE->evaluateAsConstant(Imm); 488 } 489 490 if (auto CE = dyn_cast<MCConstantExpr>(Expr)) { 491 VK = RISCVMCExpr::VK_RISCV_None; 492 Imm = CE->getValue(); 493 return true; 494 } 495 496 return false; 497 } 498 499 // True if operand is a symbol with no modifiers, or a constant with no 500 // modifiers and isShiftedInt<N-1, 1>(Op). 501 template <int N> bool isBareSimmNLsb0() const { 502 int64_t Imm; 503 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 504 if (!isImm()) 505 return false; 506 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 507 bool IsValid; 508 if (!IsConstantImm) 509 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK); 510 else 511 IsValid = isShiftedInt<N - 1, 1>(Imm); 512 return IsValid && VK == RISCVMCExpr::VK_RISCV_None; 513 } 514 515 // Predicate methods for AsmOperands defined in RISCVInstrInfo.td 516 517 bool isBareSymbol() const { 518 int64_t Imm; 519 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 520 // Must be of 'immediate' type but not a constant. 521 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK)) 522 return false; 523 return RISCVAsmParser::classifySymbolRef(getImm(), VK) && 524 VK == RISCVMCExpr::VK_RISCV_None; 525 } 526 527 bool isCallSymbol() const { 528 int64_t Imm; 529 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 530 // Must be of 'immediate' type but not a constant. 531 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK)) 532 return false; 533 return RISCVAsmParser::classifySymbolRef(getImm(), VK) && 534 (VK == RISCVMCExpr::VK_RISCV_CALL || 535 VK == RISCVMCExpr::VK_RISCV_CALL_PLT); 536 } 537 538 bool isPseudoJumpSymbol() const { 539 int64_t Imm; 540 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 541 // Must be of 'immediate' type but not a constant. 542 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK)) 543 return false; 544 return RISCVAsmParser::classifySymbolRef(getImm(), VK) && 545 VK == RISCVMCExpr::VK_RISCV_CALL; 546 } 547 548 bool isTPRelAddSymbol() const { 549 int64_t Imm; 550 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 551 // Must be of 'immediate' type but not a constant. 552 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK)) 553 return false; 554 return RISCVAsmParser::classifySymbolRef(getImm(), VK) && 555 VK == RISCVMCExpr::VK_RISCV_TPREL_ADD; 556 } 557 558 bool isTLSDESCCallSymbol() const { 559 int64_t Imm; 560 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 561 // Must be of 'immediate' type but not a constant. 562 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK)) 563 return false; 564 return RISCVAsmParser::classifySymbolRef(getImm(), VK) && 565 VK == RISCVMCExpr::VK_RISCV_TLSDESC_CALL; 566 } 567 568 bool isCSRSystemRegister() const { return isSystemRegister(); } 569 570 bool isVTypeImm(unsigned N) const { 571 int64_t Imm; 572 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 573 if (!isImm()) 574 return false; 575 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 576 return IsConstantImm && isUIntN(N, Imm) && VK == RISCVMCExpr::VK_RISCV_None; 577 } 578 579 // If the last operand of the vsetvli/vsetvli instruction is a constant 580 // expression, KindTy is Immediate. 581 bool isVTypeI10() const { 582 if (Kind == KindTy::Immediate) 583 return isVTypeImm(10); 584 return Kind == KindTy::VType; 585 } 586 bool isVTypeI11() const { 587 if (Kind == KindTy::Immediate) 588 return isVTypeImm(11); 589 return Kind == KindTy::VType; 590 } 591 592 /// Return true if the operand is a valid for the fence instruction e.g. 593 /// ('iorw'). 594 bool isFenceArg() const { return Kind == KindTy::Fence; } 595 596 /// Return true if the operand is a valid floating point rounding mode. 597 bool isFRMArg() const { return Kind == KindTy::FRM; } 598 bool isFRMArgLegacy() const { return Kind == KindTy::FRM; } 599 bool isRTZArg() const { return isFRMArg() && FRM.FRM == RISCVFPRndMode::RTZ; } 600 601 /// Return true if the operand is a valid fli.s floating-point immediate. 602 bool isLoadFPImm() const { 603 if (isImm()) 604 return isUImm5(); 605 if (Kind != KindTy::FPImmediate) 606 return false; 607 int Idx = RISCVLoadFPImm::getLoadFPImm( 608 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst()))); 609 // Don't allow decimal version of the minimum value. It is a different value 610 // for each supported data type. 611 return Idx >= 0 && Idx != 1; 612 } 613 614 bool isImmXLenLI() const { 615 int64_t Imm; 616 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 617 if (!isImm()) 618 return false; 619 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 620 if (VK == RISCVMCExpr::VK_RISCV_LO || 621 VK == RISCVMCExpr::VK_RISCV_PCREL_LO || 622 VK == RISCVMCExpr::VK_RISCV_TLSDESC_LOAD_LO || 623 VK == RISCVMCExpr::VK_RISCV_TLSDESC_ADD_LO) 624 return true; 625 // Given only Imm, ensuring that the actually specified constant is either 626 // a signed or unsigned 64-bit number is unfortunately impossible. 627 if (IsConstantImm) { 628 return VK == RISCVMCExpr::VK_RISCV_None && 629 (isRV64Imm() || (isInt<32>(Imm) || isUInt<32>(Imm))); 630 } 631 632 return RISCVAsmParser::isSymbolDiff(getImm()); 633 } 634 635 bool isImmXLenLI_Restricted() const { 636 int64_t Imm; 637 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 638 if (!isImm()) 639 return false; 640 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 641 // 'la imm' supports constant immediates only. 642 return IsConstantImm && (VK == RISCVMCExpr::VK_RISCV_None) && 643 (isRV64Imm() || (isInt<32>(Imm) || isUInt<32>(Imm))); 644 } 645 646 bool isUImmLog2XLen() const { 647 int64_t Imm; 648 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 649 if (!isImm()) 650 return false; 651 if (!evaluateConstantImm(getImm(), Imm, VK) || 652 VK != RISCVMCExpr::VK_RISCV_None) 653 return false; 654 return (isRV64Imm() && isUInt<6>(Imm)) || isUInt<5>(Imm); 655 } 656 657 bool isUImmLog2XLenNonZero() const { 658 int64_t Imm; 659 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 660 if (!isImm()) 661 return false; 662 if (!evaluateConstantImm(getImm(), Imm, VK) || 663 VK != RISCVMCExpr::VK_RISCV_None) 664 return false; 665 if (Imm == 0) 666 return false; 667 return (isRV64Imm() && isUInt<6>(Imm)) || isUInt<5>(Imm); 668 } 669 670 bool isUImmLog2XLenHalf() const { 671 int64_t Imm; 672 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 673 if (!isImm()) 674 return false; 675 if (!evaluateConstantImm(getImm(), Imm, VK) || 676 VK != RISCVMCExpr::VK_RISCV_None) 677 return false; 678 return (isRV64Imm() && isUInt<5>(Imm)) || isUInt<4>(Imm); 679 } 680 681 template <unsigned N> bool IsUImm() const { 682 int64_t Imm; 683 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 684 if (!isImm()) 685 return false; 686 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 687 return IsConstantImm && isUInt<N>(Imm) && VK == RISCVMCExpr::VK_RISCV_None; 688 } 689 690 bool isUImm1() const { return IsUImm<1>(); } 691 bool isUImm2() const { return IsUImm<2>(); } 692 bool isUImm3() const { return IsUImm<3>(); } 693 bool isUImm4() const { return IsUImm<4>(); } 694 bool isUImm5() const { return IsUImm<5>(); } 695 bool isUImm6() const { return IsUImm<6>(); } 696 bool isUImm7() const { return IsUImm<7>(); } 697 bool isUImm8() const { return IsUImm<8>(); } 698 bool isUImm20() const { return IsUImm<20>(); } 699 700 bool isUImm8GE32() const { 701 int64_t Imm; 702 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 703 if (!isImm()) 704 return false; 705 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 706 return IsConstantImm && isUInt<8>(Imm) && Imm >= 32 && 707 VK == RISCVMCExpr::VK_RISCV_None; 708 } 709 710 bool isRnumArg() const { 711 int64_t Imm; 712 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 713 if (!isImm()) 714 return false; 715 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 716 return IsConstantImm && Imm >= INT64_C(0) && Imm <= INT64_C(10) && 717 VK == RISCVMCExpr::VK_RISCV_None; 718 } 719 720 bool isRnumArg_0_7() const { 721 int64_t Imm; 722 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 723 if (!isImm()) 724 return false; 725 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 726 return IsConstantImm && Imm >= INT64_C(0) && Imm <= INT64_C(7) && 727 VK == RISCVMCExpr::VK_RISCV_None; 728 } 729 730 bool isRnumArg_1_10() const { 731 int64_t Imm; 732 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 733 if (!isImm()) 734 return false; 735 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 736 return IsConstantImm && Imm >= INT64_C(1) && Imm <= INT64_C(10) && 737 VK == RISCVMCExpr::VK_RISCV_None; 738 } 739 740 bool isRnumArg_2_14() const { 741 int64_t Imm; 742 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 743 if (!isImm()) 744 return false; 745 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 746 return IsConstantImm && Imm >= INT64_C(2) && Imm <= INT64_C(14) && 747 VK == RISCVMCExpr::VK_RISCV_None; 748 } 749 750 bool isSImm5() const { 751 if (!isImm()) 752 return false; 753 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 754 int64_t Imm; 755 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 756 return IsConstantImm && isInt<5>(fixImmediateForRV32(Imm, isRV64Imm())) && 757 VK == RISCVMCExpr::VK_RISCV_None; 758 } 759 760 bool isSImm6() const { 761 if (!isImm()) 762 return false; 763 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 764 int64_t Imm; 765 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 766 return IsConstantImm && isInt<6>(fixImmediateForRV32(Imm, isRV64Imm())) && 767 VK == RISCVMCExpr::VK_RISCV_None; 768 } 769 770 bool isSImm6NonZero() const { 771 if (!isImm()) 772 return false; 773 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 774 int64_t Imm; 775 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 776 return IsConstantImm && Imm != 0 && 777 isInt<6>(fixImmediateForRV32(Imm, isRV64Imm())) && 778 VK == RISCVMCExpr::VK_RISCV_None; 779 } 780 781 bool isCLUIImm() const { 782 if (!isImm()) 783 return false; 784 int64_t Imm; 785 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 786 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 787 return IsConstantImm && (Imm != 0) && 788 (isUInt<5>(Imm) || (Imm >= 0xfffe0 && Imm <= 0xfffff)) && 789 VK == RISCVMCExpr::VK_RISCV_None; 790 } 791 792 bool isUImm2Lsb0() const { 793 if (!isImm()) 794 return false; 795 int64_t Imm; 796 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 797 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 798 return IsConstantImm && isShiftedUInt<1, 1>(Imm) && 799 VK == RISCVMCExpr::VK_RISCV_None; 800 } 801 802 bool isUImm7Lsb00() const { 803 if (!isImm()) 804 return false; 805 int64_t Imm; 806 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 807 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 808 return IsConstantImm && isShiftedUInt<5, 2>(Imm) && 809 VK == RISCVMCExpr::VK_RISCV_None; 810 } 811 812 bool isUImm8Lsb00() const { 813 if (!isImm()) 814 return false; 815 int64_t Imm; 816 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 817 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 818 return IsConstantImm && isShiftedUInt<6, 2>(Imm) && 819 VK == RISCVMCExpr::VK_RISCV_None; 820 } 821 822 bool isUImm8Lsb000() const { 823 if (!isImm()) 824 return false; 825 int64_t Imm; 826 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 827 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 828 return IsConstantImm && isShiftedUInt<5, 3>(Imm) && 829 VK == RISCVMCExpr::VK_RISCV_None; 830 } 831 832 bool isSImm9Lsb0() const { return isBareSimmNLsb0<9>(); } 833 834 bool isUImm9Lsb000() const { 835 if (!isImm()) 836 return false; 837 int64_t Imm; 838 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 839 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 840 return IsConstantImm && isShiftedUInt<6, 3>(Imm) && 841 VK == RISCVMCExpr::VK_RISCV_None; 842 } 843 844 bool isUImm10Lsb00NonZero() const { 845 if (!isImm()) 846 return false; 847 int64_t Imm; 848 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 849 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 850 return IsConstantImm && isShiftedUInt<8, 2>(Imm) && (Imm != 0) && 851 VK == RISCVMCExpr::VK_RISCV_None; 852 } 853 854 // If this a RV32 and the immediate is a uimm32, sign extend it to 32 bits. 855 // This allows writing 'addi a0, a0, 0xffffffff'. 856 static int64_t fixImmediateForRV32(int64_t Imm, bool IsRV64Imm) { 857 if (IsRV64Imm || !isUInt<32>(Imm)) 858 return Imm; 859 return SignExtend64<32>(Imm); 860 } 861 862 bool isSImm12() const { 863 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 864 int64_t Imm; 865 bool IsValid; 866 if (!isImm()) 867 return false; 868 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 869 if (!IsConstantImm) 870 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK); 871 else 872 IsValid = isInt<12>(fixImmediateForRV32(Imm, isRV64Imm())); 873 return IsValid && ((IsConstantImm && VK == RISCVMCExpr::VK_RISCV_None) || 874 VK == RISCVMCExpr::VK_RISCV_LO || 875 VK == RISCVMCExpr::VK_RISCV_PCREL_LO || 876 VK == RISCVMCExpr::VK_RISCV_TPREL_LO || 877 VK == RISCVMCExpr::VK_RISCV_TLSDESC_LOAD_LO || 878 VK == RISCVMCExpr::VK_RISCV_TLSDESC_ADD_LO); 879 } 880 881 bool isSImm12Lsb0() const { return isBareSimmNLsb0<12>(); } 882 883 bool isSImm12Lsb00000() const { 884 if (!isImm()) 885 return false; 886 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 887 int64_t Imm; 888 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 889 return IsConstantImm && isShiftedInt<7, 5>(Imm) && 890 VK == RISCVMCExpr::VK_RISCV_None; 891 } 892 893 bool isSImm13Lsb0() const { return isBareSimmNLsb0<13>(); } 894 895 bool isSImm10Lsb0000NonZero() const { 896 if (!isImm()) 897 return false; 898 int64_t Imm; 899 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 900 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 901 return IsConstantImm && (Imm != 0) && isShiftedInt<6, 4>(Imm) && 902 VK == RISCVMCExpr::VK_RISCV_None; 903 } 904 905 bool isUImm20LUI() const { 906 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 907 int64_t Imm; 908 bool IsValid; 909 if (!isImm()) 910 return false; 911 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 912 if (!IsConstantImm) { 913 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK); 914 return IsValid && (VK == RISCVMCExpr::VK_RISCV_HI || 915 VK == RISCVMCExpr::VK_RISCV_TPREL_HI); 916 } else { 917 return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None || 918 VK == RISCVMCExpr::VK_RISCV_HI || 919 VK == RISCVMCExpr::VK_RISCV_TPREL_HI); 920 } 921 } 922 923 bool isUImm20AUIPC() const { 924 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 925 int64_t Imm; 926 bool IsValid; 927 if (!isImm()) 928 return false; 929 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 930 if (!IsConstantImm) { 931 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK); 932 return IsValid && (VK == RISCVMCExpr::VK_RISCV_PCREL_HI || 933 VK == RISCVMCExpr::VK_RISCV_GOT_HI || 934 VK == RISCVMCExpr::VK_RISCV_TLS_GOT_HI || 935 VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI || 936 VK == RISCVMCExpr::VK_RISCV_TLSDESC_HI); 937 } 938 939 return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None || 940 VK == RISCVMCExpr::VK_RISCV_PCREL_HI || 941 VK == RISCVMCExpr::VK_RISCV_GOT_HI || 942 VK == RISCVMCExpr::VK_RISCV_TLS_GOT_HI || 943 VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI || 944 VK == RISCVMCExpr::VK_RISCV_TLSDESC_HI); 945 } 946 947 bool isSImm21Lsb0JAL() const { return isBareSimmNLsb0<21>(); } 948 949 bool isImmZero() const { 950 if (!isImm()) 951 return false; 952 int64_t Imm; 953 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 954 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 955 return IsConstantImm && (Imm == 0) && VK == RISCVMCExpr::VK_RISCV_None; 956 } 957 958 bool isSImm5Plus1() const { 959 if (!isImm()) 960 return false; 961 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 962 int64_t Imm; 963 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 964 return IsConstantImm && 965 isInt<5>(fixImmediateForRV32(Imm, isRV64Imm()) - 1) && 966 VK == RISCVMCExpr::VK_RISCV_None; 967 } 968 969 /// getStartLoc - Gets location of the first token of this operand 970 SMLoc getStartLoc() const override { return StartLoc; } 971 /// getEndLoc - Gets location of the last token of this operand 972 SMLoc getEndLoc() const override { return EndLoc; } 973 /// True if this operand is for an RV64 instruction 974 bool isRV64Imm() const { 975 assert(Kind == KindTy::Immediate && "Invalid type access!"); 976 return Imm.IsRV64; 977 } 978 979 unsigned getReg() const override { 980 assert(Kind == KindTy::Register && "Invalid type access!"); 981 return Reg.RegNum.id(); 982 } 983 984 StringRef getSysReg() const { 985 assert(Kind == KindTy::SystemRegister && "Invalid type access!"); 986 return StringRef(SysReg.Data, SysReg.Length); 987 } 988 989 const MCExpr *getImm() const { 990 assert(Kind == KindTy::Immediate && "Invalid type access!"); 991 return Imm.Val; 992 } 993 994 uint64_t getFPConst() const { 995 assert(Kind == KindTy::FPImmediate && "Invalid type access!"); 996 return FPImm.Val; 997 } 998 999 StringRef getToken() const { 1000 assert(Kind == KindTy::Token && "Invalid type access!"); 1001 return Tok; 1002 } 1003 1004 unsigned getVType() const { 1005 assert(Kind == KindTy::VType && "Invalid type access!"); 1006 return VType.Val; 1007 } 1008 1009 RISCVFPRndMode::RoundingMode getFRM() const { 1010 assert(Kind == KindTy::FRM && "Invalid type access!"); 1011 return FRM.FRM; 1012 } 1013 1014 unsigned getFence() const { 1015 assert(Kind == KindTy::Fence && "Invalid type access!"); 1016 return Fence.Val; 1017 } 1018 1019 void print(raw_ostream &OS) const override { 1020 auto RegName = [](MCRegister Reg) { 1021 if (Reg) 1022 return RISCVInstPrinter::getRegisterName(Reg); 1023 else 1024 return "noreg"; 1025 }; 1026 1027 switch (Kind) { 1028 case KindTy::Immediate: 1029 OS << *getImm(); 1030 break; 1031 case KindTy::FPImmediate: 1032 break; 1033 case KindTy::Register: 1034 OS << "<register " << RegName(getReg()) << ">"; 1035 break; 1036 case KindTy::Token: 1037 OS << "'" << getToken() << "'"; 1038 break; 1039 case KindTy::SystemRegister: 1040 OS << "<sysreg: " << getSysReg() << '>'; 1041 break; 1042 case KindTy::VType: 1043 OS << "<vtype: "; 1044 RISCVVType::printVType(getVType(), OS); 1045 OS << '>'; 1046 break; 1047 case KindTy::FRM: 1048 OS << "<frm: "; 1049 roundingModeToString(getFRM()); 1050 OS << '>'; 1051 break; 1052 case KindTy::Fence: 1053 OS << "<fence: "; 1054 OS << getFence(); 1055 OS << '>'; 1056 break; 1057 case KindTy::Rlist: 1058 OS << "<rlist: "; 1059 RISCVZC::printRlist(Rlist.Val, OS); 1060 OS << '>'; 1061 break; 1062 case KindTy::Spimm: 1063 OS << "<Spimm: "; 1064 RISCVZC::printSpimm(Spimm.Val, OS); 1065 OS << '>'; 1066 break; 1067 case KindTy::RegReg: 1068 OS << "<RegReg: Reg1 " << RegName(RegReg.Reg1); 1069 OS << " Reg2 " << RegName(RegReg.Reg2); 1070 break; 1071 } 1072 } 1073 1074 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S) { 1075 auto Op = std::make_unique<RISCVOperand>(KindTy::Token); 1076 Op->Tok = Str; 1077 Op->StartLoc = S; 1078 Op->EndLoc = S; 1079 return Op; 1080 } 1081 1082 static std::unique_ptr<RISCVOperand> 1083 createReg(unsigned RegNo, SMLoc S, SMLoc E, bool IsGPRAsFPR = false) { 1084 auto Op = std::make_unique<RISCVOperand>(KindTy::Register); 1085 Op->Reg.RegNum = RegNo; 1086 Op->Reg.IsGPRAsFPR = IsGPRAsFPR; 1087 Op->StartLoc = S; 1088 Op->EndLoc = E; 1089 return Op; 1090 } 1091 1092 static std::unique_ptr<RISCVOperand> createImm(const MCExpr *Val, SMLoc S, 1093 SMLoc E, bool IsRV64) { 1094 auto Op = std::make_unique<RISCVOperand>(KindTy::Immediate); 1095 Op->Imm.Val = Val; 1096 Op->Imm.IsRV64 = IsRV64; 1097 Op->StartLoc = S; 1098 Op->EndLoc = E; 1099 return Op; 1100 } 1101 1102 static std::unique_ptr<RISCVOperand> createFPImm(uint64_t Val, SMLoc S) { 1103 auto Op = std::make_unique<RISCVOperand>(KindTy::FPImmediate); 1104 Op->FPImm.Val = Val; 1105 Op->StartLoc = S; 1106 Op->EndLoc = S; 1107 return Op; 1108 } 1109 1110 static std::unique_ptr<RISCVOperand> createSysReg(StringRef Str, SMLoc S, 1111 unsigned Encoding) { 1112 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister); 1113 Op->SysReg.Data = Str.data(); 1114 Op->SysReg.Length = Str.size(); 1115 Op->SysReg.Encoding = Encoding; 1116 Op->StartLoc = S; 1117 Op->EndLoc = S; 1118 return Op; 1119 } 1120 1121 static std::unique_ptr<RISCVOperand> 1122 createFRMArg(RISCVFPRndMode::RoundingMode FRM, SMLoc S) { 1123 auto Op = std::make_unique<RISCVOperand>(KindTy::FRM); 1124 Op->FRM.FRM = FRM; 1125 Op->StartLoc = S; 1126 Op->EndLoc = S; 1127 return Op; 1128 } 1129 1130 static std::unique_ptr<RISCVOperand> createFenceArg(unsigned Val, SMLoc S) { 1131 auto Op = std::make_unique<RISCVOperand>(KindTy::Fence); 1132 Op->Fence.Val = Val; 1133 Op->StartLoc = S; 1134 Op->EndLoc = S; 1135 return Op; 1136 } 1137 1138 static std::unique_ptr<RISCVOperand> createVType(unsigned VTypeI, SMLoc S) { 1139 auto Op = std::make_unique<RISCVOperand>(KindTy::VType); 1140 Op->VType.Val = VTypeI; 1141 Op->StartLoc = S; 1142 Op->EndLoc = S; 1143 return Op; 1144 } 1145 1146 static std::unique_ptr<RISCVOperand> createRlist(unsigned RlistEncode, 1147 SMLoc S) { 1148 auto Op = std::make_unique<RISCVOperand>(KindTy::Rlist); 1149 Op->Rlist.Val = RlistEncode; 1150 Op->StartLoc = S; 1151 return Op; 1152 } 1153 1154 static std::unique_ptr<RISCVOperand> createRegReg(unsigned Reg1No, 1155 unsigned Reg2No, SMLoc S) { 1156 auto Op = std::make_unique<RISCVOperand>(KindTy::RegReg); 1157 Op->RegReg.Reg1 = Reg1No; 1158 Op->RegReg.Reg2 = Reg2No; 1159 Op->StartLoc = S; 1160 Op->EndLoc = S; 1161 return Op; 1162 } 1163 1164 static std::unique_ptr<RISCVOperand> createSpimm(unsigned Spimm, SMLoc S) { 1165 auto Op = std::make_unique<RISCVOperand>(KindTy::Spimm); 1166 Op->Spimm.Val = Spimm; 1167 Op->StartLoc = S; 1168 return Op; 1169 } 1170 1171 static void addExpr(MCInst &Inst, const MCExpr *Expr, bool IsRV64Imm) { 1172 assert(Expr && "Expr shouldn't be null!"); 1173 int64_t Imm = 0; 1174 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 1175 bool IsConstant = evaluateConstantImm(Expr, Imm, VK); 1176 1177 if (IsConstant) 1178 Inst.addOperand( 1179 MCOperand::createImm(fixImmediateForRV32(Imm, IsRV64Imm))); 1180 else 1181 Inst.addOperand(MCOperand::createExpr(Expr)); 1182 } 1183 1184 // Used by the TableGen Code 1185 void addRegOperands(MCInst &Inst, unsigned N) const { 1186 assert(N == 1 && "Invalid number of operands!"); 1187 Inst.addOperand(MCOperand::createReg(getReg())); 1188 } 1189 1190 void addImmOperands(MCInst &Inst, unsigned N) const { 1191 assert(N == 1 && "Invalid number of operands!"); 1192 addExpr(Inst, getImm(), isRV64Imm()); 1193 } 1194 1195 void addFPImmOperands(MCInst &Inst, unsigned N) const { 1196 assert(N == 1 && "Invalid number of operands!"); 1197 if (isImm()) { 1198 addExpr(Inst, getImm(), isRV64Imm()); 1199 return; 1200 } 1201 1202 int Imm = RISCVLoadFPImm::getLoadFPImm( 1203 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst()))); 1204 Inst.addOperand(MCOperand::createImm(Imm)); 1205 } 1206 1207 void addFenceArgOperands(MCInst &Inst, unsigned N) const { 1208 assert(N == 1 && "Invalid number of operands!"); 1209 Inst.addOperand(MCOperand::createImm(Fence.Val)); 1210 } 1211 1212 void addCSRSystemRegisterOperands(MCInst &Inst, unsigned N) const { 1213 assert(N == 1 && "Invalid number of operands!"); 1214 Inst.addOperand(MCOperand::createImm(SysReg.Encoding)); 1215 } 1216 1217 // Support non-canonical syntax: 1218 // "vsetivli rd, uimm, 0xabc" or "vsetvli rd, rs1, 0xabc" 1219 // "vsetivli rd, uimm, (0xc << N)" or "vsetvli rd, rs1, (0xc << N)" 1220 void addVTypeIOperands(MCInst &Inst, unsigned N) const { 1221 assert(N == 1 && "Invalid number of operands!"); 1222 int64_t Imm = 0; 1223 if (Kind == KindTy::Immediate) { 1224 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 1225 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 1226 (void)IsConstantImm; 1227 assert(IsConstantImm && "Invalid VTypeI Operand!"); 1228 } else { 1229 Imm = getVType(); 1230 } 1231 Inst.addOperand(MCOperand::createImm(Imm)); 1232 } 1233 1234 void addRlistOperands(MCInst &Inst, unsigned N) const { 1235 assert(N == 1 && "Invalid number of operands!"); 1236 Inst.addOperand(MCOperand::createImm(Rlist.Val)); 1237 } 1238 1239 void addRegRegOperands(MCInst &Inst, unsigned N) const { 1240 assert(N == 1 && "Invalid number of operands!"); 1241 Inst.addOperand(MCOperand::createReg(RegReg.Reg1)); 1242 Inst.addOperand(MCOperand::createReg(RegReg.Reg2)); 1243 } 1244 1245 void addSpimmOperands(MCInst &Inst, unsigned N) const { 1246 assert(N == 1 && "Invalid number of operands!"); 1247 Inst.addOperand(MCOperand::createImm(Spimm.Val)); 1248 } 1249 1250 void addFRMArgOperands(MCInst &Inst, unsigned N) const { 1251 assert(N == 1 && "Invalid number of operands!"); 1252 Inst.addOperand(MCOperand::createImm(getFRM())); 1253 } 1254 }; 1255 } // end anonymous namespace. 1256 1257 #define GET_REGISTER_MATCHER 1258 #define GET_SUBTARGET_FEATURE_NAME 1259 #define GET_MATCHER_IMPLEMENTATION 1260 #define GET_MNEMONIC_SPELL_CHECKER 1261 #include "RISCVGenAsmMatcher.inc" 1262 1263 static MCRegister convertFPR64ToFPR16(MCRegister Reg) { 1264 assert(Reg >= RISCV::F0_D && Reg <= RISCV::F31_D && "Invalid register"); 1265 return Reg - RISCV::F0_D + RISCV::F0_H; 1266 } 1267 1268 static MCRegister convertFPR64ToFPR32(MCRegister Reg) { 1269 assert(Reg >= RISCV::F0_D && Reg <= RISCV::F31_D && "Invalid register"); 1270 return Reg - RISCV::F0_D + RISCV::F0_F; 1271 } 1272 1273 static MCRegister convertVRToVRMx(const MCRegisterInfo &RI, MCRegister Reg, 1274 unsigned Kind) { 1275 unsigned RegClassID; 1276 if (Kind == MCK_VRM2) 1277 RegClassID = RISCV::VRM2RegClassID; 1278 else if (Kind == MCK_VRM4) 1279 RegClassID = RISCV::VRM4RegClassID; 1280 else if (Kind == MCK_VRM8) 1281 RegClassID = RISCV::VRM8RegClassID; 1282 else 1283 return 0; 1284 return RI.getMatchingSuperReg(Reg, RISCV::sub_vrm1_0, 1285 &RISCVMCRegisterClasses[RegClassID]); 1286 } 1287 1288 unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp, 1289 unsigned Kind) { 1290 RISCVOperand &Op = static_cast<RISCVOperand &>(AsmOp); 1291 if (!Op.isReg()) 1292 return Match_InvalidOperand; 1293 1294 MCRegister Reg = Op.getReg(); 1295 bool IsRegFPR64 = 1296 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(Reg); 1297 bool IsRegFPR64C = 1298 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(Reg); 1299 bool IsRegVR = RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(Reg); 1300 1301 // As the parser couldn't differentiate an FPR32 from an FPR64, coerce the 1302 // register from FPR64 to FPR32 or FPR64C to FPR32C if necessary. 1303 if ((IsRegFPR64 && Kind == MCK_FPR32) || 1304 (IsRegFPR64C && Kind == MCK_FPR32C)) { 1305 Op.Reg.RegNum = convertFPR64ToFPR32(Reg); 1306 return Match_Success; 1307 } 1308 // As the parser couldn't differentiate an FPR16 from an FPR64, coerce the 1309 // register from FPR64 to FPR16 if necessary. 1310 if (IsRegFPR64 && Kind == MCK_FPR16) { 1311 Op.Reg.RegNum = convertFPR64ToFPR16(Reg); 1312 return Match_Success; 1313 } 1314 // As the parser couldn't differentiate an VRM2/VRM4/VRM8 from an VR, coerce 1315 // the register from VR to VRM2/VRM4/VRM8 if necessary. 1316 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) { 1317 Op.Reg.RegNum = convertVRToVRMx(*getContext().getRegisterInfo(), Reg, Kind); 1318 if (Op.Reg.RegNum == 0) 1319 return Match_InvalidOperand; 1320 return Match_Success; 1321 } 1322 return Match_InvalidOperand; 1323 } 1324 1325 unsigned RISCVAsmParser::checkTargetMatchPredicate(MCInst &Inst) { 1326 const MCInstrDesc &MCID = MII.get(Inst.getOpcode()); 1327 1328 for (unsigned I = 0; I < MCID.NumOperands; ++I) { 1329 if (MCID.operands()[I].RegClass == RISCV::GPRPairRegClassID) { 1330 const auto &Op = Inst.getOperand(I); 1331 assert(Op.isReg()); 1332 1333 MCRegister Reg = Op.getReg(); 1334 if (RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].contains(Reg)) 1335 continue; 1336 1337 // FIXME: We should form a paired register during parsing/matching. 1338 if (((Reg.id() - RISCV::X0) & 1) != 0) 1339 return Match_RequiresEvenGPRs; 1340 } 1341 } 1342 1343 return Match_Success; 1344 } 1345 1346 bool RISCVAsmParser::generateImmOutOfRangeError( 1347 SMLoc ErrorLoc, int64_t Lower, int64_t Upper, 1348 const Twine &Msg = "immediate must be an integer in the range") { 1349 return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]"); 1350 } 1351 1352 bool RISCVAsmParser::generateImmOutOfRangeError( 1353 OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper, 1354 const Twine &Msg = "immediate must be an integer in the range") { 1355 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1356 return generateImmOutOfRangeError(ErrorLoc, Lower, Upper, Msg); 1357 } 1358 1359 bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 1360 OperandVector &Operands, 1361 MCStreamer &Out, 1362 uint64_t &ErrorInfo, 1363 bool MatchingInlineAsm) { 1364 MCInst Inst; 1365 FeatureBitset MissingFeatures; 1366 1367 auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures, 1368 MatchingInlineAsm); 1369 switch (Result) { 1370 default: 1371 break; 1372 case Match_Success: 1373 if (validateInstruction(Inst, Operands)) 1374 return true; 1375 return processInstruction(Inst, IDLoc, Operands, Out); 1376 case Match_MissingFeature: { 1377 assert(MissingFeatures.any() && "Unknown missing features!"); 1378 bool FirstFeature = true; 1379 std::string Msg = "instruction requires the following:"; 1380 for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) { 1381 if (MissingFeatures[i]) { 1382 Msg += FirstFeature ? " " : ", "; 1383 Msg += getSubtargetFeatureName(i); 1384 FirstFeature = false; 1385 } 1386 } 1387 return Error(IDLoc, Msg); 1388 } 1389 case Match_MnemonicFail: { 1390 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits()); 1391 std::string Suggestion = RISCVMnemonicSpellCheck( 1392 ((RISCVOperand &)*Operands[0]).getToken(), FBS, 0); 1393 return Error(IDLoc, "unrecognized instruction mnemonic" + Suggestion); 1394 } 1395 case Match_InvalidOperand: { 1396 SMLoc ErrorLoc = IDLoc; 1397 if (ErrorInfo != ~0ULL) { 1398 if (ErrorInfo >= Operands.size()) 1399 return Error(ErrorLoc, "too few operands for instruction"); 1400 1401 ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1402 if (ErrorLoc == SMLoc()) 1403 ErrorLoc = IDLoc; 1404 } 1405 return Error(ErrorLoc, "invalid operand for instruction"); 1406 } 1407 } 1408 1409 // Handle the case when the error message is of specific type 1410 // other than the generic Match_InvalidOperand, and the 1411 // corresponding operand is missing. 1412 if (Result > FIRST_TARGET_MATCH_RESULT_TY) { 1413 SMLoc ErrorLoc = IDLoc; 1414 if (ErrorInfo != ~0ULL && ErrorInfo >= Operands.size()) 1415 return Error(ErrorLoc, "too few operands for instruction"); 1416 } 1417 1418 switch (Result) { 1419 default: 1420 break; 1421 case Match_RequiresEvenGPRs: 1422 return Error(IDLoc, 1423 "double precision floating point operands must use even " 1424 "numbered X register"); 1425 case Match_InvalidImmXLenLI: 1426 if (isRV64()) { 1427 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1428 return Error(ErrorLoc, "operand must be a constant 64-bit integer"); 1429 } 1430 return generateImmOutOfRangeError(Operands, ErrorInfo, 1431 std::numeric_limits<int32_t>::min(), 1432 std::numeric_limits<uint32_t>::max()); 1433 case Match_InvalidImmXLenLI_Restricted: 1434 if (isRV64()) { 1435 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1436 return Error(ErrorLoc, "operand either must be a constant 64-bit integer " 1437 "or a bare symbol name"); 1438 } 1439 return generateImmOutOfRangeError( 1440 Operands, ErrorInfo, std::numeric_limits<int32_t>::min(), 1441 std::numeric_limits<uint32_t>::max(), 1442 "operand either must be a bare symbol name or an immediate integer in " 1443 "the range"); 1444 case Match_InvalidImmZero: { 1445 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1446 return Error(ErrorLoc, "immediate must be zero"); 1447 } 1448 case Match_InvalidUImmLog2XLen: 1449 if (isRV64()) 1450 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1); 1451 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 1452 case Match_InvalidUImmLog2XLenNonZero: 1453 if (isRV64()) 1454 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1); 1455 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1); 1456 case Match_InvalidUImmLog2XLenHalf: 1457 if (isRV64()) 1458 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 1459 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1); 1460 case Match_InvalidUImm1: 1461 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 1) - 1); 1462 case Match_InvalidUImm2: 1463 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1); 1464 case Match_InvalidUImm2Lsb0: 1465 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 2, 1466 "immediate must be one of"); 1467 case Match_InvalidUImm3: 1468 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1); 1469 case Match_InvalidUImm4: 1470 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1); 1471 case Match_InvalidUImm5: 1472 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 1473 case Match_InvalidUImm6: 1474 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1); 1475 case Match_InvalidUImm7: 1476 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1); 1477 case Match_InvalidUImm8: 1478 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 8) - 1); 1479 case Match_InvalidUImm8GE32: 1480 return generateImmOutOfRangeError(Operands, ErrorInfo, 32, (1 << 8) - 1); 1481 case Match_InvalidSImm5: 1482 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4), 1483 (1 << 4) - 1); 1484 case Match_InvalidSImm6: 1485 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5), 1486 (1 << 5) - 1); 1487 case Match_InvalidSImm6NonZero: 1488 return generateImmOutOfRangeError( 1489 Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1, 1490 "immediate must be non-zero in the range"); 1491 case Match_InvalidCLUIImm: 1492 return generateImmOutOfRangeError( 1493 Operands, ErrorInfo, 1, (1 << 5) - 1, 1494 "immediate must be in [0xfffe0, 0xfffff] or"); 1495 case Match_InvalidUImm7Lsb00: 1496 return generateImmOutOfRangeError( 1497 Operands, ErrorInfo, 0, (1 << 7) - 4, 1498 "immediate must be a multiple of 4 bytes in the range"); 1499 case Match_InvalidUImm8Lsb00: 1500 return generateImmOutOfRangeError( 1501 Operands, ErrorInfo, 0, (1 << 8) - 4, 1502 "immediate must be a multiple of 4 bytes in the range"); 1503 case Match_InvalidUImm8Lsb000: 1504 return generateImmOutOfRangeError( 1505 Operands, ErrorInfo, 0, (1 << 8) - 8, 1506 "immediate must be a multiple of 8 bytes in the range"); 1507 case Match_InvalidSImm9Lsb0: 1508 return generateImmOutOfRangeError( 1509 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2, 1510 "immediate must be a multiple of 2 bytes in the range"); 1511 case Match_InvalidUImm9Lsb000: 1512 return generateImmOutOfRangeError( 1513 Operands, ErrorInfo, 0, (1 << 9) - 8, 1514 "immediate must be a multiple of 8 bytes in the range"); 1515 case Match_InvalidUImm10Lsb00NonZero: 1516 return generateImmOutOfRangeError( 1517 Operands, ErrorInfo, 4, (1 << 10) - 4, 1518 "immediate must be a multiple of 4 bytes in the range"); 1519 case Match_InvalidSImm10Lsb0000NonZero: 1520 return generateImmOutOfRangeError( 1521 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16, 1522 "immediate must be a multiple of 16 bytes and non-zero in the range"); 1523 case Match_InvalidSImm12: 1524 return generateImmOutOfRangeError( 1525 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1, 1526 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an " 1527 "integer in the range"); 1528 case Match_InvalidSImm12Lsb0: 1529 return generateImmOutOfRangeError( 1530 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2, 1531 "immediate must be a multiple of 2 bytes in the range"); 1532 case Match_InvalidSImm12Lsb00000: 1533 return generateImmOutOfRangeError( 1534 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 32, 1535 "immediate must be a multiple of 32 bytes in the range"); 1536 case Match_InvalidSImm13Lsb0: 1537 return generateImmOutOfRangeError( 1538 Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2, 1539 "immediate must be a multiple of 2 bytes in the range"); 1540 case Match_InvalidUImm20LUI: 1541 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1, 1542 "operand must be a symbol with " 1543 "%hi/%tprel_hi modifier or an integer in " 1544 "the range"); 1545 case Match_InvalidUImm20: 1546 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1); 1547 case Match_InvalidUImm20AUIPC: 1548 return generateImmOutOfRangeError( 1549 Operands, ErrorInfo, 0, (1 << 20) - 1, 1550 "operand must be a symbol with a " 1551 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or " 1552 "an integer in the range"); 1553 case Match_InvalidSImm21Lsb0JAL: 1554 return generateImmOutOfRangeError( 1555 Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2, 1556 "immediate must be a multiple of 2 bytes in the range"); 1557 case Match_InvalidCSRSystemRegister: { 1558 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1, 1559 "operand must be a valid system register " 1560 "name or an integer in the range"); 1561 } 1562 case Match_InvalidLoadFPImm: { 1563 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1564 return Error(ErrorLoc, "operand must be a valid floating-point constant"); 1565 } 1566 case Match_InvalidBareSymbol: { 1567 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1568 return Error(ErrorLoc, "operand must be a bare symbol name"); 1569 } 1570 case Match_InvalidPseudoJumpSymbol: { 1571 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1572 return Error(ErrorLoc, "operand must be a valid jump target"); 1573 } 1574 case Match_InvalidCallSymbol: { 1575 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1576 return Error(ErrorLoc, "operand must be a bare symbol name"); 1577 } 1578 case Match_InvalidTPRelAddSymbol: { 1579 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1580 return Error(ErrorLoc, "operand must be a symbol with %tprel_add modifier"); 1581 } 1582 case Match_InvalidTLSDESCCallSymbol: { 1583 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1584 return Error(ErrorLoc, 1585 "operand must be a symbol with %tlsdesc_call modifier"); 1586 } 1587 case Match_InvalidRTZArg: { 1588 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1589 return Error(ErrorLoc, "operand must be 'rtz' floating-point rounding mode"); 1590 } 1591 case Match_InvalidVTypeI: { 1592 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1593 return generateVTypeError(ErrorLoc); 1594 } 1595 case Match_InvalidVMaskRegister: { 1596 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1597 return Error(ErrorLoc, "operand must be v0.t"); 1598 } 1599 case Match_InvalidSImm5Plus1: { 1600 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4) + 1, 1601 (1 << 4), 1602 "immediate must be in the range"); 1603 } 1604 case Match_InvalidRlist: { 1605 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1606 return Error( 1607 ErrorLoc, 1608 "operand must be {ra [, s0[-sN]]} or {x1 [, x8[-x9][, x18[-xN]]]}"); 1609 } 1610 case Match_InvalidSpimm: { 1611 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1612 return Error( 1613 ErrorLoc, 1614 "stack adjustment is invalid for this instruction and register list; " 1615 "refer to Zc spec for a detailed range of stack adjustment"); 1616 } 1617 case Match_InvalidRnumArg: { 1618 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 10); 1619 } 1620 case Match_InvalidRegReg: { 1621 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1622 return Error(ErrorLoc, "operands must be register and register"); 1623 } 1624 } 1625 1626 llvm_unreachable("Unknown match type detected!"); 1627 } 1628 1629 // Attempts to match Name as a register (either using the default name or 1630 // alternative ABI names), setting RegNo to the matching register. Upon 1631 // failure, returns a non-valid MCRegister. If IsRVE, then registers x16-x31 1632 // will be rejected. 1633 static MCRegister matchRegisterNameHelper(bool IsRVE, StringRef Name) { 1634 MCRegister Reg = MatchRegisterName(Name); 1635 // The 16-/32- and 64-bit FPRs have the same asm name. Check that the initial 1636 // match always matches the 64-bit variant, and not the 16/32-bit one. 1637 assert(!(Reg >= RISCV::F0_H && Reg <= RISCV::F31_H)); 1638 assert(!(Reg >= RISCV::F0_F && Reg <= RISCV::F31_F)); 1639 // The default FPR register class is based on the tablegen enum ordering. 1640 static_assert(RISCV::F0_D < RISCV::F0_H, "FPR matching must be updated"); 1641 static_assert(RISCV::F0_D < RISCV::F0_F, "FPR matching must be updated"); 1642 if (!Reg) 1643 Reg = MatchRegisterAltName(Name); 1644 if (IsRVE && Reg >= RISCV::X16 && Reg <= RISCV::X31) 1645 Reg = RISCV::NoRegister; 1646 return Reg; 1647 } 1648 1649 bool RISCVAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc, 1650 SMLoc &EndLoc) { 1651 if (!tryParseRegister(Reg, StartLoc, EndLoc).isSuccess()) 1652 return Error(StartLoc, "invalid register name"); 1653 return false; 1654 } 1655 1656 ParseStatus RISCVAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, 1657 SMLoc &EndLoc) { 1658 const AsmToken &Tok = getParser().getTok(); 1659 StartLoc = Tok.getLoc(); 1660 EndLoc = Tok.getEndLoc(); 1661 StringRef Name = getLexer().getTok().getIdentifier(); 1662 1663 Reg = matchRegisterNameHelper(isRVE(), Name); 1664 if (!Reg) 1665 return ParseStatus::NoMatch; 1666 1667 getParser().Lex(); // Eat identifier token. 1668 return ParseStatus::Success; 1669 } 1670 1671 ParseStatus RISCVAsmParser::parseRegister(OperandVector &Operands, 1672 bool AllowParens) { 1673 SMLoc FirstS = getLoc(); 1674 bool HadParens = false; 1675 AsmToken LParen; 1676 1677 // If this is an LParen and a parenthesised register name is allowed, parse it 1678 // atomically. 1679 if (AllowParens && getLexer().is(AsmToken::LParen)) { 1680 AsmToken Buf[2]; 1681 size_t ReadCount = getLexer().peekTokens(Buf); 1682 if (ReadCount == 2 && Buf[1].getKind() == AsmToken::RParen) { 1683 HadParens = true; 1684 LParen = getParser().getTok(); 1685 getParser().Lex(); // Eat '(' 1686 } 1687 } 1688 1689 switch (getLexer().getKind()) { 1690 default: 1691 if (HadParens) 1692 getLexer().UnLex(LParen); 1693 return ParseStatus::NoMatch; 1694 case AsmToken::Identifier: 1695 StringRef Name = getLexer().getTok().getIdentifier(); 1696 MCRegister RegNo = matchRegisterNameHelper(isRVE(), Name); 1697 1698 if (!RegNo) { 1699 if (HadParens) 1700 getLexer().UnLex(LParen); 1701 return ParseStatus::NoMatch; 1702 } 1703 if (HadParens) 1704 Operands.push_back(RISCVOperand::createToken("(", FirstS)); 1705 SMLoc S = getLoc(); 1706 SMLoc E = SMLoc::getFromPointer(S.getPointer() + Name.size()); 1707 getLexer().Lex(); 1708 Operands.push_back(RISCVOperand::createReg(RegNo, S, E)); 1709 } 1710 1711 if (HadParens) { 1712 getParser().Lex(); // Eat ')' 1713 Operands.push_back(RISCVOperand::createToken(")", getLoc())); 1714 } 1715 1716 return ParseStatus::Success; 1717 } 1718 1719 ParseStatus RISCVAsmParser::parseInsnDirectiveOpcode(OperandVector &Operands) { 1720 SMLoc S = getLoc(); 1721 SMLoc E; 1722 const MCExpr *Res; 1723 1724 switch (getLexer().getKind()) { 1725 default: 1726 return ParseStatus::NoMatch; 1727 case AsmToken::LParen: 1728 case AsmToken::Minus: 1729 case AsmToken::Plus: 1730 case AsmToken::Exclaim: 1731 case AsmToken::Tilde: 1732 case AsmToken::Integer: 1733 case AsmToken::String: { 1734 if (getParser().parseExpression(Res, E)) 1735 return ParseStatus::Failure; 1736 1737 auto *CE = dyn_cast<MCConstantExpr>(Res); 1738 if (CE) { 1739 int64_t Imm = CE->getValue(); 1740 if (isUInt<7>(Imm)) { 1741 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1742 return ParseStatus::Success; 1743 } 1744 } 1745 1746 break; 1747 } 1748 case AsmToken::Identifier: { 1749 StringRef Identifier; 1750 if (getParser().parseIdentifier(Identifier)) 1751 return ParseStatus::Failure; 1752 1753 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier); 1754 if (Opcode) { 1755 assert(isUInt<7>(Opcode->Value) && (Opcode->Value & 0x3) == 3 && 1756 "Unexpected opcode"); 1757 Res = MCConstantExpr::create(Opcode->Value, getContext()); 1758 E = SMLoc::getFromPointer(S.getPointer() + Identifier.size()); 1759 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1760 return ParseStatus::Success; 1761 } 1762 1763 break; 1764 } 1765 case AsmToken::Percent: 1766 break; 1767 } 1768 1769 return generateImmOutOfRangeError( 1770 S, 0, 127, 1771 "opcode must be a valid opcode name or an immediate in the range"); 1772 } 1773 1774 ParseStatus RISCVAsmParser::parseInsnCDirectiveOpcode(OperandVector &Operands) { 1775 SMLoc S = getLoc(); 1776 SMLoc E; 1777 const MCExpr *Res; 1778 1779 switch (getLexer().getKind()) { 1780 default: 1781 return ParseStatus::NoMatch; 1782 case AsmToken::LParen: 1783 case AsmToken::Minus: 1784 case AsmToken::Plus: 1785 case AsmToken::Exclaim: 1786 case AsmToken::Tilde: 1787 case AsmToken::Integer: 1788 case AsmToken::String: { 1789 if (getParser().parseExpression(Res, E)) 1790 return ParseStatus::Failure; 1791 1792 auto *CE = dyn_cast<MCConstantExpr>(Res); 1793 if (CE) { 1794 int64_t Imm = CE->getValue(); 1795 if (Imm >= 0 && Imm <= 2) { 1796 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1797 return ParseStatus::Success; 1798 } 1799 } 1800 1801 break; 1802 } 1803 case AsmToken::Identifier: { 1804 StringRef Identifier; 1805 if (getParser().parseIdentifier(Identifier)) 1806 return ParseStatus::Failure; 1807 1808 unsigned Opcode; 1809 if (Identifier == "C0") 1810 Opcode = 0; 1811 else if (Identifier == "C1") 1812 Opcode = 1; 1813 else if (Identifier == "C2") 1814 Opcode = 2; 1815 else 1816 break; 1817 1818 Res = MCConstantExpr::create(Opcode, getContext()); 1819 E = SMLoc::getFromPointer(S.getPointer() + Identifier.size()); 1820 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1821 return ParseStatus::Success; 1822 } 1823 case AsmToken::Percent: { 1824 // Discard operand with modifier. 1825 break; 1826 } 1827 } 1828 1829 return generateImmOutOfRangeError( 1830 S, 0, 2, 1831 "opcode must be a valid opcode name or an immediate in the range"); 1832 } 1833 1834 ParseStatus RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) { 1835 SMLoc S = getLoc(); 1836 const MCExpr *Res; 1837 1838 switch (getLexer().getKind()) { 1839 default: 1840 return ParseStatus::NoMatch; 1841 case AsmToken::LParen: 1842 case AsmToken::Minus: 1843 case AsmToken::Plus: 1844 case AsmToken::Exclaim: 1845 case AsmToken::Tilde: 1846 case AsmToken::Integer: 1847 case AsmToken::String: { 1848 if (getParser().parseExpression(Res)) 1849 return ParseStatus::Failure; 1850 1851 auto *CE = dyn_cast<MCConstantExpr>(Res); 1852 if (CE) { 1853 int64_t Imm = CE->getValue(); 1854 if (isUInt<12>(Imm)) { 1855 auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm); 1856 // Accept an immediate representing a named or un-named Sys Reg 1857 // if the range is valid, regardless of the required features. 1858 Operands.push_back( 1859 RISCVOperand::createSysReg(SysReg ? SysReg->Name : "", S, Imm)); 1860 return ParseStatus::Success; 1861 } 1862 } 1863 1864 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1); 1865 } 1866 case AsmToken::Identifier: { 1867 StringRef Identifier; 1868 if (getParser().parseIdentifier(Identifier)) 1869 return ParseStatus::Failure; 1870 1871 auto SysReg = RISCVSysReg::lookupSysRegByName(Identifier); 1872 if (!SysReg) 1873 SysReg = RISCVSysReg::lookupSysRegByAltName(Identifier); 1874 if (!SysReg) 1875 if ((SysReg = RISCVSysReg::lookupSysRegByDeprecatedName(Identifier))) 1876 Warning(S, "'" + Identifier + "' is a deprecated alias for '" + 1877 SysReg->Name + "'"); 1878 1879 // Accept a named Sys Reg if the required features are present. 1880 if (SysReg) { 1881 if (!SysReg->haveRequiredFeatures(getSTI().getFeatureBits())) 1882 return Error(S, "system register use requires an option to be enabled"); 1883 Operands.push_back( 1884 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding)); 1885 return ParseStatus::Success; 1886 } 1887 1888 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1, 1889 "operand must be a valid system register " 1890 "name or an integer in the range"); 1891 } 1892 case AsmToken::Percent: { 1893 // Discard operand with modifier. 1894 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1); 1895 } 1896 } 1897 1898 return ParseStatus::NoMatch; 1899 } 1900 1901 ParseStatus RISCVAsmParser::parseFPImm(OperandVector &Operands) { 1902 SMLoc S = getLoc(); 1903 1904 // Parse special floats (inf/nan/min) representation. 1905 if (getTok().is(AsmToken::Identifier)) { 1906 StringRef Identifier = getTok().getIdentifier(); 1907 if (Identifier.compare_insensitive("inf") == 0) { 1908 Operands.push_back( 1909 RISCVOperand::createImm(MCConstantExpr::create(30, getContext()), S, 1910 getTok().getEndLoc(), isRV64())); 1911 } else if (Identifier.compare_insensitive("nan") == 0) { 1912 Operands.push_back( 1913 RISCVOperand::createImm(MCConstantExpr::create(31, getContext()), S, 1914 getTok().getEndLoc(), isRV64())); 1915 } else if (Identifier.compare_insensitive("min") == 0) { 1916 Operands.push_back( 1917 RISCVOperand::createImm(MCConstantExpr::create(1, getContext()), S, 1918 getTok().getEndLoc(), isRV64())); 1919 } else { 1920 return TokError("invalid floating point literal"); 1921 } 1922 1923 Lex(); // Eat the token. 1924 1925 return ParseStatus::Success; 1926 } 1927 1928 // Handle negation, as that still comes through as a separate token. 1929 bool IsNegative = parseOptionalToken(AsmToken::Minus); 1930 1931 const AsmToken &Tok = getTok(); 1932 if (!Tok.is(AsmToken::Real)) 1933 return TokError("invalid floating point immediate"); 1934 1935 // Parse FP representation. 1936 APFloat RealVal(APFloat::IEEEdouble()); 1937 auto StatusOrErr = 1938 RealVal.convertFromString(Tok.getString(), APFloat::rmTowardZero); 1939 if (errorToBool(StatusOrErr.takeError())) 1940 return TokError("invalid floating point representation"); 1941 1942 if (IsNegative) 1943 RealVal.changeSign(); 1944 1945 Operands.push_back(RISCVOperand::createFPImm( 1946 RealVal.bitcastToAPInt().getZExtValue(), S)); 1947 1948 Lex(); // Eat the token. 1949 1950 return ParseStatus::Success; 1951 } 1952 1953 ParseStatus RISCVAsmParser::parseImmediate(OperandVector &Operands) { 1954 SMLoc S = getLoc(); 1955 SMLoc E; 1956 const MCExpr *Res; 1957 1958 switch (getLexer().getKind()) { 1959 default: 1960 return ParseStatus::NoMatch; 1961 case AsmToken::LParen: 1962 case AsmToken::Dot: 1963 case AsmToken::Minus: 1964 case AsmToken::Plus: 1965 case AsmToken::Exclaim: 1966 case AsmToken::Tilde: 1967 case AsmToken::Integer: 1968 case AsmToken::String: 1969 case AsmToken::Identifier: 1970 if (getParser().parseExpression(Res, E)) 1971 return ParseStatus::Failure; 1972 break; 1973 case AsmToken::Percent: 1974 return parseOperandWithModifier(Operands); 1975 } 1976 1977 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1978 return ParseStatus::Success; 1979 } 1980 1981 ParseStatus RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) { 1982 SMLoc S = getLoc(); 1983 SMLoc E; 1984 1985 if (parseToken(AsmToken::Percent, "expected '%' for operand modifier")) 1986 return ParseStatus::Failure; 1987 1988 if (getLexer().getKind() != AsmToken::Identifier) 1989 return Error(getLoc(), "expected valid identifier for operand modifier"); 1990 StringRef Identifier = getParser().getTok().getIdentifier(); 1991 RISCVMCExpr::VariantKind VK = RISCVMCExpr::getVariantKindForName(Identifier); 1992 if (VK == RISCVMCExpr::VK_RISCV_Invalid) 1993 return Error(getLoc(), "unrecognized operand modifier"); 1994 1995 getParser().Lex(); // Eat the identifier 1996 if (parseToken(AsmToken::LParen, "expected '('")) 1997 return ParseStatus::Failure; 1998 1999 const MCExpr *SubExpr; 2000 if (getParser().parseParenExpression(SubExpr, E)) 2001 return ParseStatus::Failure; 2002 2003 const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, VK, getContext()); 2004 Operands.push_back(RISCVOperand::createImm(ModExpr, S, E, isRV64())); 2005 return ParseStatus::Success; 2006 } 2007 2008 ParseStatus RISCVAsmParser::parseBareSymbol(OperandVector &Operands) { 2009 SMLoc S = getLoc(); 2010 const MCExpr *Res; 2011 2012 if (getLexer().getKind() != AsmToken::Identifier) 2013 return ParseStatus::NoMatch; 2014 2015 StringRef Identifier; 2016 AsmToken Tok = getLexer().getTok(); 2017 2018 if (getParser().parseIdentifier(Identifier)) 2019 return ParseStatus::Failure; 2020 2021 SMLoc E = SMLoc::getFromPointer(S.getPointer() + Identifier.size()); 2022 2023 if (Identifier.consume_back("@plt")) 2024 return Error(getLoc(), "'@plt' operand not valid for instruction"); 2025 2026 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); 2027 2028 if (Sym->isVariable()) { 2029 const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false); 2030 if (!isa<MCSymbolRefExpr>(V)) { 2031 getLexer().UnLex(Tok); // Put back if it's not a bare symbol. 2032 return ParseStatus::NoMatch; 2033 } 2034 Res = V; 2035 } else 2036 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 2037 2038 MCBinaryExpr::Opcode Opcode; 2039 switch (getLexer().getKind()) { 2040 default: 2041 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 2042 return ParseStatus::Success; 2043 case AsmToken::Plus: 2044 Opcode = MCBinaryExpr::Add; 2045 getLexer().Lex(); 2046 break; 2047 case AsmToken::Minus: 2048 Opcode = MCBinaryExpr::Sub; 2049 getLexer().Lex(); 2050 break; 2051 } 2052 2053 const MCExpr *Expr; 2054 if (getParser().parseExpression(Expr, E)) 2055 return ParseStatus::Failure; 2056 Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext()); 2057 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 2058 return ParseStatus::Success; 2059 } 2060 2061 ParseStatus RISCVAsmParser::parseCallSymbol(OperandVector &Operands) { 2062 SMLoc S = getLoc(); 2063 const MCExpr *Res; 2064 2065 if (getLexer().getKind() != AsmToken::Identifier) 2066 return ParseStatus::NoMatch; 2067 2068 // Avoid parsing the register in `call rd, foo` as a call symbol. 2069 if (getLexer().peekTok().getKind() != AsmToken::EndOfStatement) 2070 return ParseStatus::NoMatch; 2071 2072 StringRef Identifier; 2073 if (getParser().parseIdentifier(Identifier)) 2074 return ParseStatus::Failure; 2075 2076 SMLoc E = SMLoc::getFromPointer(S.getPointer() + Identifier.size()); 2077 2078 RISCVMCExpr::VariantKind Kind = RISCVMCExpr::VK_RISCV_CALL_PLT; 2079 (void)Identifier.consume_back("@plt"); 2080 2081 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); 2082 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 2083 Res = RISCVMCExpr::create(Res, Kind, getContext()); 2084 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 2085 return ParseStatus::Success; 2086 } 2087 2088 ParseStatus RISCVAsmParser::parsePseudoJumpSymbol(OperandVector &Operands) { 2089 SMLoc S = getLoc(); 2090 SMLoc E; 2091 const MCExpr *Res; 2092 2093 if (getParser().parseExpression(Res, E)) 2094 return ParseStatus::Failure; 2095 2096 if (Res->getKind() != MCExpr::ExprKind::SymbolRef || 2097 cast<MCSymbolRefExpr>(Res)->getKind() == 2098 MCSymbolRefExpr::VariantKind::VK_PLT) 2099 return Error(S, "operand must be a valid jump target"); 2100 2101 Res = RISCVMCExpr::create(Res, RISCVMCExpr::VK_RISCV_CALL, getContext()); 2102 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 2103 return ParseStatus::Success; 2104 } 2105 2106 ParseStatus RISCVAsmParser::parseJALOffset(OperandVector &Operands) { 2107 // Parsing jal operands is fiddly due to the `jal foo` and `jal ra, foo` 2108 // both being acceptable forms. When parsing `jal ra, foo` this function 2109 // will be called for the `ra` register operand in an attempt to match the 2110 // single-operand alias. parseJALOffset must fail for this case. It would 2111 // seem logical to try parse the operand using parseImmediate and return 2112 // NoMatch if the next token is a comma (meaning we must be parsing a jal in 2113 // the second form rather than the first). We can't do this as there's no 2114 // way of rewinding the lexer state. Instead, return NoMatch if this operand 2115 // is an identifier and is followed by a comma. 2116 if (getLexer().is(AsmToken::Identifier) && 2117 getLexer().peekTok().is(AsmToken::Comma)) 2118 return ParseStatus::NoMatch; 2119 2120 return parseImmediate(Operands); 2121 } 2122 2123 bool RISCVAsmParser::parseVTypeToken(StringRef Identifier, VTypeState &State, 2124 unsigned &Sew, unsigned &Lmul, 2125 bool &Fractional, bool &TailAgnostic, 2126 bool &MaskAgnostic) { 2127 switch (State) { 2128 case VTypeState_SEW: 2129 if (!Identifier.consume_front("e")) 2130 break; 2131 if (Identifier.getAsInteger(10, Sew)) 2132 break; 2133 if (!RISCVVType::isValidSEW(Sew)) 2134 break; 2135 State = VTypeState_LMUL; 2136 return false; 2137 case VTypeState_LMUL: { 2138 if (!Identifier.consume_front("m")) 2139 break; 2140 Fractional = Identifier.consume_front("f"); 2141 if (Identifier.getAsInteger(10, Lmul)) 2142 break; 2143 if (!RISCVVType::isValidLMUL(Lmul, Fractional)) 2144 break; 2145 State = VTypeState_TailPolicy; 2146 return false; 2147 } 2148 case VTypeState_TailPolicy: 2149 if (Identifier == "ta") 2150 TailAgnostic = true; 2151 else if (Identifier == "tu") 2152 TailAgnostic = false; 2153 else 2154 break; 2155 State = VTypeState_MaskPolicy; 2156 return false; 2157 case VTypeState_MaskPolicy: 2158 if (Identifier == "ma") 2159 MaskAgnostic = true; 2160 else if (Identifier == "mu") 2161 MaskAgnostic = false; 2162 else 2163 break; 2164 State = VTypeState_Done; 2165 return false; 2166 case VTypeState_Done: 2167 // Extra token? 2168 break; 2169 } 2170 2171 return true; 2172 } 2173 2174 ParseStatus RISCVAsmParser::parseVTypeI(OperandVector &Operands) { 2175 SMLoc S = getLoc(); 2176 2177 unsigned Sew = 0; 2178 unsigned Lmul = 0; 2179 bool Fractional = false; 2180 bool TailAgnostic = false; 2181 bool MaskAgnostic = false; 2182 2183 VTypeState State = VTypeState_SEW; 2184 2185 if (getLexer().isNot(AsmToken::Identifier)) 2186 return ParseStatus::NoMatch; 2187 2188 StringRef Identifier = getTok().getIdentifier(); 2189 2190 if (parseVTypeToken(Identifier, State, Sew, Lmul, Fractional, TailAgnostic, 2191 MaskAgnostic)) 2192 return ParseStatus::NoMatch; 2193 2194 getLexer().Lex(); 2195 2196 while (parseOptionalToken(AsmToken::Comma)) { 2197 if (getLexer().isNot(AsmToken::Identifier)) 2198 break; 2199 2200 Identifier = getTok().getIdentifier(); 2201 2202 if (parseVTypeToken(Identifier, State, Sew, Lmul, Fractional, TailAgnostic, 2203 MaskAgnostic)) 2204 break; 2205 2206 getLexer().Lex(); 2207 } 2208 2209 if (getLexer().is(AsmToken::EndOfStatement) && State == VTypeState_Done) { 2210 RISCVII::VLMUL VLMUL = RISCVVType::encodeLMUL(Lmul, Fractional); 2211 2212 unsigned VTypeI = 2213 RISCVVType::encodeVTYPE(VLMUL, Sew, TailAgnostic, MaskAgnostic); 2214 Operands.push_back(RISCVOperand::createVType(VTypeI, S)); 2215 return ParseStatus::Success; 2216 } 2217 2218 return generateVTypeError(S); 2219 } 2220 2221 bool RISCVAsmParser::generateVTypeError(SMLoc ErrorLoc) { 2222 return Error( 2223 ErrorLoc, 2224 "operand must be " 2225 "e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]"); 2226 } 2227 2228 ParseStatus RISCVAsmParser::parseMaskReg(OperandVector &Operands) { 2229 if (getLexer().isNot(AsmToken::Identifier)) 2230 return ParseStatus::NoMatch; 2231 2232 StringRef Name = getLexer().getTok().getIdentifier(); 2233 if (!Name.consume_back(".t")) 2234 return Error(getLoc(), "expected '.t' suffix"); 2235 MCRegister RegNo = matchRegisterNameHelper(isRVE(), Name); 2236 2237 if (!RegNo) 2238 return ParseStatus::NoMatch; 2239 if (RegNo != RISCV::V0) 2240 return ParseStatus::NoMatch; 2241 SMLoc S = getLoc(); 2242 SMLoc E = SMLoc::getFromPointer(S.getPointer() + Name.size()); 2243 getLexer().Lex(); 2244 Operands.push_back(RISCVOperand::createReg(RegNo, S, E)); 2245 return ParseStatus::Success; 2246 } 2247 2248 ParseStatus RISCVAsmParser::parseGPRAsFPR(OperandVector &Operands) { 2249 if (getLexer().isNot(AsmToken::Identifier)) 2250 return ParseStatus::NoMatch; 2251 2252 StringRef Name = getLexer().getTok().getIdentifier(); 2253 MCRegister RegNo = matchRegisterNameHelper(isRVE(), Name); 2254 2255 if (!RegNo) 2256 return ParseStatus::NoMatch; 2257 SMLoc S = getLoc(); 2258 SMLoc E = SMLoc::getFromPointer(S.getPointer() + Name.size()); 2259 getLexer().Lex(); 2260 Operands.push_back(RISCVOperand::createReg( 2261 RegNo, S, E, !getSTI().hasFeature(RISCV::FeatureStdExtF))); 2262 return ParseStatus::Success; 2263 } 2264 2265 template <bool IsRV64> 2266 ParseStatus RISCVAsmParser::parseGPRPair(OperandVector &Operands) { 2267 return parseGPRPair(Operands, IsRV64); 2268 } 2269 2270 ParseStatus RISCVAsmParser::parseGPRPair(OperandVector &Operands, 2271 bool IsRV64Inst) { 2272 // If this is not an RV64 GPRPair instruction, don't parse as a GPRPair on 2273 // RV64 as it will prevent matching the RV64 version of the same instruction 2274 // that doesn't use a GPRPair. 2275 // If this is an RV64 GPRPair instruction, there is no RV32 version so we can 2276 // still parse as a pair. 2277 if (!IsRV64Inst && isRV64()) 2278 return ParseStatus::NoMatch; 2279 2280 if (getLexer().isNot(AsmToken::Identifier)) 2281 return ParseStatus::NoMatch; 2282 2283 StringRef Name = getLexer().getTok().getIdentifier(); 2284 MCRegister RegNo = matchRegisterNameHelper(isRVE(), Name); 2285 2286 if (!RegNo) 2287 return ParseStatus::NoMatch; 2288 2289 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(RegNo)) 2290 return ParseStatus::NoMatch; 2291 2292 if ((RegNo - RISCV::X0) & 1) 2293 return TokError("register must be even"); 2294 2295 SMLoc S = getLoc(); 2296 SMLoc E = SMLoc::getFromPointer(S.getPointer() + Name.size()); 2297 getLexer().Lex(); 2298 2299 const MCRegisterInfo *RI = getContext().getRegisterInfo(); 2300 unsigned Pair = RI->getMatchingSuperReg( 2301 RegNo, RISCV::sub_gpr_even, 2302 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]); 2303 Operands.push_back(RISCVOperand::createReg(Pair, S, E)); 2304 return ParseStatus::Success; 2305 } 2306 2307 ParseStatus RISCVAsmParser::parseFRMArg(OperandVector &Operands) { 2308 if (getLexer().isNot(AsmToken::Identifier)) 2309 return TokError( 2310 "operand must be a valid floating point rounding mode mnemonic"); 2311 2312 StringRef Str = getLexer().getTok().getIdentifier(); 2313 RISCVFPRndMode::RoundingMode FRM = RISCVFPRndMode::stringToRoundingMode(Str); 2314 2315 if (FRM == RISCVFPRndMode::Invalid) 2316 return TokError( 2317 "operand must be a valid floating point rounding mode mnemonic"); 2318 2319 Operands.push_back(RISCVOperand::createFRMArg(FRM, getLoc())); 2320 Lex(); // Eat identifier token. 2321 return ParseStatus::Success; 2322 } 2323 2324 ParseStatus RISCVAsmParser::parseFenceArg(OperandVector &Operands) { 2325 const AsmToken &Tok = getLexer().getTok(); 2326 2327 if (Tok.is(AsmToken::Integer)) { 2328 if (Tok.getIntVal() != 0) 2329 goto ParseFail; 2330 2331 Operands.push_back(RISCVOperand::createFenceArg(0, getLoc())); 2332 Lex(); 2333 return ParseStatus::Success; 2334 } 2335 2336 if (Tok.is(AsmToken::Identifier)) { 2337 StringRef Str = Tok.getIdentifier(); 2338 2339 // Letters must be unique, taken from 'iorw', and in ascending order. This 2340 // holds as long as each individual character is one of 'iorw' and is 2341 // greater than the previous character. 2342 unsigned Imm = 0; 2343 bool Valid = true; 2344 char Prev = '\0'; 2345 for (char c : Str) { 2346 switch (c) { 2347 default: 2348 Valid = false; 2349 break; 2350 case 'i': 2351 Imm |= RISCVFenceField::I; 2352 break; 2353 case 'o': 2354 Imm |= RISCVFenceField::O; 2355 break; 2356 case 'r': 2357 Imm |= RISCVFenceField::R; 2358 break; 2359 case 'w': 2360 Imm |= RISCVFenceField::W; 2361 break; 2362 } 2363 2364 if (c <= Prev) { 2365 Valid = false; 2366 break; 2367 } 2368 Prev = c; 2369 } 2370 2371 if (!Valid) 2372 goto ParseFail; 2373 2374 Operands.push_back(RISCVOperand::createFenceArg(Imm, getLoc())); 2375 Lex(); 2376 return ParseStatus::Success; 2377 } 2378 2379 ParseFail: 2380 return TokError("operand must be formed of letters selected in-order from " 2381 "'iorw' or be 0"); 2382 } 2383 2384 ParseStatus RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) { 2385 if (parseToken(AsmToken::LParen, "expected '('")) 2386 return ParseStatus::Failure; 2387 Operands.push_back(RISCVOperand::createToken("(", getLoc())); 2388 2389 if (!parseRegister(Operands).isSuccess()) 2390 return Error(getLoc(), "expected register"); 2391 2392 if (parseToken(AsmToken::RParen, "expected ')'")) 2393 return ParseStatus::Failure; 2394 Operands.push_back(RISCVOperand::createToken(")", getLoc())); 2395 2396 return ParseStatus::Success; 2397 } 2398 2399 ParseStatus RISCVAsmParser::parseZeroOffsetMemOp(OperandVector &Operands) { 2400 // Atomic operations such as lr.w, sc.w, and amo*.w accept a "memory operand" 2401 // as one of their register operands, such as `(a0)`. This just denotes that 2402 // the register (in this case `a0`) contains a memory address. 2403 // 2404 // Normally, we would be able to parse these by putting the parens into the 2405 // instruction string. However, GNU as also accepts a zero-offset memory 2406 // operand (such as `0(a0)`), and ignores the 0. Normally this would be parsed 2407 // with parseImmediate followed by parseMemOpBaseReg, but these instructions 2408 // do not accept an immediate operand, and we do not want to add a "dummy" 2409 // operand that is silently dropped. 2410 // 2411 // Instead, we use this custom parser. This will: allow (and discard) an 2412 // offset if it is zero; require (and discard) parentheses; and add only the 2413 // parsed register operand to `Operands`. 2414 // 2415 // These operands are printed with RISCVInstPrinter::printZeroOffsetMemOp, 2416 // which will only print the register surrounded by parentheses (which GNU as 2417 // also uses as its canonical representation for these operands). 2418 std::unique_ptr<RISCVOperand> OptionalImmOp; 2419 2420 if (getLexer().isNot(AsmToken::LParen)) { 2421 // Parse an Integer token. We do not accept arbritrary constant expressions 2422 // in the offset field (because they may include parens, which complicates 2423 // parsing a lot). 2424 int64_t ImmVal; 2425 SMLoc ImmStart = getLoc(); 2426 if (getParser().parseIntToken(ImmVal, 2427 "expected '(' or optional integer offset")) 2428 return ParseStatus::Failure; 2429 2430 // Create a RISCVOperand for checking later (so the error messages are 2431 // nicer), but we don't add it to Operands. 2432 SMLoc ImmEnd = getLoc(); 2433 OptionalImmOp = 2434 RISCVOperand::createImm(MCConstantExpr::create(ImmVal, getContext()), 2435 ImmStart, ImmEnd, isRV64()); 2436 } 2437 2438 if (parseToken(AsmToken::LParen, 2439 OptionalImmOp ? "expected '(' after optional integer offset" 2440 : "expected '(' or optional integer offset")) 2441 return ParseStatus::Failure; 2442 2443 if (!parseRegister(Operands).isSuccess()) 2444 return Error(getLoc(), "expected register"); 2445 2446 if (parseToken(AsmToken::RParen, "expected ')'")) 2447 return ParseStatus::Failure; 2448 2449 // Deferred Handling of non-zero offsets. This makes the error messages nicer. 2450 if (OptionalImmOp && !OptionalImmOp->isImmZero()) 2451 return Error( 2452 OptionalImmOp->getStartLoc(), "optional integer offset must be 0", 2453 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc())); 2454 2455 return ParseStatus::Success; 2456 } 2457 2458 ParseStatus RISCVAsmParser::parseRegReg(OperandVector &Operands) { 2459 // RR : a2(a1) 2460 if (getLexer().getKind() != AsmToken::Identifier) 2461 return ParseStatus::NoMatch; 2462 2463 StringRef RegName = getLexer().getTok().getIdentifier(); 2464 MCRegister Reg = matchRegisterNameHelper(isRVE(), RegName); 2465 if (!Reg) 2466 return Error(getLoc(), "invalid register"); 2467 getLexer().Lex(); 2468 2469 if (parseToken(AsmToken::LParen, "expected '(' or invalid operand")) 2470 return ParseStatus::Failure; 2471 2472 if (getLexer().getKind() != AsmToken::Identifier) 2473 return Error(getLoc(), "expected register"); 2474 2475 StringRef Reg2Name = getLexer().getTok().getIdentifier(); 2476 MCRegister Reg2 = matchRegisterNameHelper(isRVE(), Reg2Name); 2477 if (!Reg2) 2478 return Error(getLoc(), "invalid register"); 2479 getLexer().Lex(); 2480 2481 if (parseToken(AsmToken::RParen, "expected ')'")) 2482 return ParseStatus::Failure; 2483 2484 Operands.push_back(RISCVOperand::createRegReg(Reg, Reg2, getLoc())); 2485 2486 return ParseStatus::Success; 2487 } 2488 2489 ParseStatus RISCVAsmParser::parseReglist(OperandVector &Operands) { 2490 // Rlist: {ra [, s0[-sN]]} 2491 // XRlist: {x1 [, x8[-x9][, x18[-xN]]]} 2492 SMLoc S = getLoc(); 2493 2494 if (parseToken(AsmToken::LCurly, "register list must start with '{'")) 2495 return ParseStatus::Failure; 2496 2497 bool IsEABI = isRVE(); 2498 2499 if (getLexer().isNot(AsmToken::Identifier)) 2500 return Error(getLoc(), "register list must start from 'ra' or 'x1'"); 2501 2502 StringRef RegName = getLexer().getTok().getIdentifier(); 2503 MCRegister RegStart = matchRegisterNameHelper(IsEABI, RegName); 2504 MCRegister RegEnd; 2505 if (RegStart != RISCV::X1) 2506 return Error(getLoc(), "register list must start from 'ra' or 'x1'"); 2507 getLexer().Lex(); 2508 2509 // parse case like ,s0 2510 if (parseOptionalToken(AsmToken::Comma)) { 2511 if (getLexer().isNot(AsmToken::Identifier)) 2512 return Error(getLoc(), "invalid register"); 2513 StringRef RegName = getLexer().getTok().getIdentifier(); 2514 RegStart = matchRegisterNameHelper(IsEABI, RegName); 2515 if (!RegStart) 2516 return Error(getLoc(), "invalid register"); 2517 if (RegStart != RISCV::X8) 2518 return Error(getLoc(), 2519 "continuous register list must start from 's0' or 'x8'"); 2520 getLexer().Lex(); // eat reg 2521 } 2522 2523 // parse case like -s1 2524 if (parseOptionalToken(AsmToken::Minus)) { 2525 StringRef EndName = getLexer().getTok().getIdentifier(); 2526 // FIXME: the register mapping and checks of EABI is wrong 2527 RegEnd = matchRegisterNameHelper(IsEABI, EndName); 2528 if (!RegEnd) 2529 return Error(getLoc(), "invalid register"); 2530 if (IsEABI && RegEnd != RISCV::X9) 2531 return Error(getLoc(), "contiguous register list of EABI can only be " 2532 "'s0-s1' or 'x8-x9' pair"); 2533 getLexer().Lex(); 2534 } 2535 2536 if (!IsEABI) { 2537 // parse extra part like ', x18[-x20]' for XRegList 2538 if (parseOptionalToken(AsmToken::Comma)) { 2539 if (RegEnd != RISCV::X9) 2540 return Error( 2541 getLoc(), 2542 "first contiguous registers pair of register list must be 'x8-x9'"); 2543 2544 // parse ', x18' for extra part 2545 if (getLexer().isNot(AsmToken::Identifier)) 2546 return Error(getLoc(), "invalid register"); 2547 StringRef EndName = getLexer().getTok().getIdentifier(); 2548 if (MatchRegisterName(EndName) != RISCV::X18) 2549 return Error(getLoc(), 2550 "second contiguous registers pair of register list " 2551 "must start from 'x18'"); 2552 getLexer().Lex(); 2553 2554 // parse '-x20' for extra part 2555 if (parseOptionalToken(AsmToken::Minus)) { 2556 if (getLexer().isNot(AsmToken::Identifier)) 2557 return Error(getLoc(), "invalid register"); 2558 EndName = getLexer().getTok().getIdentifier(); 2559 if (MatchRegisterName(EndName) == RISCV::NoRegister) 2560 return Error(getLoc(), "invalid register"); 2561 getLexer().Lex(); 2562 } 2563 RegEnd = MatchRegisterName(EndName); 2564 } 2565 } 2566 2567 if (RegEnd == RISCV::X26) 2568 return Error(getLoc(), "invalid register list, {ra, s0-s10} or {x1, x8-x9, " 2569 "x18-x26} is not supported"); 2570 2571 if (parseToken(AsmToken::RCurly, "register list must end with '}'")) 2572 return ParseStatus::Failure; 2573 2574 if (RegEnd == RISCV::NoRegister) 2575 RegEnd = RegStart; 2576 2577 auto Encode = RISCVZC::encodeRlist(RegEnd, IsEABI); 2578 if (Encode == 16) 2579 return Error(S, "invalid register list"); 2580 Operands.push_back(RISCVOperand::createRlist(Encode, S)); 2581 2582 return ParseStatus::Success; 2583 } 2584 2585 ParseStatus RISCVAsmParser::parseZcmpSpimm(OperandVector &Operands) { 2586 (void)parseOptionalToken(AsmToken::Minus); 2587 2588 SMLoc S = getLoc(); 2589 int64_t StackAdjustment = getLexer().getTok().getIntVal(); 2590 unsigned Spimm = 0; 2591 unsigned RlistVal = static_cast<RISCVOperand *>(Operands[1].get())->Rlist.Val; 2592 2593 bool IsEABI = isRVE(); 2594 if (!RISCVZC::getSpimm(RlistVal, Spimm, StackAdjustment, isRV64(), IsEABI)) 2595 return ParseStatus::NoMatch; 2596 Operands.push_back(RISCVOperand::createSpimm(Spimm << 4, S)); 2597 getLexer().Lex(); 2598 return ParseStatus::Success; 2599 } 2600 2601 /// Looks at a token type and creates the relevant operand from this 2602 /// information, adding to Operands. If operand was parsed, returns false, else 2603 /// true. 2604 bool RISCVAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { 2605 // Check if the current operand has a custom associated parser, if so, try to 2606 // custom parse the operand, or fallback to the general approach. 2607 ParseStatus Result = 2608 MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true); 2609 if (Result.isSuccess()) 2610 return false; 2611 if (Result.isFailure()) 2612 return true; 2613 2614 // Attempt to parse token as a register. 2615 if (parseRegister(Operands, true).isSuccess()) 2616 return false; 2617 2618 // Attempt to parse token as an immediate 2619 if (parseImmediate(Operands).isSuccess()) { 2620 // Parse memory base register if present 2621 if (getLexer().is(AsmToken::LParen)) 2622 return !parseMemOpBaseReg(Operands).isSuccess(); 2623 return false; 2624 } 2625 2626 // Finally we have exhausted all options and must declare defeat. 2627 Error(getLoc(), "unknown operand"); 2628 return true; 2629 } 2630 2631 bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info, 2632 StringRef Name, SMLoc NameLoc, 2633 OperandVector &Operands) { 2634 // Ensure that if the instruction occurs when relaxation is enabled, 2635 // relocations are forced for the file. Ideally this would be done when there 2636 // is enough information to reliably determine if the instruction itself may 2637 // cause relaxations. Unfortunately instruction processing stage occurs in the 2638 // same pass as relocation emission, so it's too late to set a 'sticky bit' 2639 // for the entire file. 2640 if (getSTI().hasFeature(RISCV::FeatureRelax)) { 2641 auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr(); 2642 if (Assembler != nullptr) { 2643 RISCVAsmBackend &MAB = 2644 static_cast<RISCVAsmBackend &>(Assembler->getBackend()); 2645 MAB.setForceRelocs(); 2646 } 2647 } 2648 2649 // First operand is token for instruction 2650 Operands.push_back(RISCVOperand::createToken(Name, NameLoc)); 2651 2652 // If there are no more operands, then finish 2653 if (getLexer().is(AsmToken::EndOfStatement)) { 2654 getParser().Lex(); // Consume the EndOfStatement. 2655 return false; 2656 } 2657 2658 // Parse first operand 2659 if (parseOperand(Operands, Name)) 2660 return true; 2661 2662 // Parse until end of statement, consuming commas between operands 2663 while (parseOptionalToken(AsmToken::Comma)) { 2664 // Parse next operand 2665 if (parseOperand(Operands, Name)) 2666 return true; 2667 } 2668 2669 if (getParser().parseEOL("unexpected token")) { 2670 getParser().eatToEndOfStatement(); 2671 return true; 2672 } 2673 return false; 2674 } 2675 2676 bool RISCVAsmParser::classifySymbolRef(const MCExpr *Expr, 2677 RISCVMCExpr::VariantKind &Kind) { 2678 Kind = RISCVMCExpr::VK_RISCV_None; 2679 2680 if (const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) { 2681 Kind = RE->getKind(); 2682 Expr = RE->getSubExpr(); 2683 } 2684 2685 MCValue Res; 2686 MCFixup Fixup; 2687 if (Expr->evaluateAsRelocatable(Res, nullptr, &Fixup)) 2688 return Res.getRefKind() == RISCVMCExpr::VK_RISCV_None; 2689 return false; 2690 } 2691 2692 bool RISCVAsmParser::isSymbolDiff(const MCExpr *Expr) { 2693 MCValue Res; 2694 MCFixup Fixup; 2695 if (Expr->evaluateAsRelocatable(Res, nullptr, &Fixup)) { 2696 return Res.getRefKind() == RISCVMCExpr::VK_RISCV_None && Res.getSymA() && 2697 Res.getSymB(); 2698 } 2699 return false; 2700 } 2701 2702 ParseStatus RISCVAsmParser::parseDirective(AsmToken DirectiveID) { 2703 StringRef IDVal = DirectiveID.getString(); 2704 2705 if (IDVal == ".option") 2706 return parseDirectiveOption(); 2707 if (IDVal == ".attribute") 2708 return parseDirectiveAttribute(); 2709 if (IDVal == ".insn") 2710 return parseDirectiveInsn(DirectiveID.getLoc()); 2711 if (IDVal == ".variant_cc") 2712 return parseDirectiveVariantCC(); 2713 2714 return ParseStatus::NoMatch; 2715 } 2716 2717 bool RISCVAsmParser::resetToArch(StringRef Arch, SMLoc Loc, std::string &Result, 2718 bool FromOptionDirective) { 2719 for (auto Feature : RISCVFeatureKV) 2720 if (llvm::RISCVISAInfo::isSupportedExtensionFeature(Feature.Key)) 2721 clearFeatureBits(Feature.Value, Feature.Key); 2722 2723 auto ParseResult = llvm::RISCVISAInfo::parseArchString( 2724 Arch, /*EnableExperimentalExtension=*/true, 2725 /*ExperimentalExtensionVersionCheck=*/true); 2726 if (!ParseResult) { 2727 std::string Buffer; 2728 raw_string_ostream OutputErrMsg(Buffer); 2729 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) { 2730 OutputErrMsg << "invalid arch name '" << Arch << "', " 2731 << ErrMsg.getMessage(); 2732 }); 2733 2734 return Error(Loc, OutputErrMsg.str()); 2735 } 2736 auto &ISAInfo = *ParseResult; 2737 2738 for (auto Feature : RISCVFeatureKV) 2739 if (ISAInfo->hasExtension(Feature.Key)) 2740 setFeatureBits(Feature.Value, Feature.Key); 2741 2742 if (FromOptionDirective) { 2743 if (ISAInfo->getXLen() == 32 && isRV64()) 2744 return Error(Loc, "bad arch string switching from rv64 to rv32"); 2745 else if (ISAInfo->getXLen() == 64 && !isRV64()) 2746 return Error(Loc, "bad arch string switching from rv32 to rv64"); 2747 } 2748 2749 if (ISAInfo->getXLen() == 32) 2750 clearFeatureBits(RISCV::Feature64Bit, "64bit"); 2751 else if (ISAInfo->getXLen() == 64) 2752 setFeatureBits(RISCV::Feature64Bit, "64bit"); 2753 else 2754 return Error(Loc, "bad arch string " + Arch); 2755 2756 Result = ISAInfo->toString(); 2757 return false; 2758 } 2759 2760 bool RISCVAsmParser::parseDirectiveOption() { 2761 MCAsmParser &Parser = getParser(); 2762 // Get the option token. 2763 AsmToken Tok = Parser.getTok(); 2764 2765 // At the moment only identifiers are supported. 2766 if (parseToken(AsmToken::Identifier, "expected identifier")) 2767 return true; 2768 2769 StringRef Option = Tok.getIdentifier(); 2770 2771 if (Option == "push") { 2772 if (Parser.parseEOL()) 2773 return true; 2774 2775 getTargetStreamer().emitDirectiveOptionPush(); 2776 pushFeatureBits(); 2777 return false; 2778 } 2779 2780 if (Option == "pop") { 2781 SMLoc StartLoc = Parser.getTok().getLoc(); 2782 if (Parser.parseEOL()) 2783 return true; 2784 2785 getTargetStreamer().emitDirectiveOptionPop(); 2786 if (popFeatureBits()) 2787 return Error(StartLoc, ".option pop with no .option push"); 2788 2789 return false; 2790 } 2791 2792 if (Option == "arch") { 2793 SmallVector<RISCVOptionArchArg> Args; 2794 do { 2795 if (Parser.parseComma()) 2796 return true; 2797 2798 RISCVOptionArchArgType Type; 2799 if (parseOptionalToken(AsmToken::Plus)) 2800 Type = RISCVOptionArchArgType::Plus; 2801 else if (parseOptionalToken(AsmToken::Minus)) 2802 Type = RISCVOptionArchArgType::Minus; 2803 else if (!Args.empty()) 2804 return Error(Parser.getTok().getLoc(), 2805 "unexpected token, expected + or -"); 2806 else 2807 Type = RISCVOptionArchArgType::Full; 2808 2809 if (Parser.getTok().isNot(AsmToken::Identifier)) 2810 return Error(Parser.getTok().getLoc(), 2811 "unexpected token, expected identifier"); 2812 2813 StringRef Arch = Parser.getTok().getString(); 2814 SMLoc Loc = Parser.getTok().getLoc(); 2815 Parser.Lex(); 2816 2817 if (Type == RISCVOptionArchArgType::Full) { 2818 std::string Result; 2819 if (resetToArch(Arch, Loc, Result, true)) 2820 return true; 2821 2822 Args.emplace_back(Type, Result); 2823 break; 2824 } 2825 2826 ArrayRef<SubtargetFeatureKV> KVArray(RISCVFeatureKV); 2827 auto Ext = llvm::lower_bound(KVArray, Arch); 2828 if (Ext == KVArray.end() || StringRef(Ext->Key) != Arch || 2829 !RISCVISAInfo::isSupportedExtension(Arch)) { 2830 if (isDigit(Arch.back())) 2831 return Error( 2832 Loc, 2833 "Extension version number parsing not currently implemented"); 2834 return Error(Loc, "unknown extension feature"); 2835 } 2836 2837 Args.emplace_back(Type, Ext->Key); 2838 2839 if (Type == RISCVOptionArchArgType::Plus) { 2840 FeatureBitset OldFeatureBits = STI->getFeatureBits(); 2841 2842 setFeatureBits(Ext->Value, Ext->Key); 2843 auto ParseResult = RISCVFeatures::parseFeatureBits(isRV64(), STI->getFeatureBits()); 2844 if (!ParseResult) { 2845 copySTI().setFeatureBits(OldFeatureBits); 2846 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits)); 2847 2848 std::string Buffer; 2849 raw_string_ostream OutputErrMsg(Buffer); 2850 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) { 2851 OutputErrMsg << ErrMsg.getMessage(); 2852 }); 2853 2854 return Error(Loc, OutputErrMsg.str()); 2855 } 2856 } else { 2857 assert(Type == RISCVOptionArchArgType::Minus); 2858 // It is invalid to disable an extension that there are other enabled 2859 // extensions depend on it. 2860 // TODO: Make use of RISCVISAInfo to handle this 2861 for (auto Feature : KVArray) { 2862 if (getSTI().hasFeature(Feature.Value) && 2863 Feature.Implies.test(Ext->Value)) 2864 return Error(Loc, 2865 Twine("Can't disable ") + Ext->Key + " extension, " + 2866 Feature.Key + " extension requires " + Ext->Key + 2867 " extension be enabled"); 2868 } 2869 2870 clearFeatureBits(Ext->Value, Ext->Key); 2871 } 2872 } while (Parser.getTok().isNot(AsmToken::EndOfStatement)); 2873 2874 if (Parser.parseEOL()) 2875 return true; 2876 2877 getTargetStreamer().emitDirectiveOptionArch(Args); 2878 return false; 2879 } 2880 2881 if (Option == "rvc") { 2882 if (Parser.parseEOL()) 2883 return true; 2884 2885 getTargetStreamer().emitDirectiveOptionRVC(); 2886 setFeatureBits(RISCV::FeatureStdExtC, "c"); 2887 return false; 2888 } 2889 2890 if (Option == "norvc") { 2891 if (Parser.parseEOL()) 2892 return true; 2893 2894 getTargetStreamer().emitDirectiveOptionNoRVC(); 2895 clearFeatureBits(RISCV::FeatureStdExtC, "c"); 2896 clearFeatureBits(RISCV::FeatureStdExtZca, "+zca"); 2897 return false; 2898 } 2899 2900 if (Option == "pic") { 2901 if (Parser.parseEOL()) 2902 return true; 2903 2904 getTargetStreamer().emitDirectiveOptionPIC(); 2905 ParserOptions.IsPicEnabled = true; 2906 return false; 2907 } 2908 2909 if (Option == "nopic") { 2910 if (Parser.parseEOL()) 2911 return true; 2912 2913 getTargetStreamer().emitDirectiveOptionNoPIC(); 2914 ParserOptions.IsPicEnabled = false; 2915 return false; 2916 } 2917 2918 if (Option == "relax") { 2919 if (Parser.parseEOL()) 2920 return true; 2921 2922 getTargetStreamer().emitDirectiveOptionRelax(); 2923 setFeatureBits(RISCV::FeatureRelax, "relax"); 2924 return false; 2925 } 2926 2927 if (Option == "norelax") { 2928 if (Parser.parseEOL()) 2929 return true; 2930 2931 getTargetStreamer().emitDirectiveOptionNoRelax(); 2932 clearFeatureBits(RISCV::FeatureRelax, "relax"); 2933 return false; 2934 } 2935 2936 // Unknown option. 2937 Warning(Parser.getTok().getLoc(), "unknown option, expected 'push', 'pop', " 2938 "'rvc', 'norvc', 'arch', 'relax' or " 2939 "'norelax'"); 2940 Parser.eatToEndOfStatement(); 2941 return false; 2942 } 2943 2944 /// parseDirectiveAttribute 2945 /// ::= .attribute expression ',' ( expression | "string" ) 2946 /// ::= .attribute identifier ',' ( expression | "string" ) 2947 bool RISCVAsmParser::parseDirectiveAttribute() { 2948 MCAsmParser &Parser = getParser(); 2949 int64_t Tag; 2950 SMLoc TagLoc; 2951 TagLoc = Parser.getTok().getLoc(); 2952 if (Parser.getTok().is(AsmToken::Identifier)) { 2953 StringRef Name = Parser.getTok().getIdentifier(); 2954 std::optional<unsigned> Ret = 2955 ELFAttrs::attrTypeFromString(Name, RISCVAttrs::getRISCVAttributeTags()); 2956 if (!Ret) 2957 return Error(TagLoc, "attribute name not recognised: " + Name); 2958 Tag = *Ret; 2959 Parser.Lex(); 2960 } else { 2961 const MCExpr *AttrExpr; 2962 2963 TagLoc = Parser.getTok().getLoc(); 2964 if (Parser.parseExpression(AttrExpr)) 2965 return true; 2966 2967 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr); 2968 if (check(!CE, TagLoc, "expected numeric constant")) 2969 return true; 2970 2971 Tag = CE->getValue(); 2972 } 2973 2974 if (Parser.parseComma()) 2975 return true; 2976 2977 StringRef StringValue; 2978 int64_t IntegerValue = 0; 2979 bool IsIntegerValue = true; 2980 2981 // RISC-V attributes have a string value if the tag number is odd 2982 // and an integer value if the tag number is even. 2983 if (Tag % 2) 2984 IsIntegerValue = false; 2985 2986 SMLoc ValueExprLoc = Parser.getTok().getLoc(); 2987 if (IsIntegerValue) { 2988 const MCExpr *ValueExpr; 2989 if (Parser.parseExpression(ValueExpr)) 2990 return true; 2991 2992 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr); 2993 if (!CE) 2994 return Error(ValueExprLoc, "expected numeric constant"); 2995 IntegerValue = CE->getValue(); 2996 } else { 2997 if (Parser.getTok().isNot(AsmToken::String)) 2998 return Error(Parser.getTok().getLoc(), "expected string constant"); 2999 3000 StringValue = Parser.getTok().getStringContents(); 3001 Parser.Lex(); 3002 } 3003 3004 if (Parser.parseEOL()) 3005 return true; 3006 3007 if (IsIntegerValue) 3008 getTargetStreamer().emitAttribute(Tag, IntegerValue); 3009 else if (Tag != RISCVAttrs::ARCH) 3010 getTargetStreamer().emitTextAttribute(Tag, StringValue); 3011 else { 3012 std::string Result; 3013 if (resetToArch(StringValue, ValueExprLoc, Result, false)) 3014 return true; 3015 3016 // Then emit the arch string. 3017 getTargetStreamer().emitTextAttribute(Tag, Result); 3018 } 3019 3020 return false; 3021 } 3022 3023 bool isValidInsnFormat(StringRef Format, bool AllowC) { 3024 return StringSwitch<bool>(Format) 3025 .Cases("r", "r4", "i", "b", "sb", "u", "j", "uj", "s", true) 3026 .Cases("cr", "ci", "ciw", "css", "cl", "cs", "ca", "cb", "cj", AllowC) 3027 .Default(false); 3028 } 3029 3030 /// parseDirectiveInsn 3031 /// ::= .insn [ format encoding, (operands (, operands)*) ] 3032 bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) { 3033 MCAsmParser &Parser = getParser(); 3034 3035 // Expect instruction format as identifier. 3036 StringRef Format; 3037 SMLoc ErrorLoc = Parser.getTok().getLoc(); 3038 if (Parser.parseIdentifier(Format)) 3039 return Error(ErrorLoc, "expected instruction format"); 3040 3041 bool AllowC = getSTI().hasFeature(RISCV::FeatureStdExtC) || 3042 getSTI().hasFeature(RISCV::FeatureStdExtZca); 3043 if (!isValidInsnFormat(Format, AllowC)) 3044 return Error(ErrorLoc, "invalid instruction format"); 3045 3046 std::string FormatName = (".insn_" + Format).str(); 3047 3048 ParseInstructionInfo Info; 3049 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> Operands; 3050 3051 if (ParseInstruction(Info, FormatName, L, Operands)) 3052 return true; 3053 3054 unsigned Opcode; 3055 uint64_t ErrorInfo; 3056 return MatchAndEmitInstruction(L, Opcode, Operands, Parser.getStreamer(), 3057 ErrorInfo, 3058 /*MatchingInlineAsm=*/false); 3059 } 3060 3061 /// parseDirectiveVariantCC 3062 /// ::= .variant_cc symbol 3063 bool RISCVAsmParser::parseDirectiveVariantCC() { 3064 StringRef Name; 3065 if (getParser().parseIdentifier(Name)) 3066 return TokError("expected symbol name"); 3067 if (parseEOL()) 3068 return true; 3069 getTargetStreamer().emitDirectiveVariantCC( 3070 *getContext().getOrCreateSymbol(Name)); 3071 return false; 3072 } 3073 3074 void RISCVAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) { 3075 MCInst CInst; 3076 bool Res = RISCVRVC::compress(CInst, Inst, getSTI()); 3077 if (Res) 3078 ++RISCVNumInstrsCompressed; 3079 S.emitInstruction((Res ? CInst : Inst), getSTI()); 3080 } 3081 3082 void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t Value, 3083 MCStreamer &Out) { 3084 RISCVMatInt::InstSeq Seq = RISCVMatInt::generateInstSeq(Value, getSTI()); 3085 3086 MCRegister SrcReg = RISCV::X0; 3087 for (const RISCVMatInt::Inst &Inst : Seq) { 3088 switch (Inst.getOpndKind()) { 3089 case RISCVMatInt::Imm: 3090 emitToStreamer(Out, 3091 MCInstBuilder(Inst.getOpcode()).addReg(DestReg).addImm(Inst.getImm())); 3092 break; 3093 case RISCVMatInt::RegX0: 3094 emitToStreamer( 3095 Out, MCInstBuilder(Inst.getOpcode()).addReg(DestReg).addReg(SrcReg).addReg( 3096 RISCV::X0)); 3097 break; 3098 case RISCVMatInt::RegReg: 3099 emitToStreamer( 3100 Out, MCInstBuilder(Inst.getOpcode()).addReg(DestReg).addReg(SrcReg).addReg( 3101 SrcReg)); 3102 break; 3103 case RISCVMatInt::RegImm: 3104 emitToStreamer( 3105 Out, MCInstBuilder(Inst.getOpcode()).addReg(DestReg).addReg(SrcReg).addImm( 3106 Inst.getImm())); 3107 break; 3108 } 3109 3110 // Only the first instruction has X0 as its source. 3111 SrcReg = DestReg; 3112 } 3113 } 3114 3115 void RISCVAsmParser::emitAuipcInstPair(MCOperand DestReg, MCOperand TmpReg, 3116 const MCExpr *Symbol, 3117 RISCVMCExpr::VariantKind VKHi, 3118 unsigned SecondOpcode, SMLoc IDLoc, 3119 MCStreamer &Out) { 3120 // A pair of instructions for PC-relative addressing; expands to 3121 // TmpLabel: AUIPC TmpReg, VKHi(symbol) 3122 // OP DestReg, TmpReg, %pcrel_lo(TmpLabel) 3123 MCContext &Ctx = getContext(); 3124 3125 MCSymbol *TmpLabel = Ctx.createNamedTempSymbol("pcrel_hi"); 3126 Out.emitLabel(TmpLabel); 3127 3128 const RISCVMCExpr *SymbolHi = RISCVMCExpr::create(Symbol, VKHi, Ctx); 3129 emitToStreamer( 3130 Out, MCInstBuilder(RISCV::AUIPC).addOperand(TmpReg).addExpr(SymbolHi)); 3131 3132 const MCExpr *RefToLinkTmpLabel = 3133 RISCVMCExpr::create(MCSymbolRefExpr::create(TmpLabel, Ctx), 3134 RISCVMCExpr::VK_RISCV_PCREL_LO, Ctx); 3135 3136 emitToStreamer(Out, MCInstBuilder(SecondOpcode) 3137 .addOperand(DestReg) 3138 .addOperand(TmpReg) 3139 .addExpr(RefToLinkTmpLabel)); 3140 } 3141 3142 void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, 3143 MCStreamer &Out) { 3144 // The load local address pseudo-instruction "lla" is used in PC-relative 3145 // addressing of local symbols: 3146 // lla rdest, symbol 3147 // expands to 3148 // TmpLabel: AUIPC rdest, %pcrel_hi(symbol) 3149 // ADDI rdest, rdest, %pcrel_lo(TmpLabel) 3150 MCOperand DestReg = Inst.getOperand(0); 3151 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 3152 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI, 3153 RISCV::ADDI, IDLoc, Out); 3154 } 3155 3156 void RISCVAsmParser::emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc, 3157 MCStreamer &Out) { 3158 // The load global address pseudo-instruction "lga" is used in GOT-indirect 3159 // addressing of global symbols: 3160 // lga rdest, symbol 3161 // expands to 3162 // TmpLabel: AUIPC rdest, %got_pcrel_hi(symbol) 3163 // Lx rdest, %pcrel_lo(TmpLabel)(rdest) 3164 MCOperand DestReg = Inst.getOperand(0); 3165 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 3166 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW; 3167 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_GOT_HI, 3168 SecondOpcode, IDLoc, Out); 3169 } 3170 3171 void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc, 3172 MCStreamer &Out) { 3173 // The load address pseudo-instruction "la" is used in PC-relative and 3174 // GOT-indirect addressing of global symbols: 3175 // la rdest, symbol 3176 // is an alias for either (for non-PIC) 3177 // lla rdest, symbol 3178 // or (for PIC) 3179 // lga rdest, symbol 3180 if (ParserOptions.IsPicEnabled) 3181 emitLoadGlobalAddress(Inst, IDLoc, Out); 3182 else 3183 emitLoadLocalAddress(Inst, IDLoc, Out); 3184 } 3185 3186 void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc, 3187 MCStreamer &Out) { 3188 // The load TLS IE address pseudo-instruction "la.tls.ie" is used in 3189 // initial-exec TLS model addressing of global symbols: 3190 // la.tls.ie rdest, symbol 3191 // expands to 3192 // TmpLabel: AUIPC rdest, %tls_ie_pcrel_hi(symbol) 3193 // Lx rdest, %pcrel_lo(TmpLabel)(rdest) 3194 MCOperand DestReg = Inst.getOperand(0); 3195 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 3196 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW; 3197 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_TLS_GOT_HI, 3198 SecondOpcode, IDLoc, Out); 3199 } 3200 3201 void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, 3202 MCStreamer &Out) { 3203 // The load TLS GD address pseudo-instruction "la.tls.gd" is used in 3204 // global-dynamic TLS model addressing of global symbols: 3205 // la.tls.gd rdest, symbol 3206 // expands to 3207 // TmpLabel: AUIPC rdest, %tls_gd_pcrel_hi(symbol) 3208 // ADDI rdest, rdest, %pcrel_lo(TmpLabel) 3209 MCOperand DestReg = Inst.getOperand(0); 3210 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 3211 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_TLS_GD_HI, 3212 RISCV::ADDI, IDLoc, Out); 3213 } 3214 3215 void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode, 3216 SMLoc IDLoc, MCStreamer &Out, 3217 bool HasTmpReg) { 3218 // The load/store pseudo-instruction does a pc-relative load with 3219 // a symbol. 3220 // 3221 // The expansion looks like this 3222 // 3223 // TmpLabel: AUIPC tmp, %pcrel_hi(symbol) 3224 // [S|L]X rd, %pcrel_lo(TmpLabel)(tmp) 3225 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0; 3226 MCOperand DestReg = Inst.getOperand(DestRegOpIdx); 3227 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1; 3228 MCOperand TmpReg = Inst.getOperand(0); 3229 const MCExpr *Symbol = Inst.getOperand(SymbolOpIdx).getExpr(); 3230 emitAuipcInstPair(DestReg, TmpReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI, 3231 Opcode, IDLoc, Out); 3232 } 3233 3234 void RISCVAsmParser::emitPseudoExtend(MCInst &Inst, bool SignExtend, 3235 int64_t Width, SMLoc IDLoc, 3236 MCStreamer &Out) { 3237 // The sign/zero extend pseudo-instruction does two shifts, with the shift 3238 // amounts dependent on the XLEN. 3239 // 3240 // The expansion looks like this 3241 // 3242 // SLLI rd, rs, XLEN - Width 3243 // SR[A|R]I rd, rd, XLEN - Width 3244 MCOperand DestReg = Inst.getOperand(0); 3245 MCOperand SourceReg = Inst.getOperand(1); 3246 3247 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI; 3248 int64_t ShAmt = (isRV64() ? 64 : 32) - Width; 3249 3250 assert(ShAmt > 0 && "Shift amount must be non-zero."); 3251 3252 emitToStreamer(Out, MCInstBuilder(RISCV::SLLI) 3253 .addOperand(DestReg) 3254 .addOperand(SourceReg) 3255 .addImm(ShAmt)); 3256 3257 emitToStreamer(Out, MCInstBuilder(SecondOpcode) 3258 .addOperand(DestReg) 3259 .addOperand(DestReg) 3260 .addImm(ShAmt)); 3261 } 3262 3263 void RISCVAsmParser::emitVMSGE(MCInst &Inst, unsigned Opcode, SMLoc IDLoc, 3264 MCStreamer &Out) { 3265 if (Inst.getNumOperands() == 3) { 3266 // unmasked va >= x 3267 // 3268 // pseudoinstruction: vmsge{u}.vx vd, va, x 3269 // expansion: vmslt{u}.vx vd, va, x; vmnand.mm vd, vd, vd 3270 emitToStreamer(Out, MCInstBuilder(Opcode) 3271 .addOperand(Inst.getOperand(0)) 3272 .addOperand(Inst.getOperand(1)) 3273 .addOperand(Inst.getOperand(2)) 3274 .addReg(RISCV::NoRegister)); 3275 emitToStreamer(Out, MCInstBuilder(RISCV::VMNAND_MM) 3276 .addOperand(Inst.getOperand(0)) 3277 .addOperand(Inst.getOperand(0)) 3278 .addOperand(Inst.getOperand(0))); 3279 } else if (Inst.getNumOperands() == 4) { 3280 // masked va >= x, vd != v0 3281 // 3282 // pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t 3283 // expansion: vmslt{u}.vx vd, va, x, v0.t; vmxor.mm vd, vd, v0 3284 assert(Inst.getOperand(0).getReg() != RISCV::V0 && 3285 "The destination register should not be V0."); 3286 emitToStreamer(Out, MCInstBuilder(Opcode) 3287 .addOperand(Inst.getOperand(0)) 3288 .addOperand(Inst.getOperand(1)) 3289 .addOperand(Inst.getOperand(2)) 3290 .addOperand(Inst.getOperand(3))); 3291 emitToStreamer(Out, MCInstBuilder(RISCV::VMXOR_MM) 3292 .addOperand(Inst.getOperand(0)) 3293 .addOperand(Inst.getOperand(0)) 3294 .addReg(RISCV::V0)); 3295 } else if (Inst.getNumOperands() == 5 && 3296 Inst.getOperand(0).getReg() == RISCV::V0) { 3297 // masked va >= x, vd == v0 3298 // 3299 // pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t, vt 3300 // expansion: vmslt{u}.vx vt, va, x; vmandn.mm vd, vd, vt 3301 assert(Inst.getOperand(0).getReg() == RISCV::V0 && 3302 "The destination register should be V0."); 3303 assert(Inst.getOperand(1).getReg() != RISCV::V0 && 3304 "The temporary vector register should not be V0."); 3305 emitToStreamer(Out, MCInstBuilder(Opcode) 3306 .addOperand(Inst.getOperand(1)) 3307 .addOperand(Inst.getOperand(2)) 3308 .addOperand(Inst.getOperand(3)) 3309 .addReg(RISCV::NoRegister)); 3310 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM) 3311 .addOperand(Inst.getOperand(0)) 3312 .addOperand(Inst.getOperand(0)) 3313 .addOperand(Inst.getOperand(1))); 3314 } else if (Inst.getNumOperands() == 5) { 3315 // masked va >= x, any vd 3316 // 3317 // pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t, vt 3318 // expansion: vmslt{u}.vx vt, va, x; vmandn.mm vt, v0, vt; 3319 // vmandn.mm vd, vd, v0; vmor.mm vd, vt, vd 3320 assert(Inst.getOperand(1).getReg() != RISCV::V0 && 3321 "The temporary vector register should not be V0."); 3322 emitToStreamer(Out, MCInstBuilder(Opcode) 3323 .addOperand(Inst.getOperand(1)) 3324 .addOperand(Inst.getOperand(2)) 3325 .addOperand(Inst.getOperand(3)) 3326 .addReg(RISCV::NoRegister)); 3327 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM) 3328 .addOperand(Inst.getOperand(1)) 3329 .addReg(RISCV::V0) 3330 .addOperand(Inst.getOperand(1))); 3331 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM) 3332 .addOperand(Inst.getOperand(0)) 3333 .addOperand(Inst.getOperand(0)) 3334 .addReg(RISCV::V0)); 3335 emitToStreamer(Out, MCInstBuilder(RISCV::VMOR_MM) 3336 .addOperand(Inst.getOperand(0)) 3337 .addOperand(Inst.getOperand(1)) 3338 .addOperand(Inst.getOperand(0))); 3339 } 3340 } 3341 3342 bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst, 3343 OperandVector &Operands) { 3344 assert(Inst.getOpcode() == RISCV::PseudoAddTPRel && "Invalid instruction"); 3345 assert(Inst.getOperand(2).isReg() && "Unexpected second operand kind"); 3346 if (Inst.getOperand(2).getReg() != RISCV::X4) { 3347 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc(); 3348 return Error(ErrorLoc, "the second input operand must be tp/x4 when using " 3349 "%tprel_add modifier"); 3350 } 3351 3352 return false; 3353 } 3354 3355 bool RISCVAsmParser::checkPseudoTLSDESCCall(MCInst &Inst, 3356 OperandVector &Operands) { 3357 assert(Inst.getOpcode() == RISCV::PseudoTLSDESCCall && "Invalid instruction"); 3358 assert(Inst.getOperand(0).isReg() && "Unexpected operand kind"); 3359 if (Inst.getOperand(0).getReg() != RISCV::X5) { 3360 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc(); 3361 return Error(ErrorLoc, "the output operand must be t0/x5 when using " 3362 "%tlsdesc_call modifier"); 3363 } 3364 3365 return false; 3366 } 3367 3368 std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp() const { 3369 return RISCVOperand::createReg(RISCV::NoRegister, llvm::SMLoc(), 3370 llvm::SMLoc()); 3371 } 3372 3373 std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp() const { 3374 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN, 3375 llvm::SMLoc()); 3376 } 3377 3378 std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp() const { 3379 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE, 3380 llvm::SMLoc()); 3381 } 3382 3383 bool RISCVAsmParser::validateInstruction(MCInst &Inst, 3384 OperandVector &Operands) { 3385 unsigned Opcode = Inst.getOpcode(); 3386 3387 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T || 3388 Opcode == RISCV::PseudoVMSGE_VX_M_T) { 3389 unsigned DestReg = Inst.getOperand(0).getReg(); 3390 unsigned TempReg = Inst.getOperand(1).getReg(); 3391 if (DestReg == TempReg) { 3392 SMLoc Loc = Operands.back()->getStartLoc(); 3393 return Error(Loc, "The temporary vector register cannot be the same as " 3394 "the destination register."); 3395 } 3396 } 3397 3398 if (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_LWUD || 3399 Opcode == RISCV::TH_LWD) { 3400 unsigned Rd1 = Inst.getOperand(0).getReg(); 3401 unsigned Rd2 = Inst.getOperand(1).getReg(); 3402 unsigned Rs1 = Inst.getOperand(2).getReg(); 3403 // The encoding with rd1 == rd2 == rs1 is reserved for XTHead load pair. 3404 if (Rs1 == Rd1 && Rs1 == Rd2) { 3405 SMLoc Loc = Operands[1]->getStartLoc(); 3406 return Error(Loc, "The source register and destination registers " 3407 "cannot be equal."); 3408 } 3409 } 3410 3411 if (Opcode == RISCV::CM_MVSA01) { 3412 unsigned Rd1 = Inst.getOperand(0).getReg(); 3413 unsigned Rd2 = Inst.getOperand(1).getReg(); 3414 if (Rd1 == Rd2) { 3415 SMLoc Loc = Operands[1]->getStartLoc(); 3416 return Error(Loc, "'rs1' and 'rs2' must be different."); 3417 } 3418 } 3419 3420 bool IsTHeadMemPair32 = (Opcode == RISCV::TH_LWD || 3421 Opcode == RISCV::TH_LWUD || Opcode == RISCV::TH_SWD); 3422 bool IsTHeadMemPair64 = (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_SDD); 3423 // The last operand of XTHeadMemPair instructions must be constant 3 or 4 3424 // depending on the data width. 3425 if (IsTHeadMemPair32 && Inst.getOperand(4).getImm() != 3) { 3426 SMLoc Loc = Operands.back()->getStartLoc(); 3427 return Error(Loc, "Operand must be constant 3."); 3428 } else if (IsTHeadMemPair64 && Inst.getOperand(4).getImm() != 4) { 3429 SMLoc Loc = Operands.back()->getStartLoc(); 3430 return Error(Loc, "Operand must be constant 4."); 3431 } 3432 3433 const MCInstrDesc &MCID = MII.get(Opcode); 3434 if (!(MCID.TSFlags & RISCVII::ConstraintMask)) 3435 return false; 3436 3437 if (Opcode == RISCV::VC_V_XVW || Opcode == RISCV::VC_V_IVW || 3438 Opcode == RISCV::VC_V_FVW || Opcode == RISCV::VC_V_VVW) { 3439 // Operands Opcode, Dst, uimm, Dst, Rs2, Rs1 for VC_V_XVW. 3440 unsigned VCIXDst = Inst.getOperand(0).getReg(); 3441 SMLoc VCIXDstLoc = Operands[2]->getStartLoc(); 3442 if (MCID.TSFlags & RISCVII::VS1Constraint) { 3443 unsigned VCIXRs1 = Inst.getOperand(Inst.getNumOperands() - 1).getReg(); 3444 if (VCIXDst == VCIXRs1) 3445 return Error(VCIXDstLoc, "The destination vector register group cannot" 3446 " overlap the source vector register group."); 3447 } 3448 if (MCID.TSFlags & RISCVII::VS2Constraint) { 3449 unsigned VCIXRs2 = Inst.getOperand(Inst.getNumOperands() - 2).getReg(); 3450 if (VCIXDst == VCIXRs2) 3451 return Error(VCIXDstLoc, "The destination vector register group cannot" 3452 " overlap the source vector register group."); 3453 } 3454 return false; 3455 } 3456 3457 unsigned DestReg = Inst.getOperand(0).getReg(); 3458 unsigned Offset = 0; 3459 int TiedOp = MCID.getOperandConstraint(1, MCOI::TIED_TO); 3460 if (TiedOp == 0) 3461 Offset = 1; 3462 3463 // Operands[1] will be the first operand, DestReg. 3464 SMLoc Loc = Operands[1]->getStartLoc(); 3465 if (MCID.TSFlags & RISCVII::VS2Constraint) { 3466 unsigned CheckReg = Inst.getOperand(Offset + 1).getReg(); 3467 if (DestReg == CheckReg) 3468 return Error(Loc, "The destination vector register group cannot overlap" 3469 " the source vector register group."); 3470 } 3471 if ((MCID.TSFlags & RISCVII::VS1Constraint) && Inst.getOperand(Offset + 2).isReg()) { 3472 unsigned CheckReg = Inst.getOperand(Offset + 2).getReg(); 3473 if (DestReg == CheckReg) 3474 return Error(Loc, "The destination vector register group cannot overlap" 3475 " the source vector register group."); 3476 } 3477 if ((MCID.TSFlags & RISCVII::VMConstraint) && (DestReg == RISCV::V0)) { 3478 // vadc, vsbc are special cases. These instructions have no mask register. 3479 // The destination register could not be V0. 3480 if (Opcode == RISCV::VADC_VVM || Opcode == RISCV::VADC_VXM || 3481 Opcode == RISCV::VADC_VIM || Opcode == RISCV::VSBC_VVM || 3482 Opcode == RISCV::VSBC_VXM || Opcode == RISCV::VFMERGE_VFM || 3483 Opcode == RISCV::VMERGE_VIM || Opcode == RISCV::VMERGE_VVM || 3484 Opcode == RISCV::VMERGE_VXM) 3485 return Error(Loc, "The destination vector register group cannot be V0."); 3486 3487 // Regardless masked or unmasked version, the number of operands is the 3488 // same. For example, "viota.m v0, v2" is "viota.m v0, v2, NoRegister" 3489 // actually. We need to check the last operand to ensure whether it is 3490 // masked or not. 3491 unsigned CheckReg = Inst.getOperand(Inst.getNumOperands() - 1).getReg(); 3492 assert((CheckReg == RISCV::V0 || CheckReg == RISCV::NoRegister) && 3493 "Unexpected register for mask operand"); 3494 3495 if (DestReg == CheckReg) 3496 return Error(Loc, "The destination vector register group cannot overlap" 3497 " the mask register."); 3498 } 3499 return false; 3500 } 3501 3502 bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 3503 OperandVector &Operands, 3504 MCStreamer &Out) { 3505 Inst.setLoc(IDLoc); 3506 3507 switch (Inst.getOpcode()) { 3508 default: 3509 break; 3510 case RISCV::PseudoLLAImm: 3511 case RISCV::PseudoLAImm: 3512 case RISCV::PseudoLI: { 3513 MCRegister Reg = Inst.getOperand(0).getReg(); 3514 const MCOperand &Op1 = Inst.getOperand(1); 3515 if (Op1.isExpr()) { 3516 // We must have li reg, %lo(sym) or li reg, %pcrel_lo(sym) or similar. 3517 // Just convert to an addi. This allows compatibility with gas. 3518 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI) 3519 .addReg(Reg) 3520 .addReg(RISCV::X0) 3521 .addExpr(Op1.getExpr())); 3522 return false; 3523 } 3524 int64_t Imm = Inst.getOperand(1).getImm(); 3525 // On RV32 the immediate here can either be a signed or an unsigned 3526 // 32-bit number. Sign extension has to be performed to ensure that Imm 3527 // represents the expected signed 64-bit number. 3528 if (!isRV64()) 3529 Imm = SignExtend64<32>(Imm); 3530 emitLoadImm(Reg, Imm, Out); 3531 return false; 3532 } 3533 case RISCV::PseudoLLA: 3534 emitLoadLocalAddress(Inst, IDLoc, Out); 3535 return false; 3536 case RISCV::PseudoLGA: 3537 emitLoadGlobalAddress(Inst, IDLoc, Out); 3538 return false; 3539 case RISCV::PseudoLA: 3540 emitLoadAddress(Inst, IDLoc, Out); 3541 return false; 3542 case RISCV::PseudoLA_TLS_IE: 3543 emitLoadTLSIEAddress(Inst, IDLoc, Out); 3544 return false; 3545 case RISCV::PseudoLA_TLS_GD: 3546 emitLoadTLSGDAddress(Inst, IDLoc, Out); 3547 return false; 3548 case RISCV::PseudoLB: 3549 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out, /*HasTmpReg=*/false); 3550 return false; 3551 case RISCV::PseudoLBU: 3552 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out, /*HasTmpReg=*/false); 3553 return false; 3554 case RISCV::PseudoLH: 3555 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out, /*HasTmpReg=*/false); 3556 return false; 3557 case RISCV::PseudoLHU: 3558 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out, /*HasTmpReg=*/false); 3559 return false; 3560 case RISCV::PseudoLW: 3561 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out, /*HasTmpReg=*/false); 3562 return false; 3563 case RISCV::PseudoLWU: 3564 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out, /*HasTmpReg=*/false); 3565 return false; 3566 case RISCV::PseudoLD: 3567 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out, /*HasTmpReg=*/false); 3568 return false; 3569 case RISCV::PseudoFLH: 3570 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out, /*HasTmpReg=*/true); 3571 return false; 3572 case RISCV::PseudoFLW: 3573 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out, /*HasTmpReg=*/true); 3574 return false; 3575 case RISCV::PseudoFLD: 3576 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out, /*HasTmpReg=*/true); 3577 return false; 3578 case RISCV::PseudoSB: 3579 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out, /*HasTmpReg=*/true); 3580 return false; 3581 case RISCV::PseudoSH: 3582 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out, /*HasTmpReg=*/true); 3583 return false; 3584 case RISCV::PseudoSW: 3585 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out, /*HasTmpReg=*/true); 3586 return false; 3587 case RISCV::PseudoSD: 3588 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out, /*HasTmpReg=*/true); 3589 return false; 3590 case RISCV::PseudoFSH: 3591 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out, /*HasTmpReg=*/true); 3592 return false; 3593 case RISCV::PseudoFSW: 3594 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out, /*HasTmpReg=*/true); 3595 return false; 3596 case RISCV::PseudoFSD: 3597 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out, /*HasTmpReg=*/true); 3598 return false; 3599 case RISCV::PseudoAddTPRel: 3600 if (checkPseudoAddTPRel(Inst, Operands)) 3601 return true; 3602 break; 3603 case RISCV::PseudoTLSDESCCall: 3604 if (checkPseudoTLSDESCCall(Inst, Operands)) 3605 return true; 3606 break; 3607 case RISCV::PseudoSEXT_B: 3608 emitPseudoExtend(Inst, /*SignExtend=*/true, /*Width=*/8, IDLoc, Out); 3609 return false; 3610 case RISCV::PseudoSEXT_H: 3611 emitPseudoExtend(Inst, /*SignExtend=*/true, /*Width=*/16, IDLoc, Out); 3612 return false; 3613 case RISCV::PseudoZEXT_H: 3614 emitPseudoExtend(Inst, /*SignExtend=*/false, /*Width=*/16, IDLoc, Out); 3615 return false; 3616 case RISCV::PseudoZEXT_W: 3617 emitPseudoExtend(Inst, /*SignExtend=*/false, /*Width=*/32, IDLoc, Out); 3618 return false; 3619 case RISCV::PseudoVMSGEU_VX: 3620 case RISCV::PseudoVMSGEU_VX_M: 3621 case RISCV::PseudoVMSGEU_VX_M_T: 3622 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out); 3623 return false; 3624 case RISCV::PseudoVMSGE_VX: 3625 case RISCV::PseudoVMSGE_VX_M: 3626 case RISCV::PseudoVMSGE_VX_M_T: 3627 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out); 3628 return false; 3629 case RISCV::PseudoVMSGE_VI: 3630 case RISCV::PseudoVMSLT_VI: { 3631 // These instructions are signed and so is immediate so we can subtract one 3632 // and change the opcode. 3633 int64_t Imm = Inst.getOperand(2).getImm(); 3634 unsigned Opc = Inst.getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI 3635 : RISCV::VMSLE_VI; 3636 emitToStreamer(Out, MCInstBuilder(Opc) 3637 .addOperand(Inst.getOperand(0)) 3638 .addOperand(Inst.getOperand(1)) 3639 .addImm(Imm - 1) 3640 .addOperand(Inst.getOperand(3))); 3641 return false; 3642 } 3643 case RISCV::PseudoVMSGEU_VI: 3644 case RISCV::PseudoVMSLTU_VI: { 3645 int64_t Imm = Inst.getOperand(2).getImm(); 3646 // Unsigned comparisons are tricky because the immediate is signed. If the 3647 // immediate is 0 we can't just subtract one. vmsltu.vi v0, v1, 0 is always 3648 // false, but vmsle.vi v0, v1, -1 is always true. Instead we use 3649 // vmsne v0, v1, v1 which is always false. 3650 if (Imm == 0) { 3651 unsigned Opc = Inst.getOpcode() == RISCV::PseudoVMSGEU_VI 3652 ? RISCV::VMSEQ_VV 3653 : RISCV::VMSNE_VV; 3654 emitToStreamer(Out, MCInstBuilder(Opc) 3655 .addOperand(Inst.getOperand(0)) 3656 .addOperand(Inst.getOperand(1)) 3657 .addOperand(Inst.getOperand(1)) 3658 .addOperand(Inst.getOperand(3))); 3659 } else { 3660 // Other immediate values can subtract one like signed. 3661 unsigned Opc = Inst.getOpcode() == RISCV::PseudoVMSGEU_VI 3662 ? RISCV::VMSGTU_VI 3663 : RISCV::VMSLEU_VI; 3664 emitToStreamer(Out, MCInstBuilder(Opc) 3665 .addOperand(Inst.getOperand(0)) 3666 .addOperand(Inst.getOperand(1)) 3667 .addImm(Imm - 1) 3668 .addOperand(Inst.getOperand(3))); 3669 } 3670 3671 return false; 3672 } 3673 } 3674 3675 emitToStreamer(Out, Inst); 3676 return false; 3677 } 3678 3679 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVAsmParser() { 3680 RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target()); 3681 RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target()); 3682 } 3683