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