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