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