1 //===-- RISCVAsmParser.cpp - Parse RISCV 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/SmallString.h" 20 #include "llvm/ADT/SmallVector.h" 21 #include "llvm/ADT/Statistic.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/MathExtras.h" 39 #include "llvm/Support/RISCVAttributes.h" 40 #include "llvm/Support/RISCVISAInfo.h" 41 42 #include <limits> 43 44 using namespace llvm; 45 46 #define DEBUG_TYPE "riscv-asm-parser" 47 48 STATISTIC(RISCVNumInstrsCompressed, 49 "Number of RISC-V Compressed instructions emitted"); 50 51 namespace llvm { 52 extern const SubtargetFeatureKV RISCVFeatureKV[RISCV::NumSubtargetFeatures]; 53 } // namespace llvm 54 55 namespace { 56 struct RISCVOperand; 57 58 struct ParserOptionsSet { 59 bool IsPicEnabled; 60 }; 61 62 class RISCVAsmParser : public MCTargetAsmParser { 63 SmallVector<FeatureBitset, 4> FeatureBitStack; 64 65 SmallVector<ParserOptionsSet, 4> ParserOptionsStack; 66 ParserOptionsSet ParserOptions; 67 68 SMLoc getLoc() const { return getParser().getTok().getLoc(); } 69 bool isRV64() const { return getSTI().hasFeature(RISCV::Feature64Bit); } 70 bool isRV32E() const { return getSTI().hasFeature(RISCV::FeatureRV32E); } 71 72 RISCVTargetStreamer &getTargetStreamer() { 73 assert(getParser().getStreamer().getTargetStreamer() && 74 "do not have a target streamer"); 75 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer(); 76 return static_cast<RISCVTargetStreamer &>(TS); 77 } 78 79 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, 80 unsigned Kind) override; 81 82 bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo, 83 int64_t Lower, int64_t Upper, Twine Msg); 84 85 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 86 OperandVector &Operands, MCStreamer &Out, 87 uint64_t &ErrorInfo, 88 bool MatchingInlineAsm) override; 89 90 bool parseRegister(MCRegister &RegNo, SMLoc &StartLoc, 91 SMLoc &EndLoc) override; 92 OperandMatchResultTy tryParseRegister(MCRegister &RegNo, SMLoc &StartLoc, 93 SMLoc &EndLoc) override; 94 95 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 96 SMLoc NameLoc, OperandVector &Operands) override; 97 98 bool ParseDirective(AsmToken DirectiveID) override; 99 100 // Helper to actually emit an instruction to the MCStreamer. Also, when 101 // possible, compression of the instruction is performed. 102 void emitToStreamer(MCStreamer &S, const MCInst &Inst); 103 104 // Helper to emit a combination of LUI, ADDI(W), and SLLI instructions that 105 // synthesize the desired immedate value into the destination register. 106 void emitLoadImm(MCRegister DestReg, int64_t Value, MCStreamer &Out); 107 108 // Helper to emit a combination of AUIPC and SecondOpcode. Used to implement 109 // helpers such as emitLoadLocalAddress and emitLoadAddress. 110 void emitAuipcInstPair(MCOperand DestReg, MCOperand TmpReg, 111 const MCExpr *Symbol, RISCVMCExpr::VariantKind VKHi, 112 unsigned SecondOpcode, SMLoc IDLoc, MCStreamer &Out); 113 114 // Helper to emit pseudo instruction "lla" used in PC-rel addressing. 115 void emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 116 117 // Helper to emit pseudo instruction "la" used in GOT/PC-rel addressing. 118 void emitLoadAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 119 120 // Helper to emit pseudo instruction "la.tls.ie" used in initial-exec TLS 121 // addressing. 122 void emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 123 124 // Helper to emit pseudo instruction "la.tls.gd" used in global-dynamic TLS 125 // addressing. 126 void emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 127 128 // Helper to emit pseudo load/store instruction with a symbol. 129 void emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode, SMLoc IDLoc, 130 MCStreamer &Out, bool HasTmpReg); 131 132 // Helper to emit pseudo sign/zero extend instruction. 133 void emitPseudoExtend(MCInst &Inst, bool SignExtend, int64_t Width, 134 SMLoc IDLoc, MCStreamer &Out); 135 136 // Helper to emit pseudo vmsge{u}.vx instruction. 137 void emitVMSGE(MCInst &Inst, unsigned Opcode, SMLoc IDLoc, MCStreamer &Out); 138 139 // Checks that a PseudoAddTPRel is using x4/tp in its second input operand. 140 // Enforcing this using a restricted register class for the second input 141 // operand of PseudoAddTPRel results in a poor diagnostic due to the fact 142 // 'add' is an overloaded mnemonic. 143 bool checkPseudoAddTPRel(MCInst &Inst, OperandVector &Operands); 144 145 // Check instruction constraints. 146 bool validateInstruction(MCInst &Inst, OperandVector &Operands); 147 148 /// Helper for processing MC instructions that have been successfully matched 149 /// by MatchAndEmitInstruction. Modifications to the emitted instructions, 150 /// like the expansion of pseudo instructions (e.g., "li"), can be performed 151 /// in this method. 152 bool processInstruction(MCInst &Inst, SMLoc IDLoc, OperandVector &Operands, 153 MCStreamer &Out); 154 155 // Auto-generated instruction matching functions 156 #define GET_ASSEMBLER_HEADER 157 #include "RISCVGenAsmMatcher.inc" 158 159 OperandMatchResultTy parseCSRSystemRegister(OperandVector &Operands); 160 OperandMatchResultTy parseImmediate(OperandVector &Operands); 161 OperandMatchResultTy parseRegister(OperandVector &Operands, 162 bool AllowParens = false); 163 OperandMatchResultTy parseMemOpBaseReg(OperandVector &Operands); 164 OperandMatchResultTy parseZeroOffsetMemOp(OperandVector &Operands); 165 OperandMatchResultTy parseOperandWithModifier(OperandVector &Operands); 166 OperandMatchResultTy parseBareSymbol(OperandVector &Operands); 167 OperandMatchResultTy parseCallSymbol(OperandVector &Operands); 168 OperandMatchResultTy parsePseudoJumpSymbol(OperandVector &Operands); 169 OperandMatchResultTy parseJALOffset(OperandVector &Operands); 170 OperandMatchResultTy parseVTypeI(OperandVector &Operands); 171 OperandMatchResultTy parseMaskReg(OperandVector &Operands); 172 OperandMatchResultTy parseInsnDirectiveOpcode(OperandVector &Operands); 173 OperandMatchResultTy parseGPRAsFPR(OperandVector &Operands); 174 175 bool parseOperand(OperandVector &Operands, StringRef Mnemonic); 176 177 bool parseDirectiveOption(); 178 bool parseDirectiveAttribute(); 179 bool parseDirectiveInsn(SMLoc L); 180 bool parseDirectiveVariantCC(); 181 182 void setFeatureBits(uint64_t Feature, StringRef FeatureString) { 183 if (!(getSTI().getFeatureBits()[Feature])) { 184 MCSubtargetInfo &STI = copySTI(); 185 setAvailableFeatures( 186 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); 187 } 188 } 189 190 bool getFeatureBits(uint64_t Feature) { 191 return getSTI().getFeatureBits()[Feature]; 192 } 193 194 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) { 195 if (getSTI().getFeatureBits()[Feature]) { 196 MCSubtargetInfo &STI = copySTI(); 197 setAvailableFeatures( 198 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); 199 } 200 } 201 202 void pushFeatureBits() { 203 assert(FeatureBitStack.size() == ParserOptionsStack.size() && 204 "These two stacks must be kept synchronized"); 205 FeatureBitStack.push_back(getSTI().getFeatureBits()); 206 ParserOptionsStack.push_back(ParserOptions); 207 } 208 209 bool popFeatureBits() { 210 assert(FeatureBitStack.size() == ParserOptionsStack.size() && 211 "These two stacks must be kept synchronized"); 212 if (FeatureBitStack.empty()) 213 return true; 214 215 FeatureBitset FeatureBits = FeatureBitStack.pop_back_val(); 216 copySTI().setFeatureBits(FeatureBits); 217 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits)); 218 219 ParserOptions = ParserOptionsStack.pop_back_val(); 220 221 return false; 222 } 223 224 std::unique_ptr<RISCVOperand> defaultMaskRegOp() const; 225 226 public: 227 enum RISCVMatchResultTy { 228 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY, 229 #define GET_OPERAND_DIAGNOSTIC_TYPES 230 #include "RISCVGenAsmMatcher.inc" 231 #undef GET_OPERAND_DIAGNOSTIC_TYPES 232 }; 233 234 static bool classifySymbolRef(const MCExpr *Expr, 235 RISCVMCExpr::VariantKind &Kind); 236 237 RISCVAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, 238 const MCInstrInfo &MII, const MCTargetOptions &Options) 239 : MCTargetAsmParser(Options, STI, MII) { 240 Parser.addAliasForDirective(".half", ".2byte"); 241 Parser.addAliasForDirective(".hword", ".2byte"); 242 Parser.addAliasForDirective(".word", ".4byte"); 243 Parser.addAliasForDirective(".dword", ".8byte"); 244 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 245 246 auto ABIName = StringRef(Options.ABIName); 247 if (ABIName.endswith("f") && 248 !getSTI().getFeatureBits()[RISCV::FeatureStdExtF]) { 249 errs() << "Hard-float 'f' ABI can't be used for a target that " 250 "doesn't support the F instruction set extension (ignoring " 251 "target-abi)\n"; 252 } else if (ABIName.endswith("d") && 253 !getSTI().getFeatureBits()[RISCV::FeatureStdExtD]) { 254 errs() << "Hard-float 'd' ABI can't be used for a target that " 255 "doesn't support the D instruction set extension (ignoring " 256 "target-abi)\n"; 257 } 258 259 // Use computeTargetABI to check if ABIName is valid. If invalid, output 260 // error message. 261 RISCVABI::computeTargetABI(STI.getTargetTriple(), STI.getFeatureBits(), 262 ABIName); 263 264 const MCObjectFileInfo *MOFI = Parser.getContext().getObjectFileInfo(); 265 ParserOptions.IsPicEnabled = MOFI->isPositionIndependent(); 266 } 267 }; 268 269 /// RISCVOperand - Instances of this class represent a parsed machine 270 /// instruction 271 struct RISCVOperand : public MCParsedAsmOperand { 272 273 enum class KindTy { 274 Token, 275 Register, 276 Immediate, 277 SystemRegister, 278 VType, 279 } Kind; 280 281 bool IsRV64; 282 283 bool IsGPRAsFPR; 284 285 struct RegOp { 286 MCRegister RegNum; 287 }; 288 289 struct ImmOp { 290 const MCExpr *Val; 291 }; 292 293 struct SysRegOp { 294 const char *Data; 295 unsigned Length; 296 unsigned Encoding; 297 // FIXME: Add the Encoding parsed fields as needed for checks, 298 // e.g.: read/write or user/supervisor/machine privileges. 299 }; 300 301 struct VTypeOp { 302 unsigned Val; 303 }; 304 305 SMLoc StartLoc, EndLoc; 306 union { 307 StringRef Tok; 308 RegOp Reg; 309 ImmOp Imm; 310 struct SysRegOp SysReg; 311 struct VTypeOp VType; 312 }; 313 314 RISCVOperand(KindTy K) : Kind(K) {} 315 316 public: 317 RISCVOperand(const RISCVOperand &o) : MCParsedAsmOperand() { 318 Kind = o.Kind; 319 IsRV64 = o.IsRV64; 320 StartLoc = o.StartLoc; 321 EndLoc = o.EndLoc; 322 switch (Kind) { 323 case KindTy::Register: 324 Reg = o.Reg; 325 break; 326 case KindTy::Immediate: 327 Imm = o.Imm; 328 break; 329 case KindTy::Token: 330 Tok = o.Tok; 331 break; 332 case KindTy::SystemRegister: 333 SysReg = o.SysReg; 334 break; 335 case KindTy::VType: 336 VType = o.VType; 337 break; 338 } 339 } 340 341 bool isToken() const override { return Kind == KindTy::Token; } 342 bool isReg() const override { return Kind == KindTy::Register; } 343 bool isV0Reg() const { 344 return Kind == KindTy::Register && Reg.RegNum == RISCV::V0; 345 } 346 bool isImm() const override { return Kind == KindTy::Immediate; } 347 bool isMem() const override { return false; } 348 bool isSystemRegister() const { return Kind == KindTy::SystemRegister; } 349 350 bool isGPR() const { 351 return Kind == KindTy::Register && 352 RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(Reg.RegNum); 353 } 354 355 bool isGPRAsFPR() const { return isGPR() && IsGPRAsFPR; } 356 357 bool isGPRF64AsFPR() const { return isGPR() && IsGPRAsFPR && IsRV64; } 358 359 bool isGPRPF64AsFPR() const { 360 return isGPR() && IsGPRAsFPR && !IsRV64 && !((Reg.RegNum - RISCV::X0) & 1); 361 } 362 363 static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm, 364 RISCVMCExpr::VariantKind &VK) { 365 if (auto *RE = dyn_cast<RISCVMCExpr>(Expr)) { 366 VK = RE->getKind(); 367 return RE->evaluateAsConstant(Imm); 368 } 369 370 if (auto CE = dyn_cast<MCConstantExpr>(Expr)) { 371 VK = RISCVMCExpr::VK_RISCV_None; 372 Imm = CE->getValue(); 373 return true; 374 } 375 376 return false; 377 } 378 379 // True if operand is a symbol with no modifiers, or a constant with no 380 // modifiers and isShiftedInt<N-1, 1>(Op). 381 template <int N> bool isBareSimmNLsb0() const { 382 int64_t Imm; 383 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 384 if (!isImm()) 385 return false; 386 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 387 bool IsValid; 388 if (!IsConstantImm) 389 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK); 390 else 391 IsValid = isShiftedInt<N - 1, 1>(Imm); 392 return IsValid && VK == RISCVMCExpr::VK_RISCV_None; 393 } 394 395 // Predicate methods for AsmOperands defined in RISCVInstrInfo.td 396 397 bool isBareSymbol() const { 398 int64_t Imm; 399 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 400 // Must be of 'immediate' type but not a constant. 401 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK)) 402 return false; 403 return RISCVAsmParser::classifySymbolRef(getImm(), VK) && 404 VK == RISCVMCExpr::VK_RISCV_None; 405 } 406 407 bool isCallSymbol() const { 408 int64_t Imm; 409 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 410 // Must be of 'immediate' type but not a constant. 411 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK)) 412 return false; 413 return RISCVAsmParser::classifySymbolRef(getImm(), VK) && 414 (VK == RISCVMCExpr::VK_RISCV_CALL || 415 VK == RISCVMCExpr::VK_RISCV_CALL_PLT); 416 } 417 418 bool isPseudoJumpSymbol() const { 419 int64_t Imm; 420 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 421 // Must be of 'immediate' type but not a constant. 422 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK)) 423 return false; 424 return RISCVAsmParser::classifySymbolRef(getImm(), VK) && 425 VK == RISCVMCExpr::VK_RISCV_CALL; 426 } 427 428 bool isTPRelAddSymbol() const { 429 int64_t Imm; 430 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 431 // Must be of 'immediate' type but not a constant. 432 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK)) 433 return false; 434 return RISCVAsmParser::classifySymbolRef(getImm(), VK) && 435 VK == RISCVMCExpr::VK_RISCV_TPREL_ADD; 436 } 437 438 bool isCSRSystemRegister() const { return isSystemRegister(); } 439 440 bool isVTypeImm(unsigned N) const { 441 int64_t Imm; 442 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 443 if (!isImm()) 444 return false; 445 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 446 return IsConstantImm && isUIntN(N, Imm) && VK == RISCVMCExpr::VK_RISCV_None; 447 } 448 449 // If the last operand of the vsetvli/vsetvli instruction is a constant 450 // expression, KindTy is Immediate. 451 bool isVTypeI10() const { 452 if (Kind == KindTy::Immediate) 453 return isVTypeImm(10); 454 return Kind == KindTy::VType; 455 } 456 bool isVTypeI11() const { 457 if (Kind == KindTy::Immediate) 458 return isVTypeImm(11); 459 return Kind == KindTy::VType; 460 } 461 462 /// Return true if the operand is a valid for the fence instruction e.g. 463 /// ('iorw'). 464 bool isFenceArg() const { 465 if (!isImm()) 466 return false; 467 468 int64_t Imm; 469 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 470 if (evaluateConstantImm(getImm(), Imm, VK)) { 471 // Only accept 0 as a constant immediate. 472 return VK == RISCVMCExpr::VK_RISCV_None && Imm == 0; 473 } 474 475 auto *SVal = dyn_cast<MCSymbolRefExpr>(getImm()); 476 477 if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None) 478 return false; 479 480 StringRef Str = SVal->getSymbol().getName(); 481 // Letters must be unique, taken from 'iorw', and in ascending order. This 482 // holds as long as each individual character is one of 'iorw' and is 483 // greater than the previous character. 484 char Prev = '\0'; 485 for (char c : Str) { 486 if (c != 'i' && c != 'o' && c != 'r' && c != 'w') 487 return false; 488 if (c <= Prev) 489 return false; 490 Prev = c; 491 } 492 return true; 493 } 494 495 /// Return true if the operand is a valid floating point rounding mode. 496 bool isFRMArg() const { 497 if (!isImm()) 498 return false; 499 const MCExpr *Val = getImm(); 500 auto *SVal = dyn_cast<MCSymbolRefExpr>(Val); 501 if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None) 502 return false; 503 504 StringRef Str = SVal->getSymbol().getName(); 505 506 return RISCVFPRndMode::stringToRoundingMode(Str) != RISCVFPRndMode::Invalid; 507 } 508 509 bool isImmXLenLI() const { 510 int64_t Imm; 511 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 512 if (!isImm()) 513 return false; 514 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 515 if (VK == RISCVMCExpr::VK_RISCV_LO || VK == RISCVMCExpr::VK_RISCV_PCREL_LO) 516 return true; 517 // Given only Imm, ensuring that the actually specified constant is either 518 // a signed or unsigned 64-bit number is unfortunately impossible. 519 return IsConstantImm && VK == RISCVMCExpr::VK_RISCV_None && 520 (isRV64() || (isInt<32>(Imm) || isUInt<32>(Imm))); 521 } 522 523 bool isUImmLog2XLen() const { 524 int64_t Imm; 525 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 526 if (!isImm()) 527 return false; 528 if (!evaluateConstantImm(getImm(), Imm, VK) || 529 VK != RISCVMCExpr::VK_RISCV_None) 530 return false; 531 return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm); 532 } 533 534 bool isUImmLog2XLenNonZero() const { 535 int64_t Imm; 536 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 537 if (!isImm()) 538 return false; 539 if (!evaluateConstantImm(getImm(), Imm, VK) || 540 VK != RISCVMCExpr::VK_RISCV_None) 541 return false; 542 if (Imm == 0) 543 return false; 544 return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm); 545 } 546 547 bool isUImmLog2XLenHalf() const { 548 int64_t Imm; 549 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 550 if (!isImm()) 551 return false; 552 if (!evaluateConstantImm(getImm(), Imm, VK) || 553 VK != RISCVMCExpr::VK_RISCV_None) 554 return false; 555 return (isRV64() && isUInt<5>(Imm)) || isUInt<4>(Imm); 556 } 557 558 template <unsigned N> bool IsUImm() const { 559 int64_t Imm; 560 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 561 if (!isImm()) 562 return false; 563 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 564 return IsConstantImm && isUInt<N>(Imm) && VK == RISCVMCExpr::VK_RISCV_None; 565 } 566 567 bool isUImm2() { return IsUImm<2>(); } 568 bool isUImm3() { return IsUImm<3>(); } 569 bool isUImm5() { return IsUImm<5>(); } 570 bool isUImm7() { return IsUImm<7>(); } 571 572 bool isRnumArg() const { 573 int64_t Imm; 574 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 575 if (!isImm()) 576 return false; 577 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 578 return IsConstantImm && Imm >= INT64_C(0) && Imm <= INT64_C(10) && 579 VK == RISCVMCExpr::VK_RISCV_None; 580 } 581 582 bool isSImm5() const { 583 if (!isImm()) 584 return false; 585 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 586 int64_t Imm; 587 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 588 return IsConstantImm && isInt<5>(Imm) && VK == RISCVMCExpr::VK_RISCV_None; 589 } 590 591 bool isSImm6() const { 592 if (!isImm()) 593 return false; 594 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 595 int64_t Imm; 596 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 597 return IsConstantImm && isInt<6>(Imm) && VK == RISCVMCExpr::VK_RISCV_None; 598 } 599 600 bool isSImm6NonZero() const { 601 if (!isImm()) 602 return false; 603 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 604 int64_t Imm; 605 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 606 return IsConstantImm && isInt<6>(Imm) && (Imm != 0) && 607 VK == RISCVMCExpr::VK_RISCV_None; 608 } 609 610 bool isCLUIImm() const { 611 if (!isImm()) 612 return false; 613 int64_t Imm; 614 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 615 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 616 return IsConstantImm && (Imm != 0) && 617 (isUInt<5>(Imm) || (Imm >= 0xfffe0 && Imm <= 0xfffff)) && 618 VK == RISCVMCExpr::VK_RISCV_None; 619 } 620 621 bool isUImm7Lsb00() const { 622 if (!isImm()) 623 return false; 624 int64_t Imm; 625 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 626 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 627 return IsConstantImm && isShiftedUInt<5, 2>(Imm) && 628 VK == RISCVMCExpr::VK_RISCV_None; 629 } 630 631 bool isUImm8Lsb00() const { 632 if (!isImm()) 633 return false; 634 int64_t Imm; 635 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 636 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 637 return IsConstantImm && isShiftedUInt<6, 2>(Imm) && 638 VK == RISCVMCExpr::VK_RISCV_None; 639 } 640 641 bool isUImm8Lsb000() const { 642 if (!isImm()) 643 return false; 644 int64_t Imm; 645 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 646 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 647 return IsConstantImm && isShiftedUInt<5, 3>(Imm) && 648 VK == RISCVMCExpr::VK_RISCV_None; 649 } 650 651 bool isSImm9Lsb0() const { return isBareSimmNLsb0<9>(); } 652 653 bool isUImm9Lsb000() const { 654 if (!isImm()) 655 return false; 656 int64_t Imm; 657 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 658 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 659 return IsConstantImm && isShiftedUInt<6, 3>(Imm) && 660 VK == RISCVMCExpr::VK_RISCV_None; 661 } 662 663 bool isUImm10Lsb00NonZero() const { 664 if (!isImm()) 665 return false; 666 int64_t Imm; 667 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 668 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 669 return IsConstantImm && isShiftedUInt<8, 2>(Imm) && (Imm != 0) && 670 VK == RISCVMCExpr::VK_RISCV_None; 671 } 672 673 bool isSImm12() const { 674 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 675 int64_t Imm; 676 bool IsValid; 677 if (!isImm()) 678 return false; 679 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 680 if (!IsConstantImm) 681 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK); 682 else 683 IsValid = isInt<12>(Imm); 684 return IsValid && ((IsConstantImm && VK == RISCVMCExpr::VK_RISCV_None) || 685 VK == RISCVMCExpr::VK_RISCV_LO || 686 VK == RISCVMCExpr::VK_RISCV_PCREL_LO || 687 VK == RISCVMCExpr::VK_RISCV_TPREL_LO); 688 } 689 690 bool isSImm12Lsb0() const { return isBareSimmNLsb0<12>(); } 691 692 bool isSImm12Lsb00000() const { 693 if (!isImm()) 694 return false; 695 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 696 int64_t Imm; 697 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 698 return IsConstantImm && isShiftedInt<7, 5>(Imm) && 699 VK == RISCVMCExpr::VK_RISCV_None; 700 } 701 702 bool isSImm13Lsb0() const { return isBareSimmNLsb0<13>(); } 703 704 bool isSImm10Lsb0000NonZero() const { 705 if (!isImm()) 706 return false; 707 int64_t Imm; 708 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 709 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 710 return IsConstantImm && (Imm != 0) && isShiftedInt<6, 4>(Imm) && 711 VK == RISCVMCExpr::VK_RISCV_None; 712 } 713 714 bool isUImm20LUI() const { 715 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 716 int64_t Imm; 717 bool IsValid; 718 if (!isImm()) 719 return false; 720 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 721 if (!IsConstantImm) { 722 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK); 723 return IsValid && (VK == RISCVMCExpr::VK_RISCV_HI || 724 VK == RISCVMCExpr::VK_RISCV_TPREL_HI); 725 } else { 726 return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None || 727 VK == RISCVMCExpr::VK_RISCV_HI || 728 VK == RISCVMCExpr::VK_RISCV_TPREL_HI); 729 } 730 } 731 732 bool isUImm20AUIPC() const { 733 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 734 int64_t Imm; 735 bool IsValid; 736 if (!isImm()) 737 return false; 738 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 739 if (!IsConstantImm) { 740 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK); 741 return IsValid && (VK == RISCVMCExpr::VK_RISCV_PCREL_HI || 742 VK == RISCVMCExpr::VK_RISCV_GOT_HI || 743 VK == RISCVMCExpr::VK_RISCV_TLS_GOT_HI || 744 VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI); 745 } else { 746 return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None || 747 VK == RISCVMCExpr::VK_RISCV_PCREL_HI || 748 VK == RISCVMCExpr::VK_RISCV_GOT_HI || 749 VK == RISCVMCExpr::VK_RISCV_TLS_GOT_HI || 750 VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI); 751 } 752 } 753 754 bool isSImm21Lsb0JAL() const { return isBareSimmNLsb0<21>(); } 755 756 bool isImmZero() const { 757 if (!isImm()) 758 return false; 759 int64_t Imm; 760 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 761 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 762 return IsConstantImm && (Imm == 0) && VK == RISCVMCExpr::VK_RISCV_None; 763 } 764 765 bool isSImm5Plus1() const { 766 if (!isImm()) 767 return false; 768 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 769 int64_t Imm; 770 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 771 return IsConstantImm && isInt<5>(Imm - 1) && 772 VK == RISCVMCExpr::VK_RISCV_None; 773 } 774 775 /// getStartLoc - Gets location of the first token of this operand 776 SMLoc getStartLoc() const override { return StartLoc; } 777 /// getEndLoc - Gets location of the last token of this operand 778 SMLoc getEndLoc() const override { return EndLoc; } 779 /// True if this operand is for an RV64 instruction 780 bool isRV64() const { return IsRV64; } 781 782 unsigned getReg() const override { 783 assert(Kind == KindTy::Register && "Invalid type access!"); 784 return Reg.RegNum.id(); 785 } 786 787 StringRef getSysReg() const { 788 assert(Kind == KindTy::SystemRegister && "Invalid type access!"); 789 return StringRef(SysReg.Data, SysReg.Length); 790 } 791 792 const MCExpr *getImm() const { 793 assert(Kind == KindTy::Immediate && "Invalid type access!"); 794 return Imm.Val; 795 } 796 797 StringRef getToken() const { 798 assert(Kind == KindTy::Token && "Invalid type access!"); 799 return Tok; 800 } 801 802 unsigned getVType() const { 803 assert(Kind == KindTy::VType && "Invalid type access!"); 804 return VType.Val; 805 } 806 807 void print(raw_ostream &OS) const override { 808 auto RegName = [](MCRegister Reg) { 809 if (Reg) 810 return RISCVInstPrinter::getRegisterName(Reg); 811 else 812 return "noreg"; 813 }; 814 815 switch (Kind) { 816 case KindTy::Immediate: 817 OS << *getImm(); 818 break; 819 case KindTy::Register: 820 OS << "<register " << RegName(getReg()) << ">"; 821 break; 822 case KindTy::Token: 823 OS << "'" << getToken() << "'"; 824 break; 825 case KindTy::SystemRegister: 826 OS << "<sysreg: " << getSysReg() << '>'; 827 break; 828 case KindTy::VType: 829 OS << "<vtype: "; 830 RISCVVType::printVType(getVType(), OS); 831 OS << '>'; 832 break; 833 } 834 } 835 836 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S, 837 bool IsRV64) { 838 auto Op = std::make_unique<RISCVOperand>(KindTy::Token); 839 Op->Tok = Str; 840 Op->StartLoc = S; 841 Op->EndLoc = S; 842 Op->IsRV64 = IsRV64; 843 return Op; 844 } 845 846 static std::unique_ptr<RISCVOperand> createReg(unsigned RegNo, SMLoc S, 847 SMLoc E, bool IsRV64, 848 bool IsGPRAsFPR = false) { 849 auto Op = std::make_unique<RISCVOperand>(KindTy::Register); 850 Op->Reg.RegNum = RegNo; 851 Op->StartLoc = S; 852 Op->EndLoc = E; 853 Op->IsRV64 = IsRV64; 854 Op->IsGPRAsFPR = IsGPRAsFPR; 855 return Op; 856 } 857 858 static std::unique_ptr<RISCVOperand> createImm(const MCExpr *Val, SMLoc S, 859 SMLoc E, bool IsRV64) { 860 auto Op = std::make_unique<RISCVOperand>(KindTy::Immediate); 861 Op->Imm.Val = Val; 862 Op->StartLoc = S; 863 Op->EndLoc = E; 864 Op->IsRV64 = IsRV64; 865 return Op; 866 } 867 868 static std::unique_ptr<RISCVOperand> 869 createSysReg(StringRef Str, SMLoc S, unsigned Encoding, bool IsRV64) { 870 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister); 871 Op->SysReg.Data = Str.data(); 872 Op->SysReg.Length = Str.size(); 873 Op->SysReg.Encoding = Encoding; 874 Op->StartLoc = S; 875 Op->EndLoc = S; 876 Op->IsRV64 = IsRV64; 877 return Op; 878 } 879 880 static std::unique_ptr<RISCVOperand> createVType(unsigned VTypeI, SMLoc S, 881 bool IsRV64) { 882 auto Op = std::make_unique<RISCVOperand>(KindTy::VType); 883 Op->VType.Val = VTypeI; 884 Op->StartLoc = S; 885 Op->EndLoc = S; 886 Op->IsRV64 = IsRV64; 887 return Op; 888 } 889 890 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 891 assert(Expr && "Expr shouldn't be null!"); 892 int64_t Imm = 0; 893 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 894 bool IsConstant = evaluateConstantImm(Expr, Imm, VK); 895 896 if (IsConstant) 897 Inst.addOperand(MCOperand::createImm(Imm)); 898 else 899 Inst.addOperand(MCOperand::createExpr(Expr)); 900 } 901 902 // Used by the TableGen Code 903 void addRegOperands(MCInst &Inst, unsigned N) const { 904 assert(N == 1 && "Invalid number of operands!"); 905 Inst.addOperand(MCOperand::createReg(getReg())); 906 } 907 908 void addImmOperands(MCInst &Inst, unsigned N) const { 909 assert(N == 1 && "Invalid number of operands!"); 910 addExpr(Inst, getImm()); 911 } 912 913 void addFenceArgOperands(MCInst &Inst, unsigned N) const { 914 assert(N == 1 && "Invalid number of operands!"); 915 916 int64_t Constant = 0; 917 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 918 if (evaluateConstantImm(getImm(), Constant, VK)) { 919 if (Constant == 0) { 920 Inst.addOperand(MCOperand::createImm(Constant)); 921 return; 922 } 923 llvm_unreachable("FenceArg must contain only [iorw] or be 0"); 924 } 925 926 // isFenceArg has validated the operand, meaning this cast is safe 927 auto SE = cast<MCSymbolRefExpr>(getImm()); 928 929 unsigned Imm = 0; 930 for (char c : SE->getSymbol().getName()) { 931 switch (c) { 932 default: 933 llvm_unreachable("FenceArg must contain only [iorw] or be 0"); 934 case 'i': 935 Imm |= RISCVFenceField::I; 936 break; 937 case 'o': 938 Imm |= RISCVFenceField::O; 939 break; 940 case 'r': 941 Imm |= RISCVFenceField::R; 942 break; 943 case 'w': 944 Imm |= RISCVFenceField::W; 945 break; 946 } 947 } 948 Inst.addOperand(MCOperand::createImm(Imm)); 949 } 950 951 void addCSRSystemRegisterOperands(MCInst &Inst, unsigned N) const { 952 assert(N == 1 && "Invalid number of operands!"); 953 Inst.addOperand(MCOperand::createImm(SysReg.Encoding)); 954 } 955 956 // Support non-canonical syntax: 957 // "vsetivli rd, uimm, 0xabc" or "vsetvli rd, rs1, 0xabc" 958 // "vsetivli rd, uimm, (0xc << N)" or "vsetvli rd, rs1, (0xc << N)" 959 void addVTypeIOperands(MCInst &Inst, unsigned N) const { 960 assert(N == 1 && "Invalid number of operands!"); 961 int64_t Imm = 0; 962 if (Kind == KindTy::Immediate) { 963 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 964 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 965 (void)IsConstantImm; 966 assert(IsConstantImm && "Invalid VTypeI Operand!"); 967 } else { 968 Imm = getVType(); 969 } 970 Inst.addOperand(MCOperand::createImm(Imm)); 971 } 972 973 // Returns the rounding mode represented by this RISCVOperand. Should only 974 // be called after checking isFRMArg. 975 RISCVFPRndMode::RoundingMode getRoundingMode() const { 976 // isFRMArg has validated the operand, meaning this cast is safe. 977 auto SE = cast<MCSymbolRefExpr>(getImm()); 978 RISCVFPRndMode::RoundingMode FRM = 979 RISCVFPRndMode::stringToRoundingMode(SE->getSymbol().getName()); 980 assert(FRM != RISCVFPRndMode::Invalid && "Invalid rounding mode"); 981 return FRM; 982 } 983 984 void addFRMArgOperands(MCInst &Inst, unsigned N) const { 985 assert(N == 1 && "Invalid number of operands!"); 986 Inst.addOperand(MCOperand::createImm(getRoundingMode())); 987 } 988 }; 989 } // end anonymous namespace. 990 991 #define GET_REGISTER_MATCHER 992 #define GET_SUBTARGET_FEATURE_NAME 993 #define GET_MATCHER_IMPLEMENTATION 994 #define GET_MNEMONIC_SPELL_CHECKER 995 #include "RISCVGenAsmMatcher.inc" 996 997 static MCRegister convertFPR64ToFPR16(MCRegister Reg) { 998 assert(Reg >= RISCV::F0_D && Reg <= RISCV::F31_D && "Invalid register"); 999 return Reg - RISCV::F0_D + RISCV::F0_H; 1000 } 1001 1002 static MCRegister convertFPR64ToFPR32(MCRegister Reg) { 1003 assert(Reg >= RISCV::F0_D && Reg <= RISCV::F31_D && "Invalid register"); 1004 return Reg - RISCV::F0_D + RISCV::F0_F; 1005 } 1006 1007 static MCRegister convertVRToVRMx(const MCRegisterInfo &RI, MCRegister Reg, 1008 unsigned Kind) { 1009 unsigned RegClassID; 1010 if (Kind == MCK_VRM2) 1011 RegClassID = RISCV::VRM2RegClassID; 1012 else if (Kind == MCK_VRM4) 1013 RegClassID = RISCV::VRM4RegClassID; 1014 else if (Kind == MCK_VRM8) 1015 RegClassID = RISCV::VRM8RegClassID; 1016 else 1017 return 0; 1018 return RI.getMatchingSuperReg(Reg, RISCV::sub_vrm1_0, 1019 &RISCVMCRegisterClasses[RegClassID]); 1020 } 1021 1022 unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp, 1023 unsigned Kind) { 1024 RISCVOperand &Op = static_cast<RISCVOperand &>(AsmOp); 1025 if (!Op.isReg()) 1026 return Match_InvalidOperand; 1027 1028 MCRegister Reg = Op.getReg(); 1029 bool IsRegFPR64 = 1030 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(Reg); 1031 bool IsRegFPR64C = 1032 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(Reg); 1033 bool IsRegVR = RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(Reg); 1034 1035 // As the parser couldn't differentiate an FPR32 from an FPR64, coerce the 1036 // register from FPR64 to FPR32 or FPR64C to FPR32C if necessary. 1037 if ((IsRegFPR64 && Kind == MCK_FPR32) || 1038 (IsRegFPR64C && Kind == MCK_FPR32C)) { 1039 Op.Reg.RegNum = convertFPR64ToFPR32(Reg); 1040 return Match_Success; 1041 } 1042 // As the parser couldn't differentiate an FPR16 from an FPR64, coerce the 1043 // register from FPR64 to FPR16 if necessary. 1044 if (IsRegFPR64 && Kind == MCK_FPR16) { 1045 Op.Reg.RegNum = convertFPR64ToFPR16(Reg); 1046 return Match_Success; 1047 } 1048 // As the parser couldn't differentiate an VRM2/VRM4/VRM8 from an VR, coerce 1049 // the register from VR to VRM2/VRM4/VRM8 if necessary. 1050 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) { 1051 Op.Reg.RegNum = convertVRToVRMx(*getContext().getRegisterInfo(), Reg, Kind); 1052 if (Op.Reg.RegNum == 0) 1053 return Match_InvalidOperand; 1054 return Match_Success; 1055 } 1056 return Match_InvalidOperand; 1057 } 1058 1059 bool RISCVAsmParser::generateImmOutOfRangeError( 1060 OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper, 1061 Twine Msg = "immediate must be an integer in the range") { 1062 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1063 return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]"); 1064 } 1065 1066 bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 1067 OperandVector &Operands, 1068 MCStreamer &Out, 1069 uint64_t &ErrorInfo, 1070 bool MatchingInlineAsm) { 1071 MCInst Inst; 1072 FeatureBitset MissingFeatures; 1073 1074 auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures, 1075 MatchingInlineAsm); 1076 switch (Result) { 1077 default: 1078 break; 1079 case Match_Success: 1080 if (validateInstruction(Inst, Operands)) 1081 return true; 1082 return processInstruction(Inst, IDLoc, Operands, Out); 1083 case Match_MissingFeature: { 1084 assert(MissingFeatures.any() && "Unknown missing features!"); 1085 bool FirstFeature = true; 1086 std::string Msg = "instruction requires the following:"; 1087 for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) { 1088 if (MissingFeatures[i]) { 1089 Msg += FirstFeature ? " " : ", "; 1090 Msg += getSubtargetFeatureName(i); 1091 FirstFeature = false; 1092 } 1093 } 1094 return Error(IDLoc, Msg); 1095 } 1096 case Match_MnemonicFail: { 1097 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits()); 1098 std::string Suggestion = RISCVMnemonicSpellCheck( 1099 ((RISCVOperand &)*Operands[0]).getToken(), FBS, 0); 1100 return Error(IDLoc, "unrecognized instruction mnemonic" + Suggestion); 1101 } 1102 case Match_InvalidOperand: { 1103 SMLoc ErrorLoc = IDLoc; 1104 if (ErrorInfo != ~0ULL) { 1105 if (ErrorInfo >= Operands.size()) 1106 return Error(ErrorLoc, "too few operands for instruction"); 1107 1108 ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1109 if (ErrorLoc == SMLoc()) 1110 ErrorLoc = IDLoc; 1111 } 1112 return Error(ErrorLoc, "invalid operand for instruction"); 1113 } 1114 } 1115 1116 // Handle the case when the error message is of specific type 1117 // other than the generic Match_InvalidOperand, and the 1118 // corresponding operand is missing. 1119 if (Result > FIRST_TARGET_MATCH_RESULT_TY) { 1120 SMLoc ErrorLoc = IDLoc; 1121 if (ErrorInfo != ~0ULL && ErrorInfo >= Operands.size()) 1122 return Error(ErrorLoc, "too few operands for instruction"); 1123 } 1124 1125 switch (Result) { 1126 default: 1127 break; 1128 case Match_InvalidImmXLenLI: 1129 if (isRV64()) { 1130 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1131 return Error(ErrorLoc, "operand must be a constant 64-bit integer"); 1132 } 1133 return generateImmOutOfRangeError(Operands, ErrorInfo, 1134 std::numeric_limits<int32_t>::min(), 1135 std::numeric_limits<uint32_t>::max()); 1136 case Match_InvalidImmZero: { 1137 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1138 return Error(ErrorLoc, "immediate must be zero"); 1139 } 1140 case Match_InvalidUImmLog2XLen: 1141 if (isRV64()) 1142 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1); 1143 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 1144 case Match_InvalidUImmLog2XLenNonZero: 1145 if (isRV64()) 1146 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1); 1147 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1); 1148 case Match_InvalidUImmLog2XLenHalf: 1149 if (isRV64()) 1150 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 1151 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1); 1152 case Match_InvalidUImm2: 1153 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1); 1154 case Match_InvalidUImm3: 1155 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1); 1156 case Match_InvalidUImm5: 1157 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 1158 case Match_InvalidUImm7: 1159 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1); 1160 case Match_InvalidSImm5: 1161 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4), 1162 (1 << 4) - 1); 1163 case Match_InvalidSImm6: 1164 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5), 1165 (1 << 5) - 1); 1166 case Match_InvalidSImm6NonZero: 1167 return generateImmOutOfRangeError( 1168 Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1, 1169 "immediate must be non-zero in the range"); 1170 case Match_InvalidCLUIImm: 1171 return generateImmOutOfRangeError( 1172 Operands, ErrorInfo, 1, (1 << 5) - 1, 1173 "immediate must be in [0xfffe0, 0xfffff] or"); 1174 case Match_InvalidUImm7Lsb00: 1175 return generateImmOutOfRangeError( 1176 Operands, ErrorInfo, 0, (1 << 7) - 4, 1177 "immediate must be a multiple of 4 bytes in the range"); 1178 case Match_InvalidUImm8Lsb00: 1179 return generateImmOutOfRangeError( 1180 Operands, ErrorInfo, 0, (1 << 8) - 4, 1181 "immediate must be a multiple of 4 bytes in the range"); 1182 case Match_InvalidUImm8Lsb000: 1183 return generateImmOutOfRangeError( 1184 Operands, ErrorInfo, 0, (1 << 8) - 8, 1185 "immediate must be a multiple of 8 bytes in the range"); 1186 case Match_InvalidSImm9Lsb0: 1187 return generateImmOutOfRangeError( 1188 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2, 1189 "immediate must be a multiple of 2 bytes in the range"); 1190 case Match_InvalidUImm9Lsb000: 1191 return generateImmOutOfRangeError( 1192 Operands, ErrorInfo, 0, (1 << 9) - 8, 1193 "immediate must be a multiple of 8 bytes in the range"); 1194 case Match_InvalidUImm10Lsb00NonZero: 1195 return generateImmOutOfRangeError( 1196 Operands, ErrorInfo, 4, (1 << 10) - 4, 1197 "immediate must be a multiple of 4 bytes in the range"); 1198 case Match_InvalidSImm10Lsb0000NonZero: 1199 return generateImmOutOfRangeError( 1200 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16, 1201 "immediate must be a multiple of 16 bytes and non-zero in the range"); 1202 case Match_InvalidSImm12: 1203 return generateImmOutOfRangeError( 1204 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1, 1205 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an " 1206 "integer in the range"); 1207 case Match_InvalidSImm12Lsb0: 1208 return generateImmOutOfRangeError( 1209 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2, 1210 "immediate must be a multiple of 2 bytes in the range"); 1211 case Match_InvalidSImm12Lsb00000: 1212 return generateImmOutOfRangeError( 1213 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 32, 1214 "immediate must be a multiple of 32 bytes in the range"); 1215 case Match_InvalidSImm13Lsb0: 1216 return generateImmOutOfRangeError( 1217 Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2, 1218 "immediate must be a multiple of 2 bytes in the range"); 1219 case Match_InvalidUImm20LUI: 1220 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1, 1221 "operand must be a symbol with " 1222 "%hi/%tprel_hi modifier or an integer in " 1223 "the range"); 1224 case Match_InvalidUImm20AUIPC: 1225 return generateImmOutOfRangeError( 1226 Operands, ErrorInfo, 0, (1 << 20) - 1, 1227 "operand must be a symbol with a " 1228 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or " 1229 "an integer in the range"); 1230 case Match_InvalidSImm21Lsb0JAL: 1231 return generateImmOutOfRangeError( 1232 Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2, 1233 "immediate must be a multiple of 2 bytes in the range"); 1234 case Match_InvalidCSRSystemRegister: { 1235 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1, 1236 "operand must be a valid system register " 1237 "name or an integer in the range"); 1238 } 1239 case Match_InvalidFenceArg: { 1240 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1241 return Error(ErrorLoc, "operand must be formed of letters selected " 1242 "in-order from 'iorw' or be 0"); 1243 } 1244 case Match_InvalidFRMArg: { 1245 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1246 return Error( 1247 ErrorLoc, 1248 "operand must be a valid floating point rounding mode mnemonic"); 1249 } 1250 case Match_InvalidBareSymbol: { 1251 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1252 return Error(ErrorLoc, "operand must be a bare symbol name"); 1253 } 1254 case Match_InvalidPseudoJumpSymbol: { 1255 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1256 return Error(ErrorLoc, "operand must be a valid jump target"); 1257 } 1258 case Match_InvalidCallSymbol: { 1259 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1260 return Error(ErrorLoc, "operand must be a bare symbol name"); 1261 } 1262 case Match_InvalidTPRelAddSymbol: { 1263 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1264 return Error(ErrorLoc, "operand must be a symbol with %tprel_add modifier"); 1265 } 1266 case Match_InvalidVTypeI: { 1267 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1268 return Error( 1269 ErrorLoc, 1270 "operand must be " 1271 "e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]"); 1272 } 1273 case Match_InvalidVMaskRegister: { 1274 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1275 return Error(ErrorLoc, "operand must be v0.t"); 1276 } 1277 case Match_InvalidSImm5Plus1: { 1278 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4) + 1, 1279 (1 << 4), 1280 "immediate must be in the range"); 1281 } 1282 case Match_InvalidRnumArg: { 1283 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 10); 1284 } 1285 } 1286 1287 llvm_unreachable("Unknown match type detected!"); 1288 } 1289 1290 // Attempts to match Name as a register (either using the default name or 1291 // alternative ABI names), setting RegNo to the matching register. Upon 1292 // failure, returns true and sets RegNo to 0. If IsRV32E then registers 1293 // x16-x31 will be rejected. 1294 static bool matchRegisterNameHelper(bool IsRV32E, MCRegister &RegNo, 1295 StringRef Name) { 1296 RegNo = MatchRegisterName(Name); 1297 // The 16-/32- and 64-bit FPRs have the same asm name. Check that the initial 1298 // match always matches the 64-bit variant, and not the 16/32-bit one. 1299 assert(!(RegNo >= RISCV::F0_H && RegNo <= RISCV::F31_H)); 1300 assert(!(RegNo >= RISCV::F0_F && RegNo <= RISCV::F31_F)); 1301 // The default FPR register class is based on the tablegen enum ordering. 1302 static_assert(RISCV::F0_D < RISCV::F0_H, "FPR matching must be updated"); 1303 static_assert(RISCV::F0_D < RISCV::F0_F, "FPR matching must be updated"); 1304 if (RegNo == RISCV::NoRegister) 1305 RegNo = MatchRegisterAltName(Name); 1306 if (IsRV32E && RegNo >= RISCV::X16 && RegNo <= RISCV::X31) 1307 RegNo = RISCV::NoRegister; 1308 return RegNo == RISCV::NoRegister; 1309 } 1310 1311 bool RISCVAsmParser::parseRegister(MCRegister &RegNo, SMLoc &StartLoc, 1312 SMLoc &EndLoc) { 1313 if (tryParseRegister(RegNo, StartLoc, EndLoc) != MatchOperand_Success) 1314 return Error(StartLoc, "invalid register name"); 1315 return false; 1316 } 1317 1318 OperandMatchResultTy RISCVAsmParser::tryParseRegister(MCRegister &RegNo, 1319 SMLoc &StartLoc, 1320 SMLoc &EndLoc) { 1321 const AsmToken &Tok = getParser().getTok(); 1322 StartLoc = Tok.getLoc(); 1323 EndLoc = Tok.getEndLoc(); 1324 RegNo = 0; 1325 StringRef Name = getLexer().getTok().getIdentifier(); 1326 1327 if (matchRegisterNameHelper(isRV32E(), (MCRegister &)RegNo, Name)) 1328 return MatchOperand_NoMatch; 1329 1330 getParser().Lex(); // Eat identifier token. 1331 return MatchOperand_Success; 1332 } 1333 1334 OperandMatchResultTy RISCVAsmParser::parseRegister(OperandVector &Operands, 1335 bool AllowParens) { 1336 SMLoc FirstS = getLoc(); 1337 bool HadParens = false; 1338 AsmToken LParen; 1339 1340 // If this is an LParen and a parenthesised register name is allowed, parse it 1341 // atomically. 1342 if (AllowParens && getLexer().is(AsmToken::LParen)) { 1343 AsmToken Buf[2]; 1344 size_t ReadCount = getLexer().peekTokens(Buf); 1345 if (ReadCount == 2 && Buf[1].getKind() == AsmToken::RParen) { 1346 HadParens = true; 1347 LParen = getParser().getTok(); 1348 getParser().Lex(); // Eat '(' 1349 } 1350 } 1351 1352 switch (getLexer().getKind()) { 1353 default: 1354 if (HadParens) 1355 getLexer().UnLex(LParen); 1356 return MatchOperand_NoMatch; 1357 case AsmToken::Identifier: 1358 StringRef Name = getLexer().getTok().getIdentifier(); 1359 MCRegister RegNo; 1360 matchRegisterNameHelper(isRV32E(), RegNo, Name); 1361 1362 if (RegNo == RISCV::NoRegister) { 1363 if (HadParens) 1364 getLexer().UnLex(LParen); 1365 return MatchOperand_NoMatch; 1366 } 1367 if (HadParens) 1368 Operands.push_back(RISCVOperand::createToken("(", FirstS, isRV64())); 1369 SMLoc S = getLoc(); 1370 SMLoc E = SMLoc::getFromPointer(S.getPointer() + Name.size()); 1371 getLexer().Lex(); 1372 Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64())); 1373 } 1374 1375 if (HadParens) { 1376 getParser().Lex(); // Eat ')' 1377 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64())); 1378 } 1379 1380 return MatchOperand_Success; 1381 } 1382 1383 OperandMatchResultTy 1384 RISCVAsmParser::parseInsnDirectiveOpcode(OperandVector &Operands) { 1385 SMLoc S = getLoc(); 1386 SMLoc E; 1387 const MCExpr *Res; 1388 1389 switch (getLexer().getKind()) { 1390 default: 1391 return MatchOperand_NoMatch; 1392 case AsmToken::LParen: 1393 case AsmToken::Minus: 1394 case AsmToken::Plus: 1395 case AsmToken::Exclaim: 1396 case AsmToken::Tilde: 1397 case AsmToken::Integer: 1398 case AsmToken::String: { 1399 if (getParser().parseExpression(Res, E)) 1400 return MatchOperand_ParseFail; 1401 1402 auto *CE = dyn_cast<MCConstantExpr>(Res); 1403 if (CE) { 1404 int64_t Imm = CE->getValue(); 1405 if (isUInt<7>(Imm)) { 1406 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1407 return MatchOperand_Success; 1408 } 1409 } 1410 1411 Twine Msg = "immediate must be an integer in the range"; 1412 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 7) - 1) + "]"); 1413 return MatchOperand_ParseFail; 1414 } 1415 case AsmToken::Identifier: { 1416 StringRef Identifier; 1417 if (getParser().parseIdentifier(Identifier)) 1418 return MatchOperand_ParseFail; 1419 1420 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier); 1421 if (Opcode) { 1422 Res = MCConstantExpr::create(Opcode->Value, getContext()); 1423 E = SMLoc::getFromPointer(S.getPointer() + Identifier.size()); 1424 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1425 return MatchOperand_Success; 1426 } 1427 1428 Twine Msg = "operand must be a valid opcode name or an " 1429 "integer in the range"; 1430 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 7) - 1) + "]"); 1431 return MatchOperand_ParseFail; 1432 } 1433 case AsmToken::Percent: { 1434 // Discard operand with modifier. 1435 Twine Msg = "immediate must be an integer in the range"; 1436 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 7) - 1) + "]"); 1437 return MatchOperand_ParseFail; 1438 } 1439 } 1440 1441 return MatchOperand_NoMatch; 1442 } 1443 1444 OperandMatchResultTy 1445 RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) { 1446 SMLoc S = getLoc(); 1447 const MCExpr *Res; 1448 1449 switch (getLexer().getKind()) { 1450 default: 1451 return MatchOperand_NoMatch; 1452 case AsmToken::LParen: 1453 case AsmToken::Minus: 1454 case AsmToken::Plus: 1455 case AsmToken::Exclaim: 1456 case AsmToken::Tilde: 1457 case AsmToken::Integer: 1458 case AsmToken::String: { 1459 if (getParser().parseExpression(Res)) 1460 return MatchOperand_ParseFail; 1461 1462 auto *CE = dyn_cast<MCConstantExpr>(Res); 1463 if (CE) { 1464 int64_t Imm = CE->getValue(); 1465 if (isUInt<12>(Imm)) { 1466 auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm); 1467 // Accept an immediate representing a named or un-named Sys Reg 1468 // if the range is valid, regardless of the required features. 1469 Operands.push_back(RISCVOperand::createSysReg( 1470 SysReg ? SysReg->Name : "", S, Imm, isRV64())); 1471 return MatchOperand_Success; 1472 } 1473 } 1474 1475 Twine Msg = "immediate must be an integer in the range"; 1476 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]"); 1477 return MatchOperand_ParseFail; 1478 } 1479 case AsmToken::Identifier: { 1480 StringRef Identifier; 1481 if (getParser().parseIdentifier(Identifier)) 1482 return MatchOperand_ParseFail; 1483 1484 auto SysReg = RISCVSysReg::lookupSysRegByName(Identifier); 1485 if (!SysReg) 1486 SysReg = RISCVSysReg::lookupSysRegByAltName(Identifier); 1487 if (!SysReg) 1488 if ((SysReg = RISCVSysReg::lookupSysRegByDeprecatedName(Identifier))) 1489 Warning(S, "'" + Identifier + "' is a deprecated alias for '" + 1490 SysReg->Name + "'"); 1491 1492 // Accept a named Sys Reg if the required features are present. 1493 if (SysReg) { 1494 if (!SysReg->haveRequiredFeatures(getSTI().getFeatureBits())) { 1495 Error(S, "system register use requires an option to be enabled"); 1496 return MatchOperand_ParseFail; 1497 } 1498 Operands.push_back(RISCVOperand::createSysReg( 1499 Identifier, S, SysReg->Encoding, isRV64())); 1500 return MatchOperand_Success; 1501 } 1502 1503 Twine Msg = "operand must be a valid system register name " 1504 "or an integer in the range"; 1505 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]"); 1506 return MatchOperand_ParseFail; 1507 } 1508 case AsmToken::Percent: { 1509 // Discard operand with modifier. 1510 Twine Msg = "immediate must be an integer in the range"; 1511 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]"); 1512 return MatchOperand_ParseFail; 1513 } 1514 } 1515 1516 return MatchOperand_NoMatch; 1517 } 1518 1519 OperandMatchResultTy RISCVAsmParser::parseImmediate(OperandVector &Operands) { 1520 SMLoc S = getLoc(); 1521 SMLoc E; 1522 const MCExpr *Res; 1523 1524 switch (getLexer().getKind()) { 1525 default: 1526 return MatchOperand_NoMatch; 1527 case AsmToken::LParen: 1528 case AsmToken::Dot: 1529 case AsmToken::Minus: 1530 case AsmToken::Plus: 1531 case AsmToken::Exclaim: 1532 case AsmToken::Tilde: 1533 case AsmToken::Integer: 1534 case AsmToken::String: 1535 case AsmToken::Identifier: 1536 if (getParser().parseExpression(Res, E)) 1537 return MatchOperand_ParseFail; 1538 break; 1539 case AsmToken::Percent: 1540 return parseOperandWithModifier(Operands); 1541 } 1542 1543 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1544 return MatchOperand_Success; 1545 } 1546 1547 OperandMatchResultTy 1548 RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) { 1549 SMLoc S = getLoc(); 1550 SMLoc E; 1551 1552 if (getLexer().getKind() != AsmToken::Percent) { 1553 Error(getLoc(), "expected '%' for operand modifier"); 1554 return MatchOperand_ParseFail; 1555 } 1556 1557 getParser().Lex(); // Eat '%' 1558 1559 if (getLexer().getKind() != AsmToken::Identifier) { 1560 Error(getLoc(), "expected valid identifier for operand modifier"); 1561 return MatchOperand_ParseFail; 1562 } 1563 StringRef Identifier = getParser().getTok().getIdentifier(); 1564 RISCVMCExpr::VariantKind VK = RISCVMCExpr::getVariantKindForName(Identifier); 1565 if (VK == RISCVMCExpr::VK_RISCV_Invalid) { 1566 Error(getLoc(), "unrecognized operand modifier"); 1567 return MatchOperand_ParseFail; 1568 } 1569 1570 getParser().Lex(); // Eat the identifier 1571 if (getLexer().getKind() != AsmToken::LParen) { 1572 Error(getLoc(), "expected '('"); 1573 return MatchOperand_ParseFail; 1574 } 1575 getParser().Lex(); // Eat '(' 1576 1577 const MCExpr *SubExpr; 1578 if (getParser().parseParenExpression(SubExpr, E)) { 1579 return MatchOperand_ParseFail; 1580 } 1581 1582 const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, VK, getContext()); 1583 Operands.push_back(RISCVOperand::createImm(ModExpr, S, E, isRV64())); 1584 return MatchOperand_Success; 1585 } 1586 1587 OperandMatchResultTy RISCVAsmParser::parseBareSymbol(OperandVector &Operands) { 1588 SMLoc S = getLoc(); 1589 const MCExpr *Res; 1590 1591 if (getLexer().getKind() != AsmToken::Identifier) 1592 return MatchOperand_NoMatch; 1593 1594 StringRef Identifier; 1595 AsmToken Tok = getLexer().getTok(); 1596 1597 if (getParser().parseIdentifier(Identifier)) 1598 return MatchOperand_ParseFail; 1599 1600 SMLoc E = SMLoc::getFromPointer(S.getPointer() + Identifier.size()); 1601 1602 if (Identifier.consume_back("@plt")) { 1603 Error(getLoc(), "'@plt' operand not valid for instruction"); 1604 return MatchOperand_ParseFail; 1605 } 1606 1607 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); 1608 1609 if (Sym->isVariable()) { 1610 const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false); 1611 if (!isa<MCSymbolRefExpr>(V)) { 1612 getLexer().UnLex(Tok); // Put back if it's not a bare symbol. 1613 return MatchOperand_NoMatch; 1614 } 1615 Res = V; 1616 } else 1617 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1618 1619 MCBinaryExpr::Opcode Opcode; 1620 switch (getLexer().getKind()) { 1621 default: 1622 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1623 return MatchOperand_Success; 1624 case AsmToken::Plus: 1625 Opcode = MCBinaryExpr::Add; 1626 getLexer().Lex(); 1627 break; 1628 case AsmToken::Minus: 1629 Opcode = MCBinaryExpr::Sub; 1630 getLexer().Lex(); 1631 break; 1632 } 1633 1634 const MCExpr *Expr; 1635 if (getParser().parseExpression(Expr, E)) 1636 return MatchOperand_ParseFail; 1637 Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext()); 1638 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1639 return MatchOperand_Success; 1640 } 1641 1642 OperandMatchResultTy RISCVAsmParser::parseCallSymbol(OperandVector &Operands) { 1643 SMLoc S = getLoc(); 1644 const MCExpr *Res; 1645 1646 if (getLexer().getKind() != AsmToken::Identifier) 1647 return MatchOperand_NoMatch; 1648 1649 // Avoid parsing the register in `call rd, foo` as a call symbol. 1650 if (getLexer().peekTok().getKind() != AsmToken::EndOfStatement) 1651 return MatchOperand_NoMatch; 1652 1653 StringRef Identifier; 1654 if (getParser().parseIdentifier(Identifier)) 1655 return MatchOperand_ParseFail; 1656 1657 SMLoc E = SMLoc::getFromPointer(S.getPointer() + Identifier.size()); 1658 1659 RISCVMCExpr::VariantKind Kind = RISCVMCExpr::VK_RISCV_CALL; 1660 if (Identifier.consume_back("@plt")) 1661 Kind = RISCVMCExpr::VK_RISCV_CALL_PLT; 1662 1663 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); 1664 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1665 Res = RISCVMCExpr::create(Res, Kind, getContext()); 1666 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1667 return MatchOperand_Success; 1668 } 1669 1670 OperandMatchResultTy 1671 RISCVAsmParser::parsePseudoJumpSymbol(OperandVector &Operands) { 1672 SMLoc S = getLoc(); 1673 SMLoc E; 1674 const MCExpr *Res; 1675 1676 if (getParser().parseExpression(Res, E)) 1677 return MatchOperand_ParseFail; 1678 1679 if (Res->getKind() != MCExpr::ExprKind::SymbolRef || 1680 cast<MCSymbolRefExpr>(Res)->getKind() == 1681 MCSymbolRefExpr::VariantKind::VK_PLT) { 1682 Error(S, "operand must be a valid jump target"); 1683 return MatchOperand_ParseFail; 1684 } 1685 1686 Res = RISCVMCExpr::create(Res, RISCVMCExpr::VK_RISCV_CALL, getContext()); 1687 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1688 return MatchOperand_Success; 1689 } 1690 1691 OperandMatchResultTy RISCVAsmParser::parseJALOffset(OperandVector &Operands) { 1692 // Parsing jal operands is fiddly due to the `jal foo` and `jal ra, foo` 1693 // both being acceptable forms. When parsing `jal ra, foo` this function 1694 // will be called for the `ra` register operand in an attempt to match the 1695 // single-operand alias. parseJALOffset must fail for this case. It would 1696 // seem logical to try parse the operand using parseImmediate and return 1697 // NoMatch if the next token is a comma (meaning we must be parsing a jal in 1698 // the second form rather than the first). We can't do this as there's no 1699 // way of rewinding the lexer state. Instead, return NoMatch if this operand 1700 // is an identifier and is followed by a comma. 1701 if (getLexer().is(AsmToken::Identifier) && 1702 getLexer().peekTok().is(AsmToken::Comma)) 1703 return MatchOperand_NoMatch; 1704 1705 return parseImmediate(Operands); 1706 } 1707 1708 OperandMatchResultTy RISCVAsmParser::parseVTypeI(OperandVector &Operands) { 1709 SMLoc S = getLoc(); 1710 if (getLexer().isNot(AsmToken::Identifier)) 1711 return MatchOperand_NoMatch; 1712 1713 SmallVector<AsmToken, 7> VTypeIElements; 1714 // Put all the tokens for vtypei operand into VTypeIElements vector. 1715 while (getLexer().isNot(AsmToken::EndOfStatement)) { 1716 VTypeIElements.push_back(getLexer().getTok()); 1717 getLexer().Lex(); 1718 if (getLexer().is(AsmToken::EndOfStatement)) 1719 break; 1720 if (getLexer().isNot(AsmToken::Comma)) 1721 goto MatchFail; 1722 AsmToken Comma = getLexer().getTok(); 1723 VTypeIElements.push_back(Comma); 1724 getLexer().Lex(); 1725 } 1726 1727 if (VTypeIElements.size() == 7) { 1728 // The VTypeIElements layout is: 1729 // SEW comma LMUL comma TA comma MA 1730 // 0 1 2 3 4 5 6 1731 StringRef Name = VTypeIElements[0].getIdentifier(); 1732 if (!Name.consume_front("e")) 1733 goto MatchFail; 1734 unsigned Sew; 1735 if (Name.getAsInteger(10, Sew)) 1736 goto MatchFail; 1737 if (!RISCVVType::isValidSEW(Sew)) 1738 goto MatchFail; 1739 1740 Name = VTypeIElements[2].getIdentifier(); 1741 if (!Name.consume_front("m")) 1742 goto MatchFail; 1743 // "m" or "mf" 1744 bool Fractional = Name.consume_front("f"); 1745 unsigned Lmul; 1746 if (Name.getAsInteger(10, Lmul)) 1747 goto MatchFail; 1748 if (!RISCVVType::isValidLMUL(Lmul, Fractional)) 1749 goto MatchFail; 1750 1751 // ta or tu 1752 Name = VTypeIElements[4].getIdentifier(); 1753 bool TailAgnostic; 1754 if (Name == "ta") 1755 TailAgnostic = true; 1756 else if (Name == "tu") 1757 TailAgnostic = false; 1758 else 1759 goto MatchFail; 1760 1761 // ma or mu 1762 Name = VTypeIElements[6].getIdentifier(); 1763 bool MaskAgnostic; 1764 if (Name == "ma") 1765 MaskAgnostic = true; 1766 else if (Name == "mu") 1767 MaskAgnostic = false; 1768 else 1769 goto MatchFail; 1770 1771 RISCVII::VLMUL VLMUL = RISCVVType::encodeLMUL(Lmul, Fractional); 1772 1773 unsigned VTypeI = 1774 RISCVVType::encodeVTYPE(VLMUL, Sew, TailAgnostic, MaskAgnostic); 1775 Operands.push_back(RISCVOperand::createVType(VTypeI, S, isRV64())); 1776 return MatchOperand_Success; 1777 } 1778 1779 // If NoMatch, unlex all the tokens that comprise a vtypei operand 1780 MatchFail: 1781 while (!VTypeIElements.empty()) 1782 getLexer().UnLex(VTypeIElements.pop_back_val()); 1783 return MatchOperand_NoMatch; 1784 } 1785 1786 OperandMatchResultTy RISCVAsmParser::parseMaskReg(OperandVector &Operands) { 1787 switch (getLexer().getKind()) { 1788 default: 1789 return MatchOperand_NoMatch; 1790 case AsmToken::Identifier: 1791 StringRef Name = getLexer().getTok().getIdentifier(); 1792 if (!Name.consume_back(".t")) { 1793 Error(getLoc(), "expected '.t' suffix"); 1794 return MatchOperand_ParseFail; 1795 } 1796 MCRegister RegNo; 1797 matchRegisterNameHelper(isRV32E(), RegNo, Name); 1798 1799 if (RegNo == RISCV::NoRegister) 1800 return MatchOperand_NoMatch; 1801 if (RegNo != RISCV::V0) 1802 return MatchOperand_NoMatch; 1803 SMLoc S = getLoc(); 1804 SMLoc E = SMLoc::getFromPointer(S.getPointer() + Name.size()); 1805 getLexer().Lex(); 1806 Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64())); 1807 } 1808 1809 return MatchOperand_Success; 1810 } 1811 1812 OperandMatchResultTy RISCVAsmParser::parseGPRAsFPR(OperandVector &Operands) { 1813 switch (getLexer().getKind()) { 1814 default: 1815 return MatchOperand_NoMatch; 1816 case AsmToken::Identifier: 1817 StringRef Name = getLexer().getTok().getIdentifier(); 1818 MCRegister RegNo; 1819 matchRegisterNameHelper(isRV32E(), RegNo, Name); 1820 1821 if (RegNo == RISCV::NoRegister) 1822 return MatchOperand_NoMatch; 1823 SMLoc S = getLoc(); 1824 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1825 getLexer().Lex(); 1826 Operands.push_back(RISCVOperand::createReg( 1827 RegNo, S, E, isRV64(), !getSTI().hasFeature(RISCV::FeatureStdExtF))); 1828 } 1829 return MatchOperand_Success; 1830 } 1831 1832 OperandMatchResultTy 1833 RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) { 1834 if (getLexer().isNot(AsmToken::LParen)) { 1835 Error(getLoc(), "expected '('"); 1836 return MatchOperand_ParseFail; 1837 } 1838 1839 getParser().Lex(); // Eat '(' 1840 Operands.push_back(RISCVOperand::createToken("(", getLoc(), isRV64())); 1841 1842 if (parseRegister(Operands) != MatchOperand_Success) { 1843 Error(getLoc(), "expected register"); 1844 return MatchOperand_ParseFail; 1845 } 1846 1847 if (getLexer().isNot(AsmToken::RParen)) { 1848 Error(getLoc(), "expected ')'"); 1849 return MatchOperand_ParseFail; 1850 } 1851 1852 getParser().Lex(); // Eat ')' 1853 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64())); 1854 1855 return MatchOperand_Success; 1856 } 1857 1858 OperandMatchResultTy 1859 RISCVAsmParser::parseZeroOffsetMemOp(OperandVector &Operands) { 1860 // Atomic operations such as lr.w, sc.w, and amo*.w accept a "memory operand" 1861 // as one of their register operands, such as `(a0)`. This just denotes that 1862 // the register (in this case `a0`) contains a memory address. 1863 // 1864 // Normally, we would be able to parse these by putting the parens into the 1865 // instruction string. However, GNU as also accepts a zero-offset memory 1866 // operand (such as `0(a0)`), and ignores the 0. Normally this would be parsed 1867 // with parseImmediate followed by parseMemOpBaseReg, but these instructions 1868 // do not accept an immediate operand, and we do not want to add a "dummy" 1869 // operand that is silently dropped. 1870 // 1871 // Instead, we use this custom parser. This will: allow (and discard) an 1872 // offset if it is zero; require (and discard) parentheses; and add only the 1873 // parsed register operand to `Operands`. 1874 // 1875 // These operands are printed with RISCVInstPrinter::printZeroOffsetMemOp, 1876 // which will only print the register surrounded by parentheses (which GNU as 1877 // also uses as its canonical representation for these operands). 1878 std::unique_ptr<RISCVOperand> OptionalImmOp; 1879 1880 if (getLexer().isNot(AsmToken::LParen)) { 1881 // Parse an Integer token. We do not accept arbritrary constant expressions 1882 // in the offset field (because they may include parens, which complicates 1883 // parsing a lot). 1884 int64_t ImmVal; 1885 SMLoc ImmStart = getLoc(); 1886 if (getParser().parseIntToken(ImmVal, 1887 "expected '(' or optional integer offset")) 1888 return MatchOperand_ParseFail; 1889 1890 // Create a RISCVOperand for checking later (so the error messages are 1891 // nicer), but we don't add it to Operands. 1892 SMLoc ImmEnd = getLoc(); 1893 OptionalImmOp = 1894 RISCVOperand::createImm(MCConstantExpr::create(ImmVal, getContext()), 1895 ImmStart, ImmEnd, isRV64()); 1896 } 1897 1898 if (getLexer().isNot(AsmToken::LParen)) { 1899 Error(getLoc(), OptionalImmOp ? "expected '(' after optional integer offset" 1900 : "expected '(' or optional integer offset"); 1901 return MatchOperand_ParseFail; 1902 } 1903 getParser().Lex(); // Eat '(' 1904 1905 if (parseRegister(Operands) != MatchOperand_Success) { 1906 Error(getLoc(), "expected register"); 1907 return MatchOperand_ParseFail; 1908 } 1909 1910 if (getLexer().isNot(AsmToken::RParen)) { 1911 Error(getLoc(), "expected ')'"); 1912 return MatchOperand_ParseFail; 1913 } 1914 getParser().Lex(); // Eat ')' 1915 1916 // Deferred Handling of non-zero offsets. This makes the error messages nicer. 1917 if (OptionalImmOp && !OptionalImmOp->isImmZero()) { 1918 Error(OptionalImmOp->getStartLoc(), "optional integer offset must be 0", 1919 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc())); 1920 return MatchOperand_ParseFail; 1921 } 1922 1923 return MatchOperand_Success; 1924 } 1925 1926 /// Looks at a token type and creates the relevant operand from this 1927 /// information, adding to Operands. If operand was parsed, returns false, else 1928 /// true. 1929 bool RISCVAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { 1930 // Check if the current operand has a custom associated parser, if so, try to 1931 // custom parse the operand, or fallback to the general approach. 1932 OperandMatchResultTy Result = 1933 MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true); 1934 if (Result == MatchOperand_Success) 1935 return false; 1936 if (Result == MatchOperand_ParseFail) 1937 return true; 1938 1939 // Attempt to parse token as a register. 1940 if (parseRegister(Operands, true) == MatchOperand_Success) 1941 return false; 1942 1943 // Attempt to parse token as an immediate 1944 if (parseImmediate(Operands) == MatchOperand_Success) { 1945 // Parse memory base register if present 1946 if (getLexer().is(AsmToken::LParen)) 1947 return parseMemOpBaseReg(Operands) != MatchOperand_Success; 1948 return false; 1949 } 1950 1951 // Finally we have exhausted all options and must declare defeat. 1952 Error(getLoc(), "unknown operand"); 1953 return true; 1954 } 1955 1956 bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info, 1957 StringRef Name, SMLoc NameLoc, 1958 OperandVector &Operands) { 1959 // Ensure that if the instruction occurs when relaxation is enabled, 1960 // relocations are forced for the file. Ideally this would be done when there 1961 // is enough information to reliably determine if the instruction itself may 1962 // cause relaxations. Unfortunately instruction processing stage occurs in the 1963 // same pass as relocation emission, so it's too late to set a 'sticky bit' 1964 // for the entire file. 1965 if (getSTI().getFeatureBits()[RISCV::FeatureRelax]) { 1966 auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr(); 1967 if (Assembler != nullptr) { 1968 RISCVAsmBackend &MAB = 1969 static_cast<RISCVAsmBackend &>(Assembler->getBackend()); 1970 MAB.setForceRelocs(); 1971 } 1972 } 1973 1974 // First operand is token for instruction 1975 Operands.push_back(RISCVOperand::createToken(Name, NameLoc, isRV64())); 1976 1977 // If there are no more operands, then finish 1978 if (getLexer().is(AsmToken::EndOfStatement)) { 1979 getParser().Lex(); // Consume the EndOfStatement. 1980 return false; 1981 } 1982 1983 // Parse first operand 1984 if (parseOperand(Operands, Name)) 1985 return true; 1986 1987 // Parse until end of statement, consuming commas between operands 1988 while (getLexer().is(AsmToken::Comma)) { 1989 // Consume comma token 1990 getLexer().Lex(); 1991 1992 // Parse next operand 1993 if (parseOperand(Operands, Name)) 1994 return true; 1995 } 1996 1997 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1998 SMLoc Loc = getLexer().getLoc(); 1999 getParser().eatToEndOfStatement(); 2000 return Error(Loc, "unexpected token"); 2001 } 2002 2003 getParser().Lex(); // Consume the EndOfStatement. 2004 return false; 2005 } 2006 2007 bool RISCVAsmParser::classifySymbolRef(const MCExpr *Expr, 2008 RISCVMCExpr::VariantKind &Kind) { 2009 Kind = RISCVMCExpr::VK_RISCV_None; 2010 2011 if (const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) { 2012 Kind = RE->getKind(); 2013 Expr = RE->getSubExpr(); 2014 } 2015 2016 MCValue Res; 2017 MCFixup Fixup; 2018 if (Expr->evaluateAsRelocatable(Res, nullptr, &Fixup)) 2019 return Res.getRefKind() == RISCVMCExpr::VK_RISCV_None; 2020 return false; 2021 } 2022 2023 bool RISCVAsmParser::ParseDirective(AsmToken DirectiveID) { 2024 // This returns false if this function recognizes the directive 2025 // regardless of whether it is successfully handles or reports an 2026 // error. Otherwise it returns true to give the generic parser a 2027 // chance at recognizing it. 2028 StringRef IDVal = DirectiveID.getString(); 2029 2030 if (IDVal == ".option") 2031 return parseDirectiveOption(); 2032 if (IDVal == ".attribute") 2033 return parseDirectiveAttribute(); 2034 if (IDVal == ".insn") 2035 return parseDirectiveInsn(DirectiveID.getLoc()); 2036 if (IDVal == ".variant_cc") 2037 return parseDirectiveVariantCC(); 2038 2039 return true; 2040 } 2041 2042 bool RISCVAsmParser::parseDirectiveOption() { 2043 MCAsmParser &Parser = getParser(); 2044 // Get the option token. 2045 AsmToken Tok = Parser.getTok(); 2046 // At the moment only identifiers are supported. 2047 if (Tok.isNot(AsmToken::Identifier)) 2048 return Error(Parser.getTok().getLoc(), 2049 "unexpected token, expected identifier"); 2050 2051 StringRef Option = Tok.getIdentifier(); 2052 2053 if (Option == "push") { 2054 getTargetStreamer().emitDirectiveOptionPush(); 2055 2056 Parser.Lex(); 2057 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 2058 return Error(Parser.getTok().getLoc(), 2059 "unexpected token, expected end of statement"); 2060 2061 pushFeatureBits(); 2062 return false; 2063 } 2064 2065 if (Option == "pop") { 2066 SMLoc StartLoc = Parser.getTok().getLoc(); 2067 getTargetStreamer().emitDirectiveOptionPop(); 2068 2069 Parser.Lex(); 2070 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 2071 return Error(Parser.getTok().getLoc(), 2072 "unexpected token, expected end of statement"); 2073 2074 if (popFeatureBits()) 2075 return Error(StartLoc, ".option pop with no .option push"); 2076 2077 return false; 2078 } 2079 2080 if (Option == "rvc") { 2081 getTargetStreamer().emitDirectiveOptionRVC(); 2082 2083 Parser.Lex(); 2084 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 2085 return Error(Parser.getTok().getLoc(), 2086 "unexpected token, expected end of statement"); 2087 2088 setFeatureBits(RISCV::FeatureStdExtC, "c"); 2089 return false; 2090 } 2091 2092 if (Option == "norvc") { 2093 getTargetStreamer().emitDirectiveOptionNoRVC(); 2094 2095 Parser.Lex(); 2096 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 2097 return Error(Parser.getTok().getLoc(), 2098 "unexpected token, expected end of statement"); 2099 2100 clearFeatureBits(RISCV::FeatureStdExtC, "c"); 2101 clearFeatureBits(RISCV::FeatureExtZca, "+experimental-zca"); 2102 return false; 2103 } 2104 2105 if (Option == "pic") { 2106 getTargetStreamer().emitDirectiveOptionPIC(); 2107 2108 Parser.Lex(); 2109 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 2110 return Error(Parser.getTok().getLoc(), 2111 "unexpected token, expected end of statement"); 2112 2113 ParserOptions.IsPicEnabled = true; 2114 return false; 2115 } 2116 2117 if (Option == "nopic") { 2118 getTargetStreamer().emitDirectiveOptionNoPIC(); 2119 2120 Parser.Lex(); 2121 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 2122 return Error(Parser.getTok().getLoc(), 2123 "unexpected token, expected end of statement"); 2124 2125 ParserOptions.IsPicEnabled = false; 2126 return false; 2127 } 2128 2129 if (Option == "relax") { 2130 getTargetStreamer().emitDirectiveOptionRelax(); 2131 2132 Parser.Lex(); 2133 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 2134 return Error(Parser.getTok().getLoc(), 2135 "unexpected token, expected end of statement"); 2136 2137 setFeatureBits(RISCV::FeatureRelax, "relax"); 2138 return false; 2139 } 2140 2141 if (Option == "norelax") { 2142 getTargetStreamer().emitDirectiveOptionNoRelax(); 2143 2144 Parser.Lex(); 2145 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 2146 return Error(Parser.getTok().getLoc(), 2147 "unexpected token, expected end of statement"); 2148 2149 clearFeatureBits(RISCV::FeatureRelax, "relax"); 2150 return false; 2151 } 2152 2153 // Unknown option. 2154 Warning(Parser.getTok().getLoc(), 2155 "unknown option, expected 'push', 'pop', 'rvc', 'norvc', 'relax' or " 2156 "'norelax'"); 2157 Parser.eatToEndOfStatement(); 2158 return false; 2159 } 2160 2161 /// parseDirectiveAttribute 2162 /// ::= .attribute expression ',' ( expression | "string" ) 2163 /// ::= .attribute identifier ',' ( expression | "string" ) 2164 bool RISCVAsmParser::parseDirectiveAttribute() { 2165 MCAsmParser &Parser = getParser(); 2166 int64_t Tag; 2167 SMLoc TagLoc; 2168 TagLoc = Parser.getTok().getLoc(); 2169 if (Parser.getTok().is(AsmToken::Identifier)) { 2170 StringRef Name = Parser.getTok().getIdentifier(); 2171 std::optional<unsigned> Ret = 2172 ELFAttrs::attrTypeFromString(Name, RISCVAttrs::getRISCVAttributeTags()); 2173 if (!Ret) { 2174 Error(TagLoc, "attribute name not recognised: " + Name); 2175 return false; 2176 } 2177 Tag = *Ret; 2178 Parser.Lex(); 2179 } else { 2180 const MCExpr *AttrExpr; 2181 2182 TagLoc = Parser.getTok().getLoc(); 2183 if (Parser.parseExpression(AttrExpr)) 2184 return true; 2185 2186 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr); 2187 if (check(!CE, TagLoc, "expected numeric constant")) 2188 return true; 2189 2190 Tag = CE->getValue(); 2191 } 2192 2193 if (Parser.parseToken(AsmToken::Comma, "comma expected")) 2194 return true; 2195 2196 StringRef StringValue; 2197 int64_t IntegerValue = 0; 2198 bool IsIntegerValue = true; 2199 2200 // RISC-V attributes have a string value if the tag number is odd 2201 // and an integer value if the tag number is even. 2202 if (Tag % 2) 2203 IsIntegerValue = false; 2204 2205 SMLoc ValueExprLoc = Parser.getTok().getLoc(); 2206 if (IsIntegerValue) { 2207 const MCExpr *ValueExpr; 2208 if (Parser.parseExpression(ValueExpr)) 2209 return true; 2210 2211 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr); 2212 if (!CE) 2213 return Error(ValueExprLoc, "expected numeric constant"); 2214 IntegerValue = CE->getValue(); 2215 } else { 2216 if (Parser.getTok().isNot(AsmToken::String)) 2217 return Error(Parser.getTok().getLoc(), "expected string constant"); 2218 2219 StringValue = Parser.getTok().getStringContents(); 2220 Parser.Lex(); 2221 } 2222 2223 if (Parser.parseEOL()) 2224 return true; 2225 2226 if (IsIntegerValue) 2227 getTargetStreamer().emitAttribute(Tag, IntegerValue); 2228 else if (Tag != RISCVAttrs::ARCH) 2229 getTargetStreamer().emitTextAttribute(Tag, StringValue); 2230 else { 2231 StringRef Arch = StringValue; 2232 for (auto Feature : RISCVFeatureKV) 2233 if (llvm::RISCVISAInfo::isSupportedExtensionFeature(Feature.Key)) 2234 clearFeatureBits(Feature.Value, Feature.Key); 2235 2236 auto ParseResult = llvm::RISCVISAInfo::parseArchString( 2237 StringValue, /*EnableExperimentalExtension=*/true, 2238 /*ExperimentalExtensionVersionCheck=*/true); 2239 if (!ParseResult) { 2240 std::string Buffer; 2241 raw_string_ostream OutputErrMsg(Buffer); 2242 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) { 2243 OutputErrMsg << "invalid arch name '" << Arch << "', " 2244 << ErrMsg.getMessage(); 2245 }); 2246 2247 return Error(ValueExprLoc, OutputErrMsg.str()); 2248 } 2249 auto &ISAInfo = *ParseResult; 2250 2251 for (auto Feature : RISCVFeatureKV) 2252 if (ISAInfo->hasExtension(Feature.Key)) 2253 setFeatureBits(Feature.Value, Feature.Key); 2254 2255 if (ISAInfo->getXLen() == 32) 2256 clearFeatureBits(RISCV::Feature64Bit, "64bit"); 2257 else if (ISAInfo->getXLen() == 64) 2258 setFeatureBits(RISCV::Feature64Bit, "64bit"); 2259 else 2260 return Error(ValueExprLoc, "bad arch string " + Arch); 2261 2262 // Then emit the arch string. 2263 getTargetStreamer().emitTextAttribute(Tag, ISAInfo->toString()); 2264 } 2265 2266 return false; 2267 } 2268 2269 /// parseDirectiveInsn 2270 /// ::= .insn [ format encoding, (operands (, operands)*) ] 2271 bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) { 2272 MCAsmParser &Parser = getParser(); 2273 2274 // Expect instruction format as identifier. 2275 StringRef Format; 2276 SMLoc ErrorLoc = Parser.getTok().getLoc(); 2277 if (Parser.parseIdentifier(Format)) 2278 return Error(ErrorLoc, "expected instruction format"); 2279 2280 if (Format != "r" && Format != "r4" && Format != "i" && Format != "b" && 2281 Format != "sb" && Format != "u" && Format != "j" && Format != "uj" && 2282 Format != "s") 2283 return Error(ErrorLoc, "invalid instruction format"); 2284 2285 std::string FormatName = (".insn_" + Format).str(); 2286 2287 ParseInstructionInfo Info; 2288 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> Operands; 2289 2290 if (ParseInstruction(Info, FormatName, L, Operands)) 2291 return true; 2292 2293 unsigned Opcode; 2294 uint64_t ErrorInfo; 2295 return MatchAndEmitInstruction(L, Opcode, Operands, Parser.getStreamer(), 2296 ErrorInfo, 2297 /*MatchingInlineAsm=*/false); 2298 } 2299 2300 /// parseDirectiveVariantCC 2301 /// ::= .variant_cc symbol 2302 bool RISCVAsmParser::parseDirectiveVariantCC() { 2303 StringRef Name; 2304 if (getParser().parseIdentifier(Name)) 2305 return TokError("expected symbol name"); 2306 if (parseEOL()) 2307 return false; 2308 getTargetStreamer().emitDirectiveVariantCC( 2309 *getContext().getOrCreateSymbol(Name)); 2310 return false; 2311 } 2312 2313 void RISCVAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) { 2314 MCInst CInst; 2315 bool Res = RISCVRVC::compress(CInst, Inst, getSTI()); 2316 if (Res) 2317 ++RISCVNumInstrsCompressed; 2318 S.emitInstruction((Res ? CInst : Inst), getSTI()); 2319 } 2320 2321 void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t Value, 2322 MCStreamer &Out) { 2323 RISCVMatInt::InstSeq Seq = 2324 RISCVMatInt::generateInstSeq(Value, getSTI().getFeatureBits()); 2325 2326 MCRegister SrcReg = RISCV::X0; 2327 for (RISCVMatInt::Inst &Inst : Seq) { 2328 switch (Inst.getOpndKind()) { 2329 case RISCVMatInt::Imm: 2330 emitToStreamer(Out, 2331 MCInstBuilder(Inst.getOpcode()).addReg(DestReg).addImm(Inst.getImm())); 2332 break; 2333 case RISCVMatInt::RegX0: 2334 emitToStreamer( 2335 Out, MCInstBuilder(Inst.getOpcode()).addReg(DestReg).addReg(SrcReg).addReg( 2336 RISCV::X0)); 2337 break; 2338 case RISCVMatInt::RegReg: 2339 emitToStreamer( 2340 Out, MCInstBuilder(Inst.getOpcode()).addReg(DestReg).addReg(SrcReg).addReg( 2341 SrcReg)); 2342 break; 2343 case RISCVMatInt::RegImm: 2344 emitToStreamer( 2345 Out, MCInstBuilder(Inst.getOpcode()).addReg(DestReg).addReg(SrcReg).addImm( 2346 Inst.getImm())); 2347 break; 2348 } 2349 2350 // Only the first instruction has X0 as its source. 2351 SrcReg = DestReg; 2352 } 2353 } 2354 2355 void RISCVAsmParser::emitAuipcInstPair(MCOperand DestReg, MCOperand TmpReg, 2356 const MCExpr *Symbol, 2357 RISCVMCExpr::VariantKind VKHi, 2358 unsigned SecondOpcode, SMLoc IDLoc, 2359 MCStreamer &Out) { 2360 // A pair of instructions for PC-relative addressing; expands to 2361 // TmpLabel: AUIPC TmpReg, VKHi(symbol) 2362 // OP DestReg, TmpReg, %pcrel_lo(TmpLabel) 2363 MCContext &Ctx = getContext(); 2364 2365 MCSymbol *TmpLabel = Ctx.createNamedTempSymbol("pcrel_hi"); 2366 Out.emitLabel(TmpLabel); 2367 2368 const RISCVMCExpr *SymbolHi = RISCVMCExpr::create(Symbol, VKHi, Ctx); 2369 emitToStreamer( 2370 Out, MCInstBuilder(RISCV::AUIPC).addOperand(TmpReg).addExpr(SymbolHi)); 2371 2372 const MCExpr *RefToLinkTmpLabel = 2373 RISCVMCExpr::create(MCSymbolRefExpr::create(TmpLabel, Ctx), 2374 RISCVMCExpr::VK_RISCV_PCREL_LO, Ctx); 2375 2376 emitToStreamer(Out, MCInstBuilder(SecondOpcode) 2377 .addOperand(DestReg) 2378 .addOperand(TmpReg) 2379 .addExpr(RefToLinkTmpLabel)); 2380 } 2381 2382 void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, 2383 MCStreamer &Out) { 2384 // The load local address pseudo-instruction "lla" is used in PC-relative 2385 // addressing of local symbols: 2386 // lla rdest, symbol 2387 // expands to 2388 // TmpLabel: AUIPC rdest, %pcrel_hi(symbol) 2389 // ADDI rdest, rdest, %pcrel_lo(TmpLabel) 2390 MCOperand DestReg = Inst.getOperand(0); 2391 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 2392 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI, 2393 RISCV::ADDI, IDLoc, Out); 2394 } 2395 2396 void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc, 2397 MCStreamer &Out) { 2398 // The load address pseudo-instruction "la" is used in PC-relative and 2399 // GOT-indirect addressing of global symbols: 2400 // la rdest, symbol 2401 // expands to either (for non-PIC) 2402 // TmpLabel: AUIPC rdest, %pcrel_hi(symbol) 2403 // ADDI rdest, rdest, %pcrel_lo(TmpLabel) 2404 // or (for PIC) 2405 // TmpLabel: AUIPC rdest, %got_pcrel_hi(symbol) 2406 // Lx rdest, %pcrel_lo(TmpLabel)(rdest) 2407 MCOperand DestReg = Inst.getOperand(0); 2408 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 2409 unsigned SecondOpcode; 2410 RISCVMCExpr::VariantKind VKHi; 2411 if (ParserOptions.IsPicEnabled) { 2412 SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW; 2413 VKHi = RISCVMCExpr::VK_RISCV_GOT_HI; 2414 } else { 2415 SecondOpcode = RISCV::ADDI; 2416 VKHi = RISCVMCExpr::VK_RISCV_PCREL_HI; 2417 } 2418 emitAuipcInstPair(DestReg, DestReg, Symbol, VKHi, SecondOpcode, IDLoc, Out); 2419 } 2420 2421 void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc, 2422 MCStreamer &Out) { 2423 // The load TLS IE address pseudo-instruction "la.tls.ie" is used in 2424 // initial-exec TLS model addressing of global symbols: 2425 // la.tls.ie rdest, symbol 2426 // expands to 2427 // TmpLabel: AUIPC rdest, %tls_ie_pcrel_hi(symbol) 2428 // Lx rdest, %pcrel_lo(TmpLabel)(rdest) 2429 MCOperand DestReg = Inst.getOperand(0); 2430 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 2431 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW; 2432 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_TLS_GOT_HI, 2433 SecondOpcode, IDLoc, Out); 2434 } 2435 2436 void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, 2437 MCStreamer &Out) { 2438 // The load TLS GD address pseudo-instruction "la.tls.gd" is used in 2439 // global-dynamic TLS model addressing of global symbols: 2440 // la.tls.gd rdest, symbol 2441 // expands to 2442 // TmpLabel: AUIPC rdest, %tls_gd_pcrel_hi(symbol) 2443 // ADDI rdest, rdest, %pcrel_lo(TmpLabel) 2444 MCOperand DestReg = Inst.getOperand(0); 2445 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 2446 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_TLS_GD_HI, 2447 RISCV::ADDI, IDLoc, Out); 2448 } 2449 2450 void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode, 2451 SMLoc IDLoc, MCStreamer &Out, 2452 bool HasTmpReg) { 2453 // The load/store pseudo-instruction does a pc-relative load with 2454 // a symbol. 2455 // 2456 // The expansion looks like this 2457 // 2458 // TmpLabel: AUIPC tmp, %pcrel_hi(symbol) 2459 // [S|L]X rd, %pcrel_lo(TmpLabel)(tmp) 2460 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0; 2461 MCOperand DestReg = Inst.getOperand(DestRegOpIdx); 2462 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1; 2463 MCOperand TmpReg = Inst.getOperand(0); 2464 const MCExpr *Symbol = Inst.getOperand(SymbolOpIdx).getExpr(); 2465 emitAuipcInstPair(DestReg, TmpReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI, 2466 Opcode, IDLoc, Out); 2467 } 2468 2469 void RISCVAsmParser::emitPseudoExtend(MCInst &Inst, bool SignExtend, 2470 int64_t Width, SMLoc IDLoc, 2471 MCStreamer &Out) { 2472 // The sign/zero extend pseudo-instruction does two shifts, with the shift 2473 // amounts dependent on the XLEN. 2474 // 2475 // The expansion looks like this 2476 // 2477 // SLLI rd, rs, XLEN - Width 2478 // SR[A|R]I rd, rd, XLEN - Width 2479 MCOperand DestReg = Inst.getOperand(0); 2480 MCOperand SourceReg = Inst.getOperand(1); 2481 2482 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI; 2483 int64_t ShAmt = (isRV64() ? 64 : 32) - Width; 2484 2485 assert(ShAmt > 0 && "Shift amount must be non-zero."); 2486 2487 emitToStreamer(Out, MCInstBuilder(RISCV::SLLI) 2488 .addOperand(DestReg) 2489 .addOperand(SourceReg) 2490 .addImm(ShAmt)); 2491 2492 emitToStreamer(Out, MCInstBuilder(SecondOpcode) 2493 .addOperand(DestReg) 2494 .addOperand(DestReg) 2495 .addImm(ShAmt)); 2496 } 2497 2498 void RISCVAsmParser::emitVMSGE(MCInst &Inst, unsigned Opcode, SMLoc IDLoc, 2499 MCStreamer &Out) { 2500 if (Inst.getNumOperands() == 3) { 2501 // unmasked va >= x 2502 // 2503 // pseudoinstruction: vmsge{u}.vx vd, va, x 2504 // expansion: vmslt{u}.vx vd, va, x; vmnand.mm vd, vd, vd 2505 emitToStreamer(Out, MCInstBuilder(Opcode) 2506 .addOperand(Inst.getOperand(0)) 2507 .addOperand(Inst.getOperand(1)) 2508 .addOperand(Inst.getOperand(2)) 2509 .addReg(RISCV::NoRegister)); 2510 emitToStreamer(Out, MCInstBuilder(RISCV::VMNAND_MM) 2511 .addOperand(Inst.getOperand(0)) 2512 .addOperand(Inst.getOperand(0)) 2513 .addOperand(Inst.getOperand(0))); 2514 } else if (Inst.getNumOperands() == 4) { 2515 // masked va >= x, vd != v0 2516 // 2517 // pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t 2518 // expansion: vmslt{u}.vx vd, va, x, v0.t; vmxor.mm vd, vd, v0 2519 assert(Inst.getOperand(0).getReg() != RISCV::V0 && 2520 "The destination register should not be V0."); 2521 emitToStreamer(Out, MCInstBuilder(Opcode) 2522 .addOperand(Inst.getOperand(0)) 2523 .addOperand(Inst.getOperand(1)) 2524 .addOperand(Inst.getOperand(2)) 2525 .addOperand(Inst.getOperand(3))); 2526 emitToStreamer(Out, MCInstBuilder(RISCV::VMXOR_MM) 2527 .addOperand(Inst.getOperand(0)) 2528 .addOperand(Inst.getOperand(0)) 2529 .addReg(RISCV::V0)); 2530 } else if (Inst.getNumOperands() == 5 && 2531 Inst.getOperand(0).getReg() == RISCV::V0) { 2532 // masked va >= x, vd == v0 2533 // 2534 // pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t, vt 2535 // expansion: vmslt{u}.vx vt, va, x; vmandn.mm vd, vd, vt 2536 assert(Inst.getOperand(0).getReg() == RISCV::V0 && 2537 "The destination register should be V0."); 2538 assert(Inst.getOperand(1).getReg() != RISCV::V0 && 2539 "The temporary vector register should not be V0."); 2540 emitToStreamer(Out, MCInstBuilder(Opcode) 2541 .addOperand(Inst.getOperand(1)) 2542 .addOperand(Inst.getOperand(2)) 2543 .addOperand(Inst.getOperand(3)) 2544 .addOperand(Inst.getOperand(4))); 2545 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM) 2546 .addOperand(Inst.getOperand(0)) 2547 .addOperand(Inst.getOperand(0)) 2548 .addOperand(Inst.getOperand(1))); 2549 } else if (Inst.getNumOperands() == 5) { 2550 // masked va >= x, any vd 2551 // 2552 // pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t, vt 2553 // expansion: vmslt{u}.vx vt, va, x; vmandn.mm vt, v0, vt; vmandn.mm vd, 2554 // vd, v0; vmor.mm vd, vt, vd 2555 assert(Inst.getOperand(1).getReg() != RISCV::V0 && 2556 "The temporary vector register should not be V0."); 2557 emitToStreamer(Out, MCInstBuilder(Opcode) 2558 .addOperand(Inst.getOperand(1)) 2559 .addOperand(Inst.getOperand(2)) 2560 .addOperand(Inst.getOperand(3)) 2561 .addReg(RISCV::NoRegister)); 2562 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM) 2563 .addOperand(Inst.getOperand(1)) 2564 .addReg(RISCV::V0) 2565 .addOperand(Inst.getOperand(1))); 2566 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM) 2567 .addOperand(Inst.getOperand(0)) 2568 .addOperand(Inst.getOperand(0)) 2569 .addReg(RISCV::V0)); 2570 emitToStreamer(Out, MCInstBuilder(RISCV::VMOR_MM) 2571 .addOperand(Inst.getOperand(0)) 2572 .addOperand(Inst.getOperand(1)) 2573 .addOperand(Inst.getOperand(0))); 2574 } 2575 } 2576 2577 bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst, 2578 OperandVector &Operands) { 2579 assert(Inst.getOpcode() == RISCV::PseudoAddTPRel && "Invalid instruction"); 2580 assert(Inst.getOperand(2).isReg() && "Unexpected second operand kind"); 2581 if (Inst.getOperand(2).getReg() != RISCV::X4) { 2582 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc(); 2583 return Error(ErrorLoc, "the second input operand must be tp/x4 when using " 2584 "%tprel_add modifier"); 2585 } 2586 2587 return false; 2588 } 2589 2590 std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp() const { 2591 return RISCVOperand::createReg(RISCV::NoRegister, llvm::SMLoc(), 2592 llvm::SMLoc(), isRV64()); 2593 } 2594 2595 bool RISCVAsmParser::validateInstruction(MCInst &Inst, 2596 OperandVector &Operands) { 2597 if (Inst.getOpcode() == RISCV::PseudoVMSGEU_VX_M_T || 2598 Inst.getOpcode() == RISCV::PseudoVMSGE_VX_M_T) { 2599 unsigned DestReg = Inst.getOperand(0).getReg(); 2600 unsigned TempReg = Inst.getOperand(1).getReg(); 2601 if (DestReg == TempReg) { 2602 SMLoc Loc = Operands.back()->getStartLoc(); 2603 return Error(Loc, "The temporary vector register cannot be the same as " 2604 "the destination register."); 2605 } 2606 } 2607 2608 const MCInstrDesc &MCID = MII.get(Inst.getOpcode()); 2609 RISCVII::VConstraintType Constraints = RISCVII::getConstraint(MCID.TSFlags); 2610 if (Constraints == RISCVII::NoConstraint) 2611 return false; 2612 2613 unsigned DestReg = Inst.getOperand(0).getReg(); 2614 // Operands[1] will be the first operand, DestReg. 2615 SMLoc Loc = Operands[1]->getStartLoc(); 2616 if (Constraints & RISCVII::VS2Constraint) { 2617 unsigned CheckReg = Inst.getOperand(1).getReg(); 2618 if (DestReg == CheckReg) 2619 return Error(Loc, "The destination vector register group cannot overlap" 2620 " the source vector register group."); 2621 } 2622 if ((Constraints & RISCVII::VS1Constraint) && (Inst.getOperand(2).isReg())) { 2623 unsigned CheckReg = Inst.getOperand(2).getReg(); 2624 if (DestReg == CheckReg) 2625 return Error(Loc, "The destination vector register group cannot overlap" 2626 " the source vector register group."); 2627 } 2628 if ((Constraints & RISCVII::VMConstraint) && (DestReg == RISCV::V0)) { 2629 // vadc, vsbc are special cases. These instructions have no mask register. 2630 // The destination register could not be V0. 2631 unsigned Opcode = Inst.getOpcode(); 2632 if (Opcode == RISCV::VADC_VVM || Opcode == RISCV::VADC_VXM || 2633 Opcode == RISCV::VADC_VIM || Opcode == RISCV::VSBC_VVM || 2634 Opcode == RISCV::VSBC_VXM || Opcode == RISCV::VFMERGE_VFM || 2635 Opcode == RISCV::VMERGE_VIM || Opcode == RISCV::VMERGE_VVM || 2636 Opcode == RISCV::VMERGE_VXM) 2637 return Error(Loc, "The destination vector register group cannot be V0."); 2638 2639 // Regardless masked or unmasked version, the number of operands is the 2640 // same. For example, "viota.m v0, v2" is "viota.m v0, v2, NoRegister" 2641 // actually. We need to check the last operand to ensure whether it is 2642 // masked or not. 2643 unsigned CheckReg = Inst.getOperand(Inst.getNumOperands() - 1).getReg(); 2644 assert((CheckReg == RISCV::V0 || CheckReg == RISCV::NoRegister) && 2645 "Unexpected register for mask operand"); 2646 2647 if (DestReg == CheckReg) 2648 return Error(Loc, "The destination vector register group cannot overlap" 2649 " the mask register."); 2650 } 2651 return false; 2652 } 2653 2654 bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 2655 OperandVector &Operands, 2656 MCStreamer &Out) { 2657 Inst.setLoc(IDLoc); 2658 2659 switch (Inst.getOpcode()) { 2660 default: 2661 break; 2662 case RISCV::PseudoLI: { 2663 MCRegister Reg = Inst.getOperand(0).getReg(); 2664 const MCOperand &Op1 = Inst.getOperand(1); 2665 if (Op1.isExpr()) { 2666 // We must have li reg, %lo(sym) or li reg, %pcrel_lo(sym) or similar. 2667 // Just convert to an addi. This allows compatibility with gas. 2668 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI) 2669 .addReg(Reg) 2670 .addReg(RISCV::X0) 2671 .addExpr(Op1.getExpr())); 2672 return false; 2673 } 2674 int64_t Imm = Inst.getOperand(1).getImm(); 2675 // On RV32 the immediate here can either be a signed or an unsigned 2676 // 32-bit number. Sign extension has to be performed to ensure that Imm 2677 // represents the expected signed 64-bit number. 2678 if (!isRV64()) 2679 Imm = SignExtend64<32>(Imm); 2680 emitLoadImm(Reg, Imm, Out); 2681 return false; 2682 } 2683 case RISCV::PseudoLLA: 2684 emitLoadLocalAddress(Inst, IDLoc, Out); 2685 return false; 2686 case RISCV::PseudoLA: 2687 emitLoadAddress(Inst, IDLoc, Out); 2688 return false; 2689 case RISCV::PseudoLA_TLS_IE: 2690 emitLoadTLSIEAddress(Inst, IDLoc, Out); 2691 return false; 2692 case RISCV::PseudoLA_TLS_GD: 2693 emitLoadTLSGDAddress(Inst, IDLoc, Out); 2694 return false; 2695 case RISCV::PseudoLB: 2696 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out, /*HasTmpReg=*/false); 2697 return false; 2698 case RISCV::PseudoLBU: 2699 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out, /*HasTmpReg=*/false); 2700 return false; 2701 case RISCV::PseudoLH: 2702 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out, /*HasTmpReg=*/false); 2703 return false; 2704 case RISCV::PseudoLHU: 2705 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out, /*HasTmpReg=*/false); 2706 return false; 2707 case RISCV::PseudoLW: 2708 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out, /*HasTmpReg=*/false); 2709 return false; 2710 case RISCV::PseudoLWU: 2711 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out, /*HasTmpReg=*/false); 2712 return false; 2713 case RISCV::PseudoLD: 2714 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out, /*HasTmpReg=*/false); 2715 return false; 2716 case RISCV::PseudoFLH: 2717 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out, /*HasTmpReg=*/true); 2718 return false; 2719 case RISCV::PseudoFLW: 2720 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out, /*HasTmpReg=*/true); 2721 return false; 2722 case RISCV::PseudoFLD: 2723 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out, /*HasTmpReg=*/true); 2724 return false; 2725 case RISCV::PseudoSB: 2726 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out, /*HasTmpReg=*/true); 2727 return false; 2728 case RISCV::PseudoSH: 2729 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out, /*HasTmpReg=*/true); 2730 return false; 2731 case RISCV::PseudoSW: 2732 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out, /*HasTmpReg=*/true); 2733 return false; 2734 case RISCV::PseudoSD: 2735 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out, /*HasTmpReg=*/true); 2736 return false; 2737 case RISCV::PseudoFSH: 2738 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out, /*HasTmpReg=*/true); 2739 return false; 2740 case RISCV::PseudoFSW: 2741 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out, /*HasTmpReg=*/true); 2742 return false; 2743 case RISCV::PseudoFSD: 2744 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out, /*HasTmpReg=*/true); 2745 return false; 2746 case RISCV::PseudoAddTPRel: 2747 if (checkPseudoAddTPRel(Inst, Operands)) 2748 return true; 2749 break; 2750 case RISCV::PseudoSEXT_B: 2751 emitPseudoExtend(Inst, /*SignExtend=*/true, /*Width=*/8, IDLoc, Out); 2752 return false; 2753 case RISCV::PseudoSEXT_H: 2754 emitPseudoExtend(Inst, /*SignExtend=*/true, /*Width=*/16, IDLoc, Out); 2755 return false; 2756 case RISCV::PseudoZEXT_H: 2757 emitPseudoExtend(Inst, /*SignExtend=*/false, /*Width=*/16, IDLoc, Out); 2758 return false; 2759 case RISCV::PseudoZEXT_W: 2760 emitPseudoExtend(Inst, /*SignExtend=*/false, /*Width=*/32, IDLoc, Out); 2761 return false; 2762 case RISCV::PseudoVMSGEU_VX: 2763 case RISCV::PseudoVMSGEU_VX_M: 2764 case RISCV::PseudoVMSGEU_VX_M_T: 2765 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out); 2766 return false; 2767 case RISCV::PseudoVMSGE_VX: 2768 case RISCV::PseudoVMSGE_VX_M: 2769 case RISCV::PseudoVMSGE_VX_M_T: 2770 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out); 2771 return false; 2772 case RISCV::PseudoVMSGE_VI: 2773 case RISCV::PseudoVMSLT_VI: { 2774 // These instructions are signed and so is immediate so we can subtract one 2775 // and change the opcode. 2776 int64_t Imm = Inst.getOperand(2).getImm(); 2777 unsigned Opc = Inst.getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI 2778 : RISCV::VMSLE_VI; 2779 emitToStreamer(Out, MCInstBuilder(Opc) 2780 .addOperand(Inst.getOperand(0)) 2781 .addOperand(Inst.getOperand(1)) 2782 .addImm(Imm - 1) 2783 .addOperand(Inst.getOperand(3))); 2784 return false; 2785 } 2786 case RISCV::PseudoVMSGEU_VI: 2787 case RISCV::PseudoVMSLTU_VI: { 2788 int64_t Imm = Inst.getOperand(2).getImm(); 2789 // Unsigned comparisons are tricky because the immediate is signed. If the 2790 // immediate is 0 we can't just subtract one. vmsltu.vi v0, v1, 0 is always 2791 // false, but vmsle.vi v0, v1, -1 is always true. Instead we use 2792 // vmsne v0, v1, v1 which is always false. 2793 if (Imm == 0) { 2794 unsigned Opc = Inst.getOpcode() == RISCV::PseudoVMSGEU_VI 2795 ? RISCV::VMSEQ_VV 2796 : RISCV::VMSNE_VV; 2797 emitToStreamer(Out, MCInstBuilder(Opc) 2798 .addOperand(Inst.getOperand(0)) 2799 .addOperand(Inst.getOperand(1)) 2800 .addOperand(Inst.getOperand(1)) 2801 .addOperand(Inst.getOperand(3))); 2802 } else { 2803 // Other immediate values can subtract one like signed. 2804 unsigned Opc = Inst.getOpcode() == RISCV::PseudoVMSGEU_VI 2805 ? RISCV::VMSGTU_VI 2806 : RISCV::VMSLEU_VI; 2807 emitToStreamer(Out, MCInstBuilder(Opc) 2808 .addOperand(Inst.getOperand(0)) 2809 .addOperand(Inst.getOperand(1)) 2810 .addImm(Imm - 1) 2811 .addOperand(Inst.getOperand(3))); 2812 } 2813 2814 return false; 2815 } 2816 } 2817 2818 emitToStreamer(Out, Inst); 2819 return false; 2820 } 2821 2822 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVAsmParser() { 2823 RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target()); 2824 RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target()); 2825 } 2826