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