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