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