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