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/Support/Casting.h" 35 #include "llvm/Support/MathExtras.h" 36 #include "llvm/Support/RISCVAttributes.h" 37 #include "llvm/Support/TargetRegistry.h" 38 39 #include <limits> 40 41 using namespace llvm; 42 43 #define DEBUG_TYPE "riscv-asm-parser" 44 45 // Include the auto-generated portion of the compress emitter. 46 #define GEN_COMPRESS_INSTR 47 #include "RISCVGenCompressInstEmitter.inc" 48 49 STATISTIC(RISCVNumInstrsCompressed, 50 "Number of RISC-V Compressed instructions emitted"); 51 52 namespace { 53 struct RISCVOperand; 54 55 struct ParserOptionsSet { 56 bool IsPicEnabled; 57 }; 58 59 class RISCVAsmParser : public MCTargetAsmParser { 60 SmallVector<FeatureBitset, 4> FeatureBitStack; 61 62 SmallVector<ParserOptionsSet, 4> ParserOptionsStack; 63 ParserOptionsSet ParserOptions; 64 65 SMLoc getLoc() const { return getParser().getTok().getLoc(); } 66 bool isRV64() const { return getSTI().hasFeature(RISCV::Feature64Bit); } 67 bool isRV32E() const { return getSTI().hasFeature(RISCV::FeatureRV32E); } 68 69 RISCVTargetStreamer &getTargetStreamer() { 70 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer(); 71 return static_cast<RISCVTargetStreamer &>(TS); 72 } 73 74 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, 75 unsigned Kind) override; 76 77 bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo, 78 int64_t Lower, int64_t Upper, Twine Msg); 79 80 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 81 OperandVector &Operands, MCStreamer &Out, 82 uint64_t &ErrorInfo, 83 bool MatchingInlineAsm) override; 84 85 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; 86 OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc, 87 SMLoc &EndLoc) override; 88 89 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 90 SMLoc NameLoc, OperandVector &Operands) override; 91 92 bool ParseDirective(AsmToken DirectiveID) override; 93 94 // Helper to actually emit an instruction to the MCStreamer. Also, when 95 // possible, compression of the instruction is performed. 96 void emitToStreamer(MCStreamer &S, const MCInst &Inst); 97 98 // Helper to emit a combination of LUI, ADDI(W), and SLLI instructions that 99 // synthesize the desired immedate value into the destination register. 100 void emitLoadImm(MCRegister DestReg, int64_t Value, MCStreamer &Out); 101 102 // Helper to emit a combination of AUIPC and SecondOpcode. Used to implement 103 // helpers such as emitLoadLocalAddress and emitLoadAddress. 104 void emitAuipcInstPair(MCOperand DestReg, MCOperand TmpReg, 105 const MCExpr *Symbol, RISCVMCExpr::VariantKind VKHi, 106 unsigned SecondOpcode, SMLoc IDLoc, MCStreamer &Out); 107 108 // Helper to emit pseudo instruction "lla" used in PC-rel addressing. 109 void emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 110 111 // Helper to emit pseudo instruction "la" used in GOT/PC-rel addressing. 112 void emitLoadAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 113 114 // Helper to emit pseudo instruction "la.tls.ie" used in initial-exec TLS 115 // addressing. 116 void emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 117 118 // Helper to emit pseudo instruction "la.tls.gd" used in global-dynamic TLS 119 // addressing. 120 void emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 121 122 // Helper to emit pseudo load/store instruction with a symbol. 123 void emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode, SMLoc IDLoc, 124 MCStreamer &Out, bool HasTmpReg); 125 126 // Checks that a PseudoAddTPRel is using x4/tp in its second input operand. 127 // Enforcing this using a restricted register class for the second input 128 // operand of PseudoAddTPRel results in a poor diagnostic due to the fact 129 // 'add' is an overloaded mnemonic. 130 bool checkPseudoAddTPRel(MCInst &Inst, OperandVector &Operands); 131 132 // Check instruction constraints. 133 bool validateInstruction(MCInst &Inst, OperandVector &Operands); 134 135 /// Helper for processing MC instructions that have been successfully matched 136 /// by MatchAndEmitInstruction. Modifications to the emitted instructions, 137 /// like the expansion of pseudo instructions (e.g., "li"), can be performed 138 /// in this method. 139 bool processInstruction(MCInst &Inst, SMLoc IDLoc, OperandVector &Operands, 140 MCStreamer &Out); 141 142 // Auto-generated instruction matching functions 143 #define GET_ASSEMBLER_HEADER 144 #include "RISCVGenAsmMatcher.inc" 145 146 OperandMatchResultTy parseCSRSystemRegister(OperandVector &Operands); 147 OperandMatchResultTy parseImmediate(OperandVector &Operands); 148 OperandMatchResultTy parseRegister(OperandVector &Operands, 149 bool AllowParens = false); 150 OperandMatchResultTy parseMemOpBaseReg(OperandVector &Operands); 151 OperandMatchResultTy parseAtomicMemOp(OperandVector &Operands); 152 OperandMatchResultTy parseOperandWithModifier(OperandVector &Operands); 153 OperandMatchResultTy parseBareSymbol(OperandVector &Operands); 154 OperandMatchResultTy parseCallSymbol(OperandVector &Operands); 155 OperandMatchResultTy parsePseudoJumpSymbol(OperandVector &Operands); 156 OperandMatchResultTy parseJALOffset(OperandVector &Operands); 157 OperandMatchResultTy parseVTypeI(OperandVector &Operands); 158 OperandMatchResultTy parseMaskReg(OperandVector &Operands); 159 160 bool parseOperand(OperandVector &Operands, StringRef Mnemonic); 161 162 bool parseDirectiveOption(); 163 bool parseDirectiveAttribute(); 164 165 void setFeatureBits(uint64_t Feature, StringRef FeatureString) { 166 if (!(getSTI().getFeatureBits()[Feature])) { 167 MCSubtargetInfo &STI = copySTI(); 168 setAvailableFeatures( 169 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); 170 } 171 } 172 173 bool getFeatureBits(uint64_t Feature) { 174 return getSTI().getFeatureBits()[Feature]; 175 } 176 177 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) { 178 if (getSTI().getFeatureBits()[Feature]) { 179 MCSubtargetInfo &STI = copySTI(); 180 setAvailableFeatures( 181 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); 182 } 183 } 184 185 void pushFeatureBits() { 186 assert(FeatureBitStack.size() == ParserOptionsStack.size() && 187 "These two stacks must be kept synchronized"); 188 FeatureBitStack.push_back(getSTI().getFeatureBits()); 189 ParserOptionsStack.push_back(ParserOptions); 190 } 191 192 bool popFeatureBits() { 193 assert(FeatureBitStack.size() == ParserOptionsStack.size() && 194 "These two stacks must be kept synchronized"); 195 if (FeatureBitStack.empty()) 196 return true; 197 198 FeatureBitset FeatureBits = FeatureBitStack.pop_back_val(); 199 copySTI().setFeatureBits(FeatureBits); 200 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits)); 201 202 ParserOptions = ParserOptionsStack.pop_back_val(); 203 204 return false; 205 } 206 207 std::unique_ptr<RISCVOperand> defaultMaskRegOp() const; 208 209 public: 210 enum RISCVMatchResultTy { 211 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY, 212 #define GET_OPERAND_DIAGNOSTIC_TYPES 213 #include "RISCVGenAsmMatcher.inc" 214 #undef GET_OPERAND_DIAGNOSTIC_TYPES 215 }; 216 217 static bool classifySymbolRef(const MCExpr *Expr, 218 RISCVMCExpr::VariantKind &Kind, 219 int64_t &Addend); 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, Imm); 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, Imm) && 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, Imm) && 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, Imm) && 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, Imm) && 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, Imm); 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, Imm); 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, Imm); 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 convertFPR64ToFPR32(MCRegister Reg) { 986 assert(Reg >= RISCV::F0_D && Reg <= RISCV::F31_D && "Invalid register"); 987 return Reg - RISCV::F0_D + RISCV::F0_F; 988 } 989 990 unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp, 991 unsigned Kind) { 992 RISCVOperand &Op = static_cast<RISCVOperand &>(AsmOp); 993 if (!Op.isReg()) 994 return Match_InvalidOperand; 995 996 MCRegister Reg = Op.getReg(); 997 bool IsRegFPR64 = 998 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(Reg); 999 bool IsRegFPR64C = 1000 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(Reg); 1001 1002 // As the parser couldn't differentiate an FPR32 from an FPR64, coerce the 1003 // register from FPR64 to FPR32 or FPR64C to FPR32C if necessary. 1004 if ((IsRegFPR64 && Kind == MCK_FPR32) || 1005 (IsRegFPR64C && Kind == MCK_FPR32C)) { 1006 Op.Reg.RegNum = convertFPR64ToFPR32(Reg); 1007 return Match_Success; 1008 } 1009 return Match_InvalidOperand; 1010 } 1011 1012 bool RISCVAsmParser::generateImmOutOfRangeError( 1013 OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper, 1014 Twine Msg = "immediate must be an integer in the range") { 1015 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1016 return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]"); 1017 } 1018 1019 static std::string RISCVMnemonicSpellCheck(StringRef S, 1020 const FeatureBitset &FBS, 1021 unsigned VariantID = 0); 1022 1023 bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 1024 OperandVector &Operands, 1025 MCStreamer &Out, 1026 uint64_t &ErrorInfo, 1027 bool MatchingInlineAsm) { 1028 MCInst Inst; 1029 FeatureBitset MissingFeatures; 1030 1031 auto Result = 1032 MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures, 1033 MatchingInlineAsm); 1034 switch (Result) { 1035 default: 1036 break; 1037 case Match_Success: 1038 if (validateInstruction(Inst, Operands)) 1039 return true; 1040 return processInstruction(Inst, IDLoc, Operands, Out); 1041 case Match_MissingFeature: { 1042 assert(MissingFeatures.any() && "Unknown missing features!"); 1043 bool FirstFeature = true; 1044 std::string Msg = "instruction requires the following:"; 1045 for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) { 1046 if (MissingFeatures[i]) { 1047 Msg += FirstFeature ? " " : ", "; 1048 Msg += getSubtargetFeatureName(i); 1049 FirstFeature = false; 1050 } 1051 } 1052 return Error(IDLoc, Msg); 1053 } 1054 case Match_MnemonicFail: { 1055 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits()); 1056 std::string Suggestion = RISCVMnemonicSpellCheck( 1057 ((RISCVOperand &)*Operands[0]).getToken(), FBS); 1058 return Error(IDLoc, "unrecognized instruction mnemonic" + Suggestion); 1059 } 1060 case Match_InvalidOperand: { 1061 SMLoc ErrorLoc = IDLoc; 1062 if (ErrorInfo != ~0U) { 1063 if (ErrorInfo >= Operands.size()) 1064 return Error(ErrorLoc, "too few operands for instruction"); 1065 1066 ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1067 if (ErrorLoc == SMLoc()) 1068 ErrorLoc = IDLoc; 1069 } 1070 return Error(ErrorLoc, "invalid operand for instruction"); 1071 } 1072 } 1073 1074 // Handle the case when the error message is of specific type 1075 // other than the generic Match_InvalidOperand, and the 1076 // corresponding operand is missing. 1077 if (Result > FIRST_TARGET_MATCH_RESULT_TY) { 1078 SMLoc ErrorLoc = IDLoc; 1079 if (ErrorInfo != ~0U && ErrorInfo >= Operands.size()) 1080 return Error(ErrorLoc, "too few operands for instruction"); 1081 } 1082 1083 switch(Result) { 1084 default: 1085 break; 1086 case Match_InvalidImmXLenLI: 1087 if (isRV64()) { 1088 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1089 return Error(ErrorLoc, "operand must be a constant 64-bit integer"); 1090 } 1091 return generateImmOutOfRangeError(Operands, ErrorInfo, 1092 std::numeric_limits<int32_t>::min(), 1093 std::numeric_limits<uint32_t>::max()); 1094 case Match_InvalidImmZero: { 1095 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1096 return Error(ErrorLoc, "immediate must be zero"); 1097 } 1098 case Match_InvalidUImmLog2XLen: 1099 if (isRV64()) 1100 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1); 1101 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 1102 case Match_InvalidUImmLog2XLenNonZero: 1103 if (isRV64()) 1104 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1); 1105 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1); 1106 case Match_InvalidUImmLog2XLenHalf: 1107 if (isRV64()) 1108 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 1109 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1); 1110 case Match_InvalidUImm5: 1111 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 1112 case Match_InvalidSImm6: 1113 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5), 1114 (1 << 5) - 1); 1115 case Match_InvalidSImm6NonZero: 1116 return generateImmOutOfRangeError( 1117 Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1, 1118 "immediate must be non-zero in the range"); 1119 case Match_InvalidCLUIImm: 1120 return generateImmOutOfRangeError( 1121 Operands, ErrorInfo, 1, (1 << 5) - 1, 1122 "immediate must be in [0xfffe0, 0xfffff] or"); 1123 case Match_InvalidUImm7Lsb00: 1124 return generateImmOutOfRangeError( 1125 Operands, ErrorInfo, 0, (1 << 7) - 4, 1126 "immediate must be a multiple of 4 bytes in the range"); 1127 case Match_InvalidUImm8Lsb00: 1128 return generateImmOutOfRangeError( 1129 Operands, ErrorInfo, 0, (1 << 8) - 4, 1130 "immediate must be a multiple of 4 bytes in the range"); 1131 case Match_InvalidUImm8Lsb000: 1132 return generateImmOutOfRangeError( 1133 Operands, ErrorInfo, 0, (1 << 8) - 8, 1134 "immediate must be a multiple of 8 bytes in the range"); 1135 case Match_InvalidSImm9Lsb0: 1136 return generateImmOutOfRangeError( 1137 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2, 1138 "immediate must be a multiple of 2 bytes in the range"); 1139 case Match_InvalidUImm9Lsb000: 1140 return generateImmOutOfRangeError( 1141 Operands, ErrorInfo, 0, (1 << 9) - 8, 1142 "immediate must be a multiple of 8 bytes in the range"); 1143 case Match_InvalidUImm10Lsb00NonZero: 1144 return generateImmOutOfRangeError( 1145 Operands, ErrorInfo, 4, (1 << 10) - 4, 1146 "immediate must be a multiple of 4 bytes in the range"); 1147 case Match_InvalidSImm10Lsb0000NonZero: 1148 return generateImmOutOfRangeError( 1149 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16, 1150 "immediate must be a multiple of 16 bytes and non-zero in the range"); 1151 case Match_InvalidSImm12: 1152 return generateImmOutOfRangeError( 1153 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1, 1154 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an " 1155 "integer in the range"); 1156 case Match_InvalidSImm12Lsb0: 1157 return generateImmOutOfRangeError( 1158 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2, 1159 "immediate must be a multiple of 2 bytes in the range"); 1160 case Match_InvalidSImm13Lsb0: 1161 return generateImmOutOfRangeError( 1162 Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2, 1163 "immediate must be a multiple of 2 bytes in the range"); 1164 case Match_InvalidUImm20LUI: 1165 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1, 1166 "operand must be a symbol with " 1167 "%hi/%tprel_hi modifier or an integer in " 1168 "the range"); 1169 case Match_InvalidUImm20AUIPC: 1170 return generateImmOutOfRangeError( 1171 Operands, ErrorInfo, 0, (1 << 20) - 1, 1172 "operand must be a symbol with a " 1173 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or " 1174 "an integer in the range"); 1175 case Match_InvalidSImm21Lsb0JAL: 1176 return generateImmOutOfRangeError( 1177 Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2, 1178 "immediate must be a multiple of 2 bytes in the range"); 1179 case Match_InvalidCSRSystemRegister: { 1180 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1, 1181 "operand must be a valid system register " 1182 "name or an integer in the range"); 1183 } 1184 case Match_InvalidFenceArg: { 1185 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1186 return Error( 1187 ErrorLoc, 1188 "operand must be formed of letters selected in-order from 'iorw'"); 1189 } 1190 case Match_InvalidFRMArg: { 1191 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1192 return Error( 1193 ErrorLoc, 1194 "operand must be a valid floating point rounding mode mnemonic"); 1195 } 1196 case Match_InvalidBareSymbol: { 1197 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1198 return Error(ErrorLoc, "operand must be a bare symbol name"); 1199 } 1200 case Match_InvalidPseudoJumpSymbol: { 1201 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1202 return Error(ErrorLoc, "operand must be a valid jump target"); 1203 } 1204 case Match_InvalidCallSymbol: { 1205 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1206 return Error(ErrorLoc, "operand must be a bare symbol name"); 1207 } 1208 case Match_InvalidTPRelAddSymbol: { 1209 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1210 return Error(ErrorLoc, "operand must be a symbol with %tprel_add modifier"); 1211 } 1212 case Match_InvalidVTypeI: { 1213 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1214 return Error( 1215 ErrorLoc, 1216 "operand must be " 1217 "e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]"); 1218 } 1219 case Match_InvalidVMaskRegister: { 1220 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1221 return Error(ErrorLoc, "operand must be v0.t"); 1222 } 1223 case Match_InvalidSImm5Plus1: { 1224 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4) + 1, 1225 (1 << 4), 1226 "immediate must be in the range"); 1227 } 1228 } 1229 1230 llvm_unreachable("Unknown match type detected!"); 1231 } 1232 1233 // Attempts to match Name as a register (either using the default name or 1234 // alternative ABI names), setting RegNo to the matching register. Upon 1235 // failure, returns true and sets RegNo to 0. If IsRV32E then registers 1236 // x16-x31 will be rejected. 1237 static bool matchRegisterNameHelper(bool IsRV32E, MCRegister &RegNo, 1238 StringRef Name) { 1239 RegNo = MatchRegisterName(Name); 1240 // The 32- and 64-bit FPRs have the same asm name. Check that the initial 1241 // match always matches the 64-bit variant, and not the 32-bit one. 1242 assert(!(RegNo >= RISCV::F0_F && RegNo <= RISCV::F31_F)); 1243 // The default FPR register class is based on the tablegen enum ordering. 1244 static_assert(RISCV::F0_D < RISCV::F0_F, "FPR matching must be updated"); 1245 if (RegNo == RISCV::NoRegister) 1246 RegNo = MatchRegisterAltName(Name); 1247 if (IsRV32E && RegNo >= RISCV::X16 && RegNo <= RISCV::X31) 1248 RegNo = RISCV::NoRegister; 1249 return RegNo == RISCV::NoRegister; 1250 } 1251 1252 bool RISCVAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 1253 SMLoc &EndLoc) { 1254 if (tryParseRegister(RegNo, StartLoc, EndLoc) != MatchOperand_Success) 1255 return Error(StartLoc, "invalid register name"); 1256 return false; 1257 } 1258 1259 OperandMatchResultTy RISCVAsmParser::tryParseRegister(unsigned &RegNo, 1260 SMLoc &StartLoc, 1261 SMLoc &EndLoc) { 1262 const AsmToken &Tok = getParser().getTok(); 1263 StartLoc = Tok.getLoc(); 1264 EndLoc = Tok.getEndLoc(); 1265 RegNo = 0; 1266 StringRef Name = getLexer().getTok().getIdentifier(); 1267 1268 if (matchRegisterNameHelper(isRV32E(), (MCRegister &)RegNo, Name)) 1269 return MatchOperand_NoMatch; 1270 1271 getParser().Lex(); // Eat identifier token. 1272 return MatchOperand_Success; 1273 } 1274 1275 OperandMatchResultTy RISCVAsmParser::parseRegister(OperandVector &Operands, 1276 bool AllowParens) { 1277 SMLoc FirstS = getLoc(); 1278 bool HadParens = false; 1279 AsmToken LParen; 1280 1281 // If this is an LParen and a parenthesised register name is allowed, parse it 1282 // atomically. 1283 if (AllowParens && getLexer().is(AsmToken::LParen)) { 1284 AsmToken Buf[2]; 1285 size_t ReadCount = getLexer().peekTokens(Buf); 1286 if (ReadCount == 2 && Buf[1].getKind() == AsmToken::RParen) { 1287 HadParens = true; 1288 LParen = getParser().getTok(); 1289 getParser().Lex(); // Eat '(' 1290 } 1291 } 1292 1293 switch (getLexer().getKind()) { 1294 default: 1295 if (HadParens) 1296 getLexer().UnLex(LParen); 1297 return MatchOperand_NoMatch; 1298 case AsmToken::Identifier: 1299 StringRef Name = getLexer().getTok().getIdentifier(); 1300 MCRegister RegNo; 1301 matchRegisterNameHelper(isRV32E(), RegNo, Name); 1302 1303 if (RegNo == RISCV::NoRegister) { 1304 if (HadParens) 1305 getLexer().UnLex(LParen); 1306 return MatchOperand_NoMatch; 1307 } 1308 if (HadParens) 1309 Operands.push_back(RISCVOperand::createToken("(", FirstS, isRV64())); 1310 SMLoc S = getLoc(); 1311 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1312 getLexer().Lex(); 1313 Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64())); 1314 } 1315 1316 if (HadParens) { 1317 getParser().Lex(); // Eat ')' 1318 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64())); 1319 } 1320 1321 return MatchOperand_Success; 1322 } 1323 1324 OperandMatchResultTy 1325 RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) { 1326 SMLoc S = getLoc(); 1327 const MCExpr *Res; 1328 1329 switch (getLexer().getKind()) { 1330 default: 1331 return MatchOperand_NoMatch; 1332 case AsmToken::LParen: 1333 case AsmToken::Minus: 1334 case AsmToken::Plus: 1335 case AsmToken::Exclaim: 1336 case AsmToken::Tilde: 1337 case AsmToken::Integer: 1338 case AsmToken::String: { 1339 if (getParser().parseExpression(Res)) 1340 return MatchOperand_ParseFail; 1341 1342 auto *CE = dyn_cast<MCConstantExpr>(Res); 1343 if (CE) { 1344 int64_t Imm = CE->getValue(); 1345 if (isUInt<12>(Imm)) { 1346 auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm); 1347 // Accept an immediate representing a named or un-named Sys Reg 1348 // if the range is valid, regardless of the required features. 1349 Operands.push_back(RISCVOperand::createSysReg( 1350 SysReg ? SysReg->Name : "", S, Imm, isRV64())); 1351 return MatchOperand_Success; 1352 } 1353 } 1354 1355 Twine Msg = "immediate must be an integer in the range"; 1356 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]"); 1357 return MatchOperand_ParseFail; 1358 } 1359 case AsmToken::Identifier: { 1360 StringRef Identifier; 1361 if (getParser().parseIdentifier(Identifier)) 1362 return MatchOperand_ParseFail; 1363 1364 auto SysReg = RISCVSysReg::lookupSysRegByName(Identifier); 1365 if (!SysReg) 1366 SysReg = RISCVSysReg::lookupSysRegByAltName(Identifier); 1367 // Accept a named Sys Reg if the required features are present. 1368 if (SysReg) { 1369 if (!SysReg->haveRequiredFeatures(getSTI().getFeatureBits())) { 1370 Error(S, "system register use requires an option to be enabled"); 1371 return MatchOperand_ParseFail; 1372 } 1373 Operands.push_back(RISCVOperand::createSysReg( 1374 Identifier, S, SysReg->Encoding, isRV64())); 1375 return MatchOperand_Success; 1376 } 1377 1378 Twine Msg = "operand must be a valid system register name " 1379 "or an integer in the range"; 1380 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]"); 1381 return MatchOperand_ParseFail; 1382 } 1383 case AsmToken::Percent: { 1384 // Discard operand with modifier. 1385 Twine Msg = "immediate must be an integer in the range"; 1386 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]"); 1387 return MatchOperand_ParseFail; 1388 } 1389 } 1390 1391 return MatchOperand_NoMatch; 1392 } 1393 1394 OperandMatchResultTy RISCVAsmParser::parseImmediate(OperandVector &Operands) { 1395 SMLoc S = getLoc(); 1396 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1397 const MCExpr *Res; 1398 1399 switch (getLexer().getKind()) { 1400 default: 1401 return MatchOperand_NoMatch; 1402 case AsmToken::LParen: 1403 case AsmToken::Dot: 1404 case AsmToken::Minus: 1405 case AsmToken::Plus: 1406 case AsmToken::Exclaim: 1407 case AsmToken::Tilde: 1408 case AsmToken::Integer: 1409 case AsmToken::String: 1410 case AsmToken::Identifier: 1411 if (getParser().parseExpression(Res)) 1412 return MatchOperand_ParseFail; 1413 break; 1414 case AsmToken::Percent: 1415 return parseOperandWithModifier(Operands); 1416 } 1417 1418 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1419 return MatchOperand_Success; 1420 } 1421 1422 OperandMatchResultTy 1423 RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) { 1424 SMLoc S = getLoc(); 1425 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1426 1427 if (getLexer().getKind() != AsmToken::Percent) { 1428 Error(getLoc(), "expected '%' for operand modifier"); 1429 return MatchOperand_ParseFail; 1430 } 1431 1432 getParser().Lex(); // Eat '%' 1433 1434 if (getLexer().getKind() != AsmToken::Identifier) { 1435 Error(getLoc(), "expected valid identifier for operand modifier"); 1436 return MatchOperand_ParseFail; 1437 } 1438 StringRef Identifier = getParser().getTok().getIdentifier(); 1439 RISCVMCExpr::VariantKind VK = RISCVMCExpr::getVariantKindForName(Identifier); 1440 if (VK == RISCVMCExpr::VK_RISCV_Invalid) { 1441 Error(getLoc(), "unrecognized operand modifier"); 1442 return MatchOperand_ParseFail; 1443 } 1444 1445 getParser().Lex(); // Eat the identifier 1446 if (getLexer().getKind() != AsmToken::LParen) { 1447 Error(getLoc(), "expected '('"); 1448 return MatchOperand_ParseFail; 1449 } 1450 getParser().Lex(); // Eat '(' 1451 1452 const MCExpr *SubExpr; 1453 if (getParser().parseParenExpression(SubExpr, E)) { 1454 return MatchOperand_ParseFail; 1455 } 1456 1457 const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, VK, getContext()); 1458 Operands.push_back(RISCVOperand::createImm(ModExpr, S, E, isRV64())); 1459 return MatchOperand_Success; 1460 } 1461 1462 OperandMatchResultTy RISCVAsmParser::parseBareSymbol(OperandVector &Operands) { 1463 SMLoc S = getLoc(); 1464 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1465 const MCExpr *Res; 1466 1467 if (getLexer().getKind() != AsmToken::Identifier) 1468 return MatchOperand_NoMatch; 1469 1470 StringRef Identifier; 1471 AsmToken Tok = getLexer().getTok(); 1472 1473 if (getParser().parseIdentifier(Identifier)) 1474 return MatchOperand_ParseFail; 1475 1476 if (Identifier.consume_back("@plt")) { 1477 Error(getLoc(), "'@plt' operand not valid for instruction"); 1478 return MatchOperand_ParseFail; 1479 } 1480 1481 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); 1482 1483 if (Sym->isVariable()) { 1484 const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false); 1485 if (!isa<MCSymbolRefExpr>(V)) { 1486 getLexer().UnLex(Tok); // Put back if it's not a bare symbol. 1487 return MatchOperand_NoMatch; 1488 } 1489 Res = V; 1490 } else 1491 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1492 1493 MCBinaryExpr::Opcode Opcode; 1494 switch (getLexer().getKind()) { 1495 default: 1496 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1497 return MatchOperand_Success; 1498 case AsmToken::Plus: 1499 Opcode = MCBinaryExpr::Add; 1500 break; 1501 case AsmToken::Minus: 1502 Opcode = MCBinaryExpr::Sub; 1503 break; 1504 } 1505 1506 const MCExpr *Expr; 1507 if (getParser().parseExpression(Expr)) 1508 return MatchOperand_ParseFail; 1509 Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext()); 1510 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1511 return MatchOperand_Success; 1512 } 1513 1514 OperandMatchResultTy RISCVAsmParser::parseCallSymbol(OperandVector &Operands) { 1515 SMLoc S = getLoc(); 1516 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1517 const MCExpr *Res; 1518 1519 if (getLexer().getKind() != AsmToken::Identifier) 1520 return MatchOperand_NoMatch; 1521 1522 // Avoid parsing the register in `call rd, foo` as a call symbol. 1523 if (getLexer().peekTok().getKind() != AsmToken::EndOfStatement) 1524 return MatchOperand_NoMatch; 1525 1526 StringRef Identifier; 1527 if (getParser().parseIdentifier(Identifier)) 1528 return MatchOperand_ParseFail; 1529 1530 RISCVMCExpr::VariantKind Kind = RISCVMCExpr::VK_RISCV_CALL; 1531 if (Identifier.consume_back("@plt")) 1532 Kind = RISCVMCExpr::VK_RISCV_CALL_PLT; 1533 1534 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); 1535 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1536 Res = RISCVMCExpr::create(Res, Kind, getContext()); 1537 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1538 return MatchOperand_Success; 1539 } 1540 1541 OperandMatchResultTy 1542 RISCVAsmParser::parsePseudoJumpSymbol(OperandVector &Operands) { 1543 SMLoc S = getLoc(); 1544 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1545 const MCExpr *Res; 1546 1547 if (getParser().parseExpression(Res)) 1548 return MatchOperand_ParseFail; 1549 1550 if (Res->getKind() != MCExpr::ExprKind::SymbolRef || 1551 cast<MCSymbolRefExpr>(Res)->getKind() == 1552 MCSymbolRefExpr::VariantKind::VK_PLT) { 1553 Error(S, "operand must be a valid jump target"); 1554 return MatchOperand_ParseFail; 1555 } 1556 1557 Res = RISCVMCExpr::create(Res, RISCVMCExpr::VK_RISCV_CALL, getContext()); 1558 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1559 return MatchOperand_Success; 1560 } 1561 1562 OperandMatchResultTy RISCVAsmParser::parseJALOffset(OperandVector &Operands) { 1563 // Parsing jal operands is fiddly due to the `jal foo` and `jal ra, foo` 1564 // both being acceptable forms. When parsing `jal ra, foo` this function 1565 // will be called for the `ra` register operand in an attempt to match the 1566 // single-operand alias. parseJALOffset must fail for this case. It would 1567 // seem logical to try parse the operand using parseImmediate and return 1568 // NoMatch if the next token is a comma (meaning we must be parsing a jal in 1569 // the second form rather than the first). We can't do this as there's no 1570 // way of rewinding the lexer state. Instead, return NoMatch if this operand 1571 // is an identifier and is followed by a comma. 1572 if (getLexer().is(AsmToken::Identifier) && 1573 getLexer().peekTok().is(AsmToken::Comma)) 1574 return MatchOperand_NoMatch; 1575 1576 return parseImmediate(Operands); 1577 } 1578 1579 OperandMatchResultTy RISCVAsmParser::parseVTypeI(OperandVector &Operands) { 1580 SMLoc S = getLoc(); 1581 if (getLexer().getKind() != AsmToken::Identifier) 1582 return MatchOperand_NoMatch; 1583 1584 // Parse "e8,m1,t[a|u],m[a|u]" 1585 StringRef Name = getLexer().getTok().getIdentifier(); 1586 if (!Name.consume_front("e")) 1587 return MatchOperand_NoMatch; 1588 APInt Sew(16, Name, 10); 1589 if (Sew != 8 && Sew != 16 && Sew != 32 && Sew != 64 && Sew != 128 && 1590 Sew != 256 && Sew != 512 && Sew != 1024) 1591 return MatchOperand_NoMatch; 1592 getLexer().Lex(); 1593 1594 if (!getLexer().is(AsmToken::Comma)) 1595 return MatchOperand_NoMatch; 1596 getLexer().Lex(); 1597 1598 Name = getLexer().getTok().getIdentifier(); 1599 if (!Name.consume_front("m")) 1600 return MatchOperand_NoMatch; 1601 // "m" or "mf" 1602 bool Fractional = false; 1603 if (Name.consume_front("f")) { 1604 Fractional = true; 1605 } 1606 APInt Lmul(16, Name, 10); 1607 if (Lmul != 1 && Lmul != 2 && Lmul != 4 && Lmul != 8) 1608 return MatchOperand_NoMatch; 1609 getLexer().Lex(); 1610 1611 if (!getLexer().is(AsmToken::Comma)) 1612 return MatchOperand_NoMatch; 1613 getLexer().Lex(); 1614 1615 Name = getLexer().getTok().getIdentifier(); 1616 // ta or tu 1617 bool TailAgnostic; 1618 if (Name.consume_front("ta")) 1619 TailAgnostic = true; 1620 else if (Name.consume_front("tu")) 1621 TailAgnostic = false; 1622 else 1623 return MatchOperand_NoMatch; 1624 getLexer().Lex(); 1625 1626 if (!getLexer().is(AsmToken::Comma)) 1627 return MatchOperand_NoMatch; 1628 getLexer().Lex(); 1629 1630 Name = getLexer().getTok().getIdentifier(); 1631 // ma or mu 1632 bool MaskedoffAgnostic; 1633 if (Name.consume_front("ma")) 1634 MaskedoffAgnostic = true; 1635 else if (Name.consume_front("mu")) 1636 MaskedoffAgnostic = false; 1637 else 1638 return MatchOperand_NoMatch; 1639 getLexer().Lex(); 1640 1641 if (getLexer().getKind() != AsmToken::EndOfStatement) 1642 return MatchOperand_NoMatch; 1643 1644 Operands.push_back(RISCVOperand::createVType( 1645 Sew, Lmul, Fractional, TailAgnostic, MaskedoffAgnostic, S, isRV64())); 1646 1647 return MatchOperand_Success; 1648 } 1649 1650 OperandMatchResultTy RISCVAsmParser::parseMaskReg(OperandVector &Operands) { 1651 switch (getLexer().getKind()) { 1652 default: 1653 return MatchOperand_NoMatch; 1654 case AsmToken::Identifier: 1655 StringRef Name = getLexer().getTok().getIdentifier(); 1656 if (!Name.consume_back(".t")) { 1657 Error(getLoc(), "expected '.t' suffix"); 1658 return MatchOperand_ParseFail; 1659 } 1660 MCRegister RegNo; 1661 matchRegisterNameHelper(isRV32E(), RegNo, Name); 1662 1663 if (RegNo == RISCV::NoRegister) 1664 return MatchOperand_NoMatch; 1665 if (RegNo != RISCV::V0) 1666 return MatchOperand_NoMatch; 1667 SMLoc S = getLoc(); 1668 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1669 getLexer().Lex(); 1670 Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64())); 1671 } 1672 1673 return MatchOperand_Success; 1674 } 1675 1676 OperandMatchResultTy 1677 RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) { 1678 if (getLexer().isNot(AsmToken::LParen)) { 1679 Error(getLoc(), "expected '('"); 1680 return MatchOperand_ParseFail; 1681 } 1682 1683 getParser().Lex(); // Eat '(' 1684 Operands.push_back(RISCVOperand::createToken("(", getLoc(), isRV64())); 1685 1686 if (parseRegister(Operands) != MatchOperand_Success) { 1687 Error(getLoc(), "expected register"); 1688 return MatchOperand_ParseFail; 1689 } 1690 1691 if (getLexer().isNot(AsmToken::RParen)) { 1692 Error(getLoc(), "expected ')'"); 1693 return MatchOperand_ParseFail; 1694 } 1695 1696 getParser().Lex(); // Eat ')' 1697 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64())); 1698 1699 return MatchOperand_Success; 1700 } 1701 1702 OperandMatchResultTy RISCVAsmParser::parseAtomicMemOp(OperandVector &Operands) { 1703 // Atomic operations such as lr.w, sc.w, and amo*.w accept a "memory operand" 1704 // as one of their register operands, such as `(a0)`. This just denotes that 1705 // the register (in this case `a0`) contains a memory address. 1706 // 1707 // Normally, we would be able to parse these by putting the parens into the 1708 // instruction string. However, GNU as also accepts a zero-offset memory 1709 // operand (such as `0(a0)`), and ignores the 0. Normally this would be parsed 1710 // with parseImmediate followed by parseMemOpBaseReg, but these instructions 1711 // do not accept an immediate operand, and we do not want to add a "dummy" 1712 // operand that is silently dropped. 1713 // 1714 // Instead, we use this custom parser. This will: allow (and discard) an 1715 // offset if it is zero; require (and discard) parentheses; and add only the 1716 // parsed register operand to `Operands`. 1717 // 1718 // These operands are printed with RISCVInstPrinter::printAtomicMemOp, which 1719 // will only print the register surrounded by parentheses (which GNU as also 1720 // uses as its canonical representation for these operands). 1721 std::unique_ptr<RISCVOperand> OptionalImmOp; 1722 1723 if (getLexer().isNot(AsmToken::LParen)) { 1724 // Parse an Integer token. We do not accept arbritrary constant expressions 1725 // in the offset field (because they may include parens, which complicates 1726 // parsing a lot). 1727 int64_t ImmVal; 1728 SMLoc ImmStart = getLoc(); 1729 if (getParser().parseIntToken(ImmVal, 1730 "expected '(' or optional integer offset")) 1731 return MatchOperand_ParseFail; 1732 1733 // Create a RISCVOperand for checking later (so the error messages are 1734 // nicer), but we don't add it to Operands. 1735 SMLoc ImmEnd = getLoc(); 1736 OptionalImmOp = 1737 RISCVOperand::createImm(MCConstantExpr::create(ImmVal, getContext()), 1738 ImmStart, ImmEnd, isRV64()); 1739 } 1740 1741 if (getLexer().isNot(AsmToken::LParen)) { 1742 Error(getLoc(), OptionalImmOp ? "expected '(' after optional integer offset" 1743 : "expected '(' or optional integer offset"); 1744 return MatchOperand_ParseFail; 1745 } 1746 getParser().Lex(); // Eat '(' 1747 1748 if (parseRegister(Operands) != MatchOperand_Success) { 1749 Error(getLoc(), "expected register"); 1750 return MatchOperand_ParseFail; 1751 } 1752 1753 if (getLexer().isNot(AsmToken::RParen)) { 1754 Error(getLoc(), "expected ')'"); 1755 return MatchOperand_ParseFail; 1756 } 1757 getParser().Lex(); // Eat ')' 1758 1759 // Deferred Handling of non-zero offsets. This makes the error messages nicer. 1760 if (OptionalImmOp && !OptionalImmOp->isImmZero()) { 1761 Error(OptionalImmOp->getStartLoc(), "optional integer offset must be 0", 1762 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc())); 1763 return MatchOperand_ParseFail; 1764 } 1765 1766 return MatchOperand_Success; 1767 } 1768 1769 /// Looks at a token type and creates the relevant operand from this 1770 /// information, adding to Operands. If operand was parsed, returns false, else 1771 /// true. 1772 bool RISCVAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { 1773 // Check if the current operand has a custom associated parser, if so, try to 1774 // custom parse the operand, or fallback to the general approach. 1775 OperandMatchResultTy Result = 1776 MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true); 1777 if (Result == MatchOperand_Success) 1778 return false; 1779 if (Result == MatchOperand_ParseFail) 1780 return true; 1781 1782 // Attempt to parse token as a register. 1783 if (parseRegister(Operands, true) == MatchOperand_Success) 1784 return false; 1785 1786 // Attempt to parse token as an immediate 1787 if (parseImmediate(Operands) == MatchOperand_Success) { 1788 // Parse memory base register if present 1789 if (getLexer().is(AsmToken::LParen)) 1790 return parseMemOpBaseReg(Operands) != MatchOperand_Success; 1791 return false; 1792 } 1793 1794 // Finally we have exhausted all options and must declare defeat. 1795 Error(getLoc(), "unknown operand"); 1796 return true; 1797 } 1798 1799 bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info, 1800 StringRef Name, SMLoc NameLoc, 1801 OperandVector &Operands) { 1802 // Ensure that if the instruction occurs when relaxation is enabled, 1803 // relocations are forced for the file. Ideally this would be done when there 1804 // is enough information to reliably determine if the instruction itself may 1805 // cause relaxations. Unfortunately instruction processing stage occurs in the 1806 // same pass as relocation emission, so it's too late to set a 'sticky bit' 1807 // for the entire file. 1808 if (getSTI().getFeatureBits()[RISCV::FeatureRelax]) { 1809 auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr(); 1810 if (Assembler != nullptr) { 1811 RISCVAsmBackend &MAB = 1812 static_cast<RISCVAsmBackend &>(Assembler->getBackend()); 1813 MAB.setForceRelocs(); 1814 } 1815 } 1816 1817 // First operand is token for instruction 1818 Operands.push_back(RISCVOperand::createToken(Name, NameLoc, isRV64())); 1819 1820 // If there are no more operands, then finish 1821 if (getLexer().is(AsmToken::EndOfStatement)) 1822 return false; 1823 1824 // Parse first operand 1825 if (parseOperand(Operands, Name)) 1826 return true; 1827 1828 // Parse until end of statement, consuming commas between operands 1829 unsigned OperandIdx = 1; 1830 while (getLexer().is(AsmToken::Comma)) { 1831 // Consume comma token 1832 getLexer().Lex(); 1833 1834 // Parse next operand 1835 if (parseOperand(Operands, Name)) 1836 return true; 1837 1838 ++OperandIdx; 1839 } 1840 1841 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1842 SMLoc Loc = getLexer().getLoc(); 1843 getParser().eatToEndOfStatement(); 1844 return Error(Loc, "unexpected token"); 1845 } 1846 1847 getParser().Lex(); // Consume the EndOfStatement. 1848 return false; 1849 } 1850 1851 bool RISCVAsmParser::classifySymbolRef(const MCExpr *Expr, 1852 RISCVMCExpr::VariantKind &Kind, 1853 int64_t &Addend) { 1854 Kind = RISCVMCExpr::VK_RISCV_None; 1855 Addend = 0; 1856 1857 if (const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) { 1858 Kind = RE->getKind(); 1859 Expr = RE->getSubExpr(); 1860 } 1861 1862 // It's a simple symbol reference or constant with no addend. 1863 if (isa<MCConstantExpr>(Expr) || isa<MCSymbolRefExpr>(Expr)) 1864 return true; 1865 1866 const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr); 1867 if (!BE) 1868 return false; 1869 1870 if (!isa<MCSymbolRefExpr>(BE->getLHS())) 1871 return false; 1872 1873 if (BE->getOpcode() != MCBinaryExpr::Add && 1874 BE->getOpcode() != MCBinaryExpr::Sub) 1875 return false; 1876 1877 // We are able to support the subtraction of two symbol references 1878 if (BE->getOpcode() == MCBinaryExpr::Sub && 1879 isa<MCSymbolRefExpr>(BE->getRHS())) 1880 return true; 1881 1882 // See if the addend is a constant, otherwise there's more going 1883 // on here than we can deal with. 1884 auto AddendExpr = dyn_cast<MCConstantExpr>(BE->getRHS()); 1885 if (!AddendExpr) 1886 return false; 1887 1888 Addend = AddendExpr->getValue(); 1889 if (BE->getOpcode() == MCBinaryExpr::Sub) 1890 Addend = -Addend; 1891 1892 // It's some symbol reference + a constant addend 1893 return Kind != RISCVMCExpr::VK_RISCV_Invalid; 1894 } 1895 1896 bool RISCVAsmParser::ParseDirective(AsmToken DirectiveID) { 1897 // This returns false if this function recognizes the directive 1898 // regardless of whether it is successfully handles or reports an 1899 // error. Otherwise it returns true to give the generic parser a 1900 // chance at recognizing it. 1901 StringRef IDVal = DirectiveID.getString(); 1902 1903 if (IDVal == ".option") 1904 return parseDirectiveOption(); 1905 else if (IDVal == ".attribute") 1906 return parseDirectiveAttribute(); 1907 1908 return true; 1909 } 1910 1911 bool RISCVAsmParser::parseDirectiveOption() { 1912 MCAsmParser &Parser = getParser(); 1913 // Get the option token. 1914 AsmToken Tok = Parser.getTok(); 1915 // At the moment only identifiers are supported. 1916 if (Tok.isNot(AsmToken::Identifier)) 1917 return Error(Parser.getTok().getLoc(), 1918 "unexpected token, expected identifier"); 1919 1920 StringRef Option = Tok.getIdentifier(); 1921 1922 if (Option == "push") { 1923 getTargetStreamer().emitDirectiveOptionPush(); 1924 1925 Parser.Lex(); 1926 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1927 return Error(Parser.getTok().getLoc(), 1928 "unexpected token, expected end of statement"); 1929 1930 pushFeatureBits(); 1931 return false; 1932 } 1933 1934 if (Option == "pop") { 1935 SMLoc StartLoc = Parser.getTok().getLoc(); 1936 getTargetStreamer().emitDirectiveOptionPop(); 1937 1938 Parser.Lex(); 1939 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1940 return Error(Parser.getTok().getLoc(), 1941 "unexpected token, expected end of statement"); 1942 1943 if (popFeatureBits()) 1944 return Error(StartLoc, ".option pop with no .option push"); 1945 1946 return false; 1947 } 1948 1949 if (Option == "rvc") { 1950 getTargetStreamer().emitDirectiveOptionRVC(); 1951 1952 Parser.Lex(); 1953 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1954 return Error(Parser.getTok().getLoc(), 1955 "unexpected token, expected end of statement"); 1956 1957 setFeatureBits(RISCV::FeatureStdExtC, "c"); 1958 return false; 1959 } 1960 1961 if (Option == "norvc") { 1962 getTargetStreamer().emitDirectiveOptionNoRVC(); 1963 1964 Parser.Lex(); 1965 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1966 return Error(Parser.getTok().getLoc(), 1967 "unexpected token, expected end of statement"); 1968 1969 clearFeatureBits(RISCV::FeatureStdExtC, "c"); 1970 return false; 1971 } 1972 1973 if (Option == "pic") { 1974 getTargetStreamer().emitDirectiveOptionPIC(); 1975 1976 Parser.Lex(); 1977 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1978 return Error(Parser.getTok().getLoc(), 1979 "unexpected token, expected end of statement"); 1980 1981 ParserOptions.IsPicEnabled = true; 1982 return false; 1983 } 1984 1985 if (Option == "nopic") { 1986 getTargetStreamer().emitDirectiveOptionNoPIC(); 1987 1988 Parser.Lex(); 1989 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1990 return Error(Parser.getTok().getLoc(), 1991 "unexpected token, expected end of statement"); 1992 1993 ParserOptions.IsPicEnabled = false; 1994 return false; 1995 } 1996 1997 if (Option == "relax") { 1998 getTargetStreamer().emitDirectiveOptionRelax(); 1999 2000 Parser.Lex(); 2001 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 2002 return Error(Parser.getTok().getLoc(), 2003 "unexpected token, expected end of statement"); 2004 2005 setFeatureBits(RISCV::FeatureRelax, "relax"); 2006 return false; 2007 } 2008 2009 if (Option == "norelax") { 2010 getTargetStreamer().emitDirectiveOptionNoRelax(); 2011 2012 Parser.Lex(); 2013 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 2014 return Error(Parser.getTok().getLoc(), 2015 "unexpected token, expected end of statement"); 2016 2017 clearFeatureBits(RISCV::FeatureRelax, "relax"); 2018 return false; 2019 } 2020 2021 // Unknown option. 2022 Warning(Parser.getTok().getLoc(), 2023 "unknown option, expected 'push', 'pop', 'rvc', 'norvc', 'relax' or " 2024 "'norelax'"); 2025 Parser.eatToEndOfStatement(); 2026 return false; 2027 } 2028 2029 /// parseDirectiveAttribute 2030 /// ::= .attribute expression ',' ( expression | "string" ) 2031 /// ::= .attribute identifier ',' ( expression | "string" ) 2032 bool RISCVAsmParser::parseDirectiveAttribute() { 2033 MCAsmParser &Parser = getParser(); 2034 int64_t Tag; 2035 SMLoc TagLoc; 2036 TagLoc = Parser.getTok().getLoc(); 2037 if (Parser.getTok().is(AsmToken::Identifier)) { 2038 StringRef Name = Parser.getTok().getIdentifier(); 2039 Optional<unsigned> Ret = 2040 ELFAttrs::attrTypeFromString(Name, RISCVAttrs::RISCVAttributeTags); 2041 if (!Ret.hasValue()) { 2042 Error(TagLoc, "attribute name not recognised: " + Name); 2043 return false; 2044 } 2045 Tag = Ret.getValue(); 2046 Parser.Lex(); 2047 } else { 2048 const MCExpr *AttrExpr; 2049 2050 TagLoc = Parser.getTok().getLoc(); 2051 if (Parser.parseExpression(AttrExpr)) 2052 return true; 2053 2054 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr); 2055 if (check(!CE, TagLoc, "expected numeric constant")) 2056 return true; 2057 2058 Tag = CE->getValue(); 2059 } 2060 2061 if (Parser.parseToken(AsmToken::Comma, "comma expected")) 2062 return true; 2063 2064 StringRef StringValue; 2065 int64_t IntegerValue = 0; 2066 bool IsIntegerValue = true; 2067 2068 // RISC-V attributes have a string value if the tag number is odd 2069 // and an integer value if the tag number is even. 2070 if (Tag % 2) 2071 IsIntegerValue = false; 2072 2073 SMLoc ValueExprLoc = Parser.getTok().getLoc(); 2074 if (IsIntegerValue) { 2075 const MCExpr *ValueExpr; 2076 if (Parser.parseExpression(ValueExpr)) 2077 return true; 2078 2079 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr); 2080 if (!CE) 2081 return Error(ValueExprLoc, "expected numeric constant"); 2082 IntegerValue = CE->getValue(); 2083 } else { 2084 if (Parser.getTok().isNot(AsmToken::String)) 2085 return Error(Parser.getTok().getLoc(), "expected string constant"); 2086 2087 StringValue = Parser.getTok().getStringContents(); 2088 Parser.Lex(); 2089 } 2090 2091 if (Parser.parseToken(AsmToken::EndOfStatement, 2092 "unexpected token in '.attribute' directive")) 2093 return true; 2094 2095 if (Tag == RISCVAttrs::ARCH) { 2096 StringRef Arch = StringValue; 2097 if (Arch.consume_front("rv32")) 2098 clearFeatureBits(RISCV::Feature64Bit, "64bit"); 2099 else if (Arch.consume_front("rv64")) 2100 setFeatureBits(RISCV::Feature64Bit, "64bit"); 2101 else 2102 return Error(ValueExprLoc, "bad arch string " + Arch); 2103 2104 while (!Arch.empty()) { 2105 if (Arch[0] == 'i') 2106 clearFeatureBits(RISCV::FeatureRV32E, "e"); 2107 else if (Arch[0] == 'e') 2108 setFeatureBits(RISCV::FeatureRV32E, "e"); 2109 else if (Arch[0] == 'g') { 2110 clearFeatureBits(RISCV::FeatureRV32E, "e"); 2111 setFeatureBits(RISCV::FeatureStdExtM, "m"); 2112 setFeatureBits(RISCV::FeatureStdExtA, "a"); 2113 setFeatureBits(RISCV::FeatureStdExtF, "f"); 2114 setFeatureBits(RISCV::FeatureStdExtD, "d"); 2115 } else if (Arch[0] == 'm') 2116 setFeatureBits(RISCV::FeatureStdExtM, "m"); 2117 else if (Arch[0] == 'a') 2118 setFeatureBits(RISCV::FeatureStdExtA, "a"); 2119 else if (Arch[0] == 'f') 2120 setFeatureBits(RISCV::FeatureStdExtF, "f"); 2121 else if (Arch[0] == 'd') { 2122 setFeatureBits(RISCV::FeatureStdExtF, "f"); 2123 setFeatureBits(RISCV::FeatureStdExtD, "d"); 2124 } else if (Arch[0] == 'c') { 2125 setFeatureBits(RISCV::FeatureStdExtC, "c"); 2126 } else 2127 return Error(ValueExprLoc, "bad arch string " + Arch); 2128 2129 Arch = Arch.drop_front(1); 2130 int major = 0; 2131 int minor = 0; 2132 Arch.consumeInteger(10, major); 2133 Arch.consume_front("p"); 2134 Arch.consumeInteger(10, minor); 2135 if (major != 0 || minor != 0) { 2136 Arch = Arch.drop_until([](char c) { return c == '_' || c == '"'; }); 2137 Arch = Arch.drop_while([](char c) { return c == '_'; }); 2138 } 2139 } 2140 } 2141 2142 if (IsIntegerValue) 2143 getTargetStreamer().emitAttribute(Tag, IntegerValue); 2144 else { 2145 if (Tag != RISCVAttrs::ARCH) { 2146 getTargetStreamer().emitTextAttribute(Tag, StringValue); 2147 } else { 2148 std::string formalArchStr = "rv32"; 2149 if (getFeatureBits(RISCV::Feature64Bit)) 2150 formalArchStr = "rv64"; 2151 if (getFeatureBits(RISCV::FeatureRV32E)) 2152 formalArchStr = (Twine(formalArchStr) + "e1p9").str(); 2153 else 2154 formalArchStr = (Twine(formalArchStr) + "i2p0").str(); 2155 2156 if (getFeatureBits(RISCV::FeatureStdExtM)) 2157 formalArchStr = (Twine(formalArchStr) + "_m2p0").str(); 2158 if (getFeatureBits(RISCV::FeatureStdExtA)) 2159 formalArchStr = (Twine(formalArchStr) + "_a2p0").str(); 2160 if (getFeatureBits(RISCV::FeatureStdExtF)) 2161 formalArchStr = (Twine(formalArchStr) + "_f2p0").str(); 2162 if (getFeatureBits(RISCV::FeatureStdExtD)) 2163 formalArchStr = (Twine(formalArchStr) + "_d2p0").str(); 2164 if (getFeatureBits(RISCV::FeatureStdExtC)) 2165 formalArchStr = (Twine(formalArchStr) + "_c2p0").str(); 2166 2167 getTargetStreamer().emitTextAttribute(Tag, formalArchStr); 2168 } 2169 } 2170 2171 return false; 2172 } 2173 2174 void RISCVAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) { 2175 MCInst CInst; 2176 bool Res = compressInst(CInst, Inst, getSTI(), S.getContext()); 2177 if (Res) 2178 ++RISCVNumInstrsCompressed; 2179 S.emitInstruction((Res ? CInst : Inst), getSTI()); 2180 } 2181 2182 void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t Value, 2183 MCStreamer &Out) { 2184 RISCVMatInt::InstSeq Seq; 2185 RISCVMatInt::generateInstSeq(Value, isRV64(), Seq); 2186 2187 MCRegister SrcReg = RISCV::X0; 2188 for (RISCVMatInt::Inst &Inst : Seq) { 2189 if (Inst.Opc == RISCV::LUI) { 2190 emitToStreamer( 2191 Out, MCInstBuilder(RISCV::LUI).addReg(DestReg).addImm(Inst.Imm)); 2192 } else { 2193 emitToStreamer( 2194 Out, MCInstBuilder(Inst.Opc).addReg(DestReg).addReg(SrcReg).addImm( 2195 Inst.Imm)); 2196 } 2197 2198 // Only the first instruction has X0 as its source. 2199 SrcReg = DestReg; 2200 } 2201 } 2202 2203 void RISCVAsmParser::emitAuipcInstPair(MCOperand DestReg, MCOperand TmpReg, 2204 const MCExpr *Symbol, 2205 RISCVMCExpr::VariantKind VKHi, 2206 unsigned SecondOpcode, SMLoc IDLoc, 2207 MCStreamer &Out) { 2208 // A pair of instructions for PC-relative addressing; expands to 2209 // TmpLabel: AUIPC TmpReg, VKHi(symbol) 2210 // OP DestReg, TmpReg, %pcrel_lo(TmpLabel) 2211 MCContext &Ctx = getContext(); 2212 2213 MCSymbol *TmpLabel = Ctx.createTempSymbol( 2214 "pcrel_hi", /* AlwaysAddSuffix */ true, /* CanBeUnnamed */ false); 2215 Out.emitLabel(TmpLabel); 2216 2217 const RISCVMCExpr *SymbolHi = RISCVMCExpr::create(Symbol, VKHi, Ctx); 2218 emitToStreamer( 2219 Out, MCInstBuilder(RISCV::AUIPC).addOperand(TmpReg).addExpr(SymbolHi)); 2220 2221 const MCExpr *RefToLinkTmpLabel = 2222 RISCVMCExpr::create(MCSymbolRefExpr::create(TmpLabel, Ctx), 2223 RISCVMCExpr::VK_RISCV_PCREL_LO, Ctx); 2224 2225 emitToStreamer(Out, MCInstBuilder(SecondOpcode) 2226 .addOperand(DestReg) 2227 .addOperand(TmpReg) 2228 .addExpr(RefToLinkTmpLabel)); 2229 } 2230 2231 void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, 2232 MCStreamer &Out) { 2233 // The load local address pseudo-instruction "lla" is used in PC-relative 2234 // addressing of local symbols: 2235 // lla rdest, symbol 2236 // expands to 2237 // TmpLabel: AUIPC rdest, %pcrel_hi(symbol) 2238 // ADDI rdest, rdest, %pcrel_lo(TmpLabel) 2239 MCOperand DestReg = Inst.getOperand(0); 2240 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 2241 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI, 2242 RISCV::ADDI, IDLoc, Out); 2243 } 2244 2245 void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc, 2246 MCStreamer &Out) { 2247 // The load address pseudo-instruction "la" is used in PC-relative and 2248 // GOT-indirect addressing of global symbols: 2249 // la rdest, symbol 2250 // expands to either (for non-PIC) 2251 // TmpLabel: AUIPC rdest, %pcrel_hi(symbol) 2252 // ADDI rdest, rdest, %pcrel_lo(TmpLabel) 2253 // or (for PIC) 2254 // TmpLabel: AUIPC rdest, %got_pcrel_hi(symbol) 2255 // Lx rdest, %pcrel_lo(TmpLabel)(rdest) 2256 MCOperand DestReg = Inst.getOperand(0); 2257 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 2258 unsigned SecondOpcode; 2259 RISCVMCExpr::VariantKind VKHi; 2260 if (ParserOptions.IsPicEnabled) { 2261 SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW; 2262 VKHi = RISCVMCExpr::VK_RISCV_GOT_HI; 2263 } else { 2264 SecondOpcode = RISCV::ADDI; 2265 VKHi = RISCVMCExpr::VK_RISCV_PCREL_HI; 2266 } 2267 emitAuipcInstPair(DestReg, DestReg, Symbol, VKHi, SecondOpcode, IDLoc, Out); 2268 } 2269 2270 void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc, 2271 MCStreamer &Out) { 2272 // The load TLS IE address pseudo-instruction "la.tls.ie" is used in 2273 // initial-exec TLS model addressing of global symbols: 2274 // la.tls.ie rdest, symbol 2275 // expands to 2276 // TmpLabel: AUIPC rdest, %tls_ie_pcrel_hi(symbol) 2277 // Lx rdest, %pcrel_lo(TmpLabel)(rdest) 2278 MCOperand DestReg = Inst.getOperand(0); 2279 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 2280 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW; 2281 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_TLS_GOT_HI, 2282 SecondOpcode, IDLoc, Out); 2283 } 2284 2285 void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, 2286 MCStreamer &Out) { 2287 // The load TLS GD address pseudo-instruction "la.tls.gd" is used in 2288 // global-dynamic TLS model addressing of global symbols: 2289 // la.tls.gd rdest, symbol 2290 // expands to 2291 // TmpLabel: AUIPC rdest, %tls_gd_pcrel_hi(symbol) 2292 // ADDI rdest, rdest, %pcrel_lo(TmpLabel) 2293 MCOperand DestReg = Inst.getOperand(0); 2294 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 2295 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_TLS_GD_HI, 2296 RISCV::ADDI, IDLoc, Out); 2297 } 2298 2299 void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode, 2300 SMLoc IDLoc, MCStreamer &Out, 2301 bool HasTmpReg) { 2302 // The load/store pseudo-instruction does a pc-relative load with 2303 // a symbol. 2304 // 2305 // The expansion looks like this 2306 // 2307 // TmpLabel: AUIPC tmp, %pcrel_hi(symbol) 2308 // [S|L]X rd, %pcrel_lo(TmpLabel)(tmp) 2309 MCOperand DestReg = Inst.getOperand(0); 2310 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1; 2311 unsigned TmpRegOpIdx = HasTmpReg ? 1 : 0; 2312 MCOperand TmpReg = Inst.getOperand(TmpRegOpIdx); 2313 const MCExpr *Symbol = Inst.getOperand(SymbolOpIdx).getExpr(); 2314 emitAuipcInstPair(DestReg, TmpReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI, 2315 Opcode, IDLoc, Out); 2316 } 2317 2318 bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst, 2319 OperandVector &Operands) { 2320 assert(Inst.getOpcode() == RISCV::PseudoAddTPRel && "Invalid instruction"); 2321 assert(Inst.getOperand(2).isReg() && "Unexpected second operand kind"); 2322 if (Inst.getOperand(2).getReg() != RISCV::X4) { 2323 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc(); 2324 return Error(ErrorLoc, "the second input operand must be tp/x4 when using " 2325 "%tprel_add modifier"); 2326 } 2327 2328 return false; 2329 } 2330 2331 std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp() const { 2332 return RISCVOperand::createReg(RISCV::NoRegister, llvm::SMLoc(), 2333 llvm::SMLoc(), isRV64()); 2334 } 2335 2336 bool RISCVAsmParser::validateInstruction(MCInst &Inst, 2337 OperandVector &Operands) { 2338 const MCInstrDesc &MCID = MII.get(Inst.getOpcode()); 2339 unsigned TargetFlags = 2340 (MCID.TSFlags >> RISCVII::ConstraintOffset) & RISCVII::ConstraintMask; 2341 if (TargetFlags == RISCVII::NoConstraint) 2342 return false; 2343 2344 unsigned DestReg = Inst.getOperand(0).getReg(); 2345 unsigned CheckReg; 2346 // Operands[1] will be the first operand, DestReg. 2347 SMLoc Loc = Operands[1]->getStartLoc(); 2348 if (TargetFlags & RISCVII::VS2Constraint) { 2349 CheckReg = Inst.getOperand(1).getReg(); 2350 if (DestReg == CheckReg) 2351 return Error(Loc, "The destination vector register group cannot overlap" 2352 " the source vector register group."); 2353 } 2354 if ((TargetFlags & RISCVII::VS1Constraint) && (Inst.getOperand(2).isReg())) { 2355 CheckReg = Inst.getOperand(2).getReg(); 2356 if (DestReg == CheckReg) 2357 return Error(Loc, "The destination vector register group cannot overlap" 2358 " the source vector register group."); 2359 } 2360 if ((TargetFlags & RISCVII::VMConstraint) && (DestReg == RISCV::V0)) { 2361 // vadc, vsbc are special cases. These instructions have no mask register. 2362 // The destination register could not be V0. 2363 unsigned Opcode = Inst.getOpcode(); 2364 if (Opcode == RISCV::VADC_VVM || Opcode == RISCV::VADC_VXM || 2365 Opcode == RISCV::VADC_VIM || Opcode == RISCV::VSBC_VVM || 2366 Opcode == RISCV::VSBC_VXM) 2367 return Error(Loc, "The destination vector register group cannot be V0."); 2368 2369 // Regardless masked or unmasked version, the number of operands is the 2370 // same. For example, "viota.m v0, v2" is "viota.m v0, v2, NoRegister" 2371 // actually. We need to check the last operand to ensure whether it is 2372 // masked or not. 2373 if ((TargetFlags & RISCVII::OneInput) && (Inst.getNumOperands() == 3)) 2374 CheckReg = Inst.getOperand(2).getReg(); 2375 else if (Inst.getNumOperands() == 4) 2376 CheckReg = Inst.getOperand(3).getReg(); 2377 if (DestReg == CheckReg) 2378 return Error(Loc, "The destination vector register group cannot overlap" 2379 " the mask register."); 2380 } 2381 return false; 2382 } 2383 2384 bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 2385 OperandVector &Operands, 2386 MCStreamer &Out) { 2387 Inst.setLoc(IDLoc); 2388 2389 switch (Inst.getOpcode()) { 2390 default: 2391 break; 2392 case RISCV::PseudoLI: { 2393 MCRegister Reg = Inst.getOperand(0).getReg(); 2394 const MCOperand &Op1 = Inst.getOperand(1); 2395 if (Op1.isExpr()) { 2396 // We must have li reg, %lo(sym) or li reg, %pcrel_lo(sym) or similar. 2397 // Just convert to an addi. This allows compatibility with gas. 2398 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI) 2399 .addReg(Reg) 2400 .addReg(RISCV::X0) 2401 .addExpr(Op1.getExpr())); 2402 return false; 2403 } 2404 int64_t Imm = Inst.getOperand(1).getImm(); 2405 // On RV32 the immediate here can either be a signed or an unsigned 2406 // 32-bit number. Sign extension has to be performed to ensure that Imm 2407 // represents the expected signed 64-bit number. 2408 if (!isRV64()) 2409 Imm = SignExtend64<32>(Imm); 2410 emitLoadImm(Reg, Imm, Out); 2411 return false; 2412 } 2413 case RISCV::PseudoLLA: 2414 emitLoadLocalAddress(Inst, IDLoc, Out); 2415 return false; 2416 case RISCV::PseudoLA: 2417 emitLoadAddress(Inst, IDLoc, Out); 2418 return false; 2419 case RISCV::PseudoLA_TLS_IE: 2420 emitLoadTLSIEAddress(Inst, IDLoc, Out); 2421 return false; 2422 case RISCV::PseudoLA_TLS_GD: 2423 emitLoadTLSGDAddress(Inst, IDLoc, Out); 2424 return false; 2425 case RISCV::PseudoLB: 2426 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out, /*HasTmpReg=*/false); 2427 return false; 2428 case RISCV::PseudoLBU: 2429 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out, /*HasTmpReg=*/false); 2430 return false; 2431 case RISCV::PseudoLH: 2432 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out, /*HasTmpReg=*/false); 2433 return false; 2434 case RISCV::PseudoLHU: 2435 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out, /*HasTmpReg=*/false); 2436 return false; 2437 case RISCV::PseudoLW: 2438 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out, /*HasTmpReg=*/false); 2439 return false; 2440 case RISCV::PseudoLWU: 2441 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out, /*HasTmpReg=*/false); 2442 return false; 2443 case RISCV::PseudoLD: 2444 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out, /*HasTmpReg=*/false); 2445 return false; 2446 case RISCV::PseudoFLW: 2447 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out, /*HasTmpReg=*/true); 2448 return false; 2449 case RISCV::PseudoFLD: 2450 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out, /*HasTmpReg=*/true); 2451 return false; 2452 case RISCV::PseudoSB: 2453 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out, /*HasTmpReg=*/true); 2454 return false; 2455 case RISCV::PseudoSH: 2456 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out, /*HasTmpReg=*/true); 2457 return false; 2458 case RISCV::PseudoSW: 2459 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out, /*HasTmpReg=*/true); 2460 return false; 2461 case RISCV::PseudoSD: 2462 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out, /*HasTmpReg=*/true); 2463 return false; 2464 case RISCV::PseudoFSW: 2465 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out, /*HasTmpReg=*/true); 2466 return false; 2467 case RISCV::PseudoFSD: 2468 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out, /*HasTmpReg=*/true); 2469 return false; 2470 case RISCV::PseudoAddTPRel: 2471 if (checkPseudoAddTPRel(Inst, Operands)) 2472 return true; 2473 break; 2474 } 2475 2476 emitToStreamer(Out, Inst); 2477 return false; 2478 } 2479 2480 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVAsmParser() { 2481 RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target()); 2482 RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target()); 2483 } 2484