1 //===-- RISCVAsmParser.cpp - Parse RISCV assembly to MCInst instructions --===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "MCTargetDesc/RISCVAsmBackend.h" 11 #include "MCTargetDesc/RISCVMCExpr.h" 12 #include "MCTargetDesc/RISCVMCTargetDesc.h" 13 #include "MCTargetDesc/RISCVTargetStreamer.h" 14 #include "Utils/RISCVBaseInfo.h" 15 #include "llvm/ADT/STLExtras.h" 16 #include "llvm/ADT/StringSwitch.h" 17 #include "llvm/MC/MCAssembler.h" 18 #include "llvm/MC/MCContext.h" 19 #include "llvm/MC/MCExpr.h" 20 #include "llvm/MC/MCInst.h" 21 #include "llvm/MC/MCInstBuilder.h" 22 #include "llvm/MC/MCParser/MCAsmLexer.h" 23 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 24 #include "llvm/MC/MCParser/MCTargetAsmParser.h" 25 #include "llvm/MC/MCRegisterInfo.h" 26 #include "llvm/MC/MCStreamer.h" 27 #include "llvm/MC/MCSubtargetInfo.h" 28 #include "llvm/Support/Casting.h" 29 #include "llvm/Support/MathExtras.h" 30 #include "llvm/Support/TargetRegistry.h" 31 32 #include <limits> 33 34 using namespace llvm; 35 36 // Include the auto-generated portion of the compress emitter. 37 #define GEN_COMPRESS_INSTR 38 #include "RISCVGenCompressInstEmitter.inc" 39 40 namespace { 41 struct RISCVOperand; 42 43 class RISCVAsmParser : public MCTargetAsmParser { 44 SMLoc getLoc() const { return getParser().getTok().getLoc(); } 45 bool isRV64() const { return getSTI().hasFeature(RISCV::Feature64Bit); } 46 47 RISCVTargetStreamer &getTargetStreamer() { 48 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer(); 49 return static_cast<RISCVTargetStreamer &>(TS); 50 } 51 52 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, 53 unsigned Kind) override; 54 55 bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo, 56 int64_t Lower, int64_t Upper, Twine Msg); 57 58 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 59 OperandVector &Operands, MCStreamer &Out, 60 uint64_t &ErrorInfo, 61 bool MatchingInlineAsm) override; 62 63 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; 64 65 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 66 SMLoc NameLoc, OperandVector &Operands) override; 67 68 bool ParseDirective(AsmToken DirectiveID) override; 69 70 // Helper to actually emit an instruction to the MCStreamer. Also, when 71 // possible, compression of the instruction is performed. 72 void emitToStreamer(MCStreamer &S, const MCInst &Inst); 73 74 // Helper to emit a combination of LUI, ADDI(W), and SLLI instructions that 75 // synthesize the desired immedate value into the destination register. 76 void emitLoadImm(unsigned DestReg, int64_t Value, MCStreamer &Out); 77 78 // Helper to emit pseudo instruction "lla" used in PC-rel addressing. 79 void emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 80 81 /// Helper for processing MC instructions that have been successfully matched 82 /// by MatchAndEmitInstruction. Modifications to the emitted instructions, 83 /// like the expansion of pseudo instructions (e.g., "li"), can be performed 84 /// in this method. 85 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 86 87 // Auto-generated instruction matching functions 88 #define GET_ASSEMBLER_HEADER 89 #include "RISCVGenAsmMatcher.inc" 90 91 OperandMatchResultTy parseCSRSystemRegister(OperandVector &Operands); 92 OperandMatchResultTy parseImmediate(OperandVector &Operands); 93 OperandMatchResultTy parseRegister(OperandVector &Operands, 94 bool AllowParens = false); 95 OperandMatchResultTy parseMemOpBaseReg(OperandVector &Operands); 96 OperandMatchResultTy parseOperandWithModifier(OperandVector &Operands); 97 OperandMatchResultTy parseBareSymbol(OperandVector &Operands); 98 OperandMatchResultTy parseJALOffset(OperandVector &Operands); 99 100 bool parseOperand(OperandVector &Operands, StringRef Mnemonic); 101 102 bool parseDirectiveOption(); 103 104 void setFeatureBits(uint64_t Feature, StringRef FeatureString) { 105 if (!(getSTI().getFeatureBits()[Feature])) { 106 MCSubtargetInfo &STI = copySTI(); 107 setAvailableFeatures( 108 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); 109 } 110 } 111 112 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) { 113 if (getSTI().getFeatureBits()[Feature]) { 114 MCSubtargetInfo &STI = copySTI(); 115 setAvailableFeatures( 116 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); 117 } 118 } 119 120 public: 121 enum RISCVMatchResultTy { 122 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY, 123 #define GET_OPERAND_DIAGNOSTIC_TYPES 124 #include "RISCVGenAsmMatcher.inc" 125 #undef GET_OPERAND_DIAGNOSTIC_TYPES 126 }; 127 128 static bool classifySymbolRef(const MCExpr *Expr, 129 RISCVMCExpr::VariantKind &Kind, 130 int64_t &Addend); 131 132 RISCVAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, 133 const MCInstrInfo &MII, const MCTargetOptions &Options) 134 : MCTargetAsmParser(Options, STI, MII) { 135 Parser.addAliasForDirective(".half", ".2byte"); 136 Parser.addAliasForDirective(".hword", ".2byte"); 137 Parser.addAliasForDirective(".word", ".4byte"); 138 Parser.addAliasForDirective(".dword", ".8byte"); 139 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 140 } 141 }; 142 143 /// RISCVOperand - Instances of this class represent a parsed machine 144 /// instruction 145 struct RISCVOperand : public MCParsedAsmOperand { 146 147 enum KindTy { 148 Token, 149 Register, 150 Immediate, 151 SystemRegister 152 } Kind; 153 154 bool IsRV64; 155 156 struct RegOp { 157 unsigned RegNum; 158 }; 159 160 struct ImmOp { 161 const MCExpr *Val; 162 }; 163 164 struct SysRegOp { 165 const char *Data; 166 unsigned Length; 167 unsigned Encoding; 168 // FIXME: Add the Encoding parsed fields as needed for checks, 169 // e.g.: read/write or user/supervisor/machine privileges. 170 }; 171 172 SMLoc StartLoc, EndLoc; 173 union { 174 StringRef Tok; 175 RegOp Reg; 176 ImmOp Imm; 177 struct SysRegOp SysReg; 178 }; 179 180 RISCVOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 181 182 public: 183 RISCVOperand(const RISCVOperand &o) : MCParsedAsmOperand() { 184 Kind = o.Kind; 185 IsRV64 = o.IsRV64; 186 StartLoc = o.StartLoc; 187 EndLoc = o.EndLoc; 188 switch (Kind) { 189 case Register: 190 Reg = o.Reg; 191 break; 192 case Immediate: 193 Imm = o.Imm; 194 break; 195 case Token: 196 Tok = o.Tok; 197 break; 198 case SystemRegister: 199 SysReg = o.SysReg; 200 break; 201 } 202 } 203 204 bool isToken() const override { return Kind == Token; } 205 bool isReg() const override { return Kind == Register; } 206 bool isImm() const override { return Kind == Immediate; } 207 bool isMem() const override { return false; } 208 bool isSystemRegister() const { return Kind == SystemRegister; } 209 210 static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm, 211 RISCVMCExpr::VariantKind &VK) { 212 if (auto *RE = dyn_cast<RISCVMCExpr>(Expr)) { 213 VK = RE->getKind(); 214 return RE->evaluateAsConstant(Imm); 215 } 216 217 if (auto CE = dyn_cast<MCConstantExpr>(Expr)) { 218 VK = RISCVMCExpr::VK_RISCV_None; 219 Imm = CE->getValue(); 220 return true; 221 } 222 223 return false; 224 } 225 226 // True if operand is a symbol with no modifiers, or a constant with no 227 // modifiers and isShiftedInt<N-1, 1>(Op). 228 template <int N> bool isBareSimmNLsb0() const { 229 int64_t Imm; 230 RISCVMCExpr::VariantKind VK; 231 if (!isImm()) 232 return false; 233 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 234 bool IsValid; 235 if (!IsConstantImm) 236 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); 237 else 238 IsValid = isShiftedInt<N - 1, 1>(Imm); 239 return IsValid && VK == RISCVMCExpr::VK_RISCV_None; 240 } 241 242 // Predicate methods for AsmOperands defined in RISCVInstrInfo.td 243 244 bool isBareSymbol() const { 245 int64_t Imm; 246 RISCVMCExpr::VariantKind VK; 247 // Must be of 'immediate' type but not a constant. 248 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK)) 249 return false; 250 return RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm) && 251 VK == RISCVMCExpr::VK_RISCV_None; 252 } 253 254 bool isCSRSystemRegister() const { return isSystemRegister(); } 255 256 /// Return true if the operand is a valid for the fence instruction e.g. 257 /// ('iorw'). 258 bool isFenceArg() const { 259 if (!isImm()) 260 return false; 261 const MCExpr *Val = getImm(); 262 auto *SVal = dyn_cast<MCSymbolRefExpr>(Val); 263 if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None) 264 return false; 265 266 StringRef Str = SVal->getSymbol().getName(); 267 // Letters must be unique, taken from 'iorw', and in ascending order. This 268 // holds as long as each individual character is one of 'iorw' and is 269 // greater than the previous character. 270 char Prev = '\0'; 271 for (char c : Str) { 272 if (c != 'i' && c != 'o' && c != 'r' && c != 'w') 273 return false; 274 if (c <= Prev) 275 return false; 276 Prev = c; 277 } 278 return true; 279 } 280 281 /// Return true if the operand is a valid floating point rounding mode. 282 bool isFRMArg() const { 283 if (!isImm()) 284 return false; 285 const MCExpr *Val = getImm(); 286 auto *SVal = dyn_cast<MCSymbolRefExpr>(Val); 287 if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None) 288 return false; 289 290 StringRef Str = SVal->getSymbol().getName(); 291 292 return RISCVFPRndMode::stringToRoundingMode(Str) != RISCVFPRndMode::Invalid; 293 } 294 295 bool isImmXLen() const { 296 int64_t Imm; 297 RISCVMCExpr::VariantKind VK; 298 if (!isImm()) 299 return false; 300 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 301 // Given only Imm, ensuring that the actually specified constant is either 302 // a signed or unsigned 64-bit number is unfortunately impossible. 303 bool IsInRange = isRV64() ? true : isInt<32>(Imm) || isUInt<32>(Imm); 304 return IsConstantImm && IsInRange && VK == RISCVMCExpr::VK_RISCV_None; 305 } 306 307 bool isUImmLog2XLen() const { 308 int64_t Imm; 309 RISCVMCExpr::VariantKind VK; 310 if (!isImm()) 311 return false; 312 if (!evaluateConstantImm(getImm(), Imm, VK) || 313 VK != RISCVMCExpr::VK_RISCV_None) 314 return false; 315 return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm); 316 } 317 318 bool isUImmLog2XLenNonZero() const { 319 int64_t Imm; 320 RISCVMCExpr::VariantKind VK; 321 if (!isImm()) 322 return false; 323 if (!evaluateConstantImm(getImm(), Imm, VK) || 324 VK != RISCVMCExpr::VK_RISCV_None) 325 return false; 326 if (Imm == 0) 327 return false; 328 return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm); 329 } 330 331 bool isUImm5() const { 332 int64_t Imm; 333 RISCVMCExpr::VariantKind VK; 334 if (!isImm()) 335 return false; 336 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 337 return IsConstantImm && isUInt<5>(Imm) && VK == RISCVMCExpr::VK_RISCV_None; 338 } 339 340 bool isUImm5NonZero() const { 341 int64_t Imm; 342 RISCVMCExpr::VariantKind VK; 343 if (!isImm()) 344 return false; 345 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 346 return IsConstantImm && isUInt<5>(Imm) && (Imm != 0) && 347 VK == RISCVMCExpr::VK_RISCV_None; 348 } 349 350 bool isSImm6() const { 351 if (!isImm()) 352 return false; 353 RISCVMCExpr::VariantKind VK; 354 int64_t Imm; 355 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 356 return IsConstantImm && isInt<6>(Imm) && 357 VK == RISCVMCExpr::VK_RISCV_None; 358 } 359 360 bool isSImm6NonZero() const { 361 if (!isImm()) 362 return false; 363 RISCVMCExpr::VariantKind VK; 364 int64_t Imm; 365 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 366 return IsConstantImm && isInt<6>(Imm) && (Imm != 0) && 367 VK == RISCVMCExpr::VK_RISCV_None; 368 } 369 370 bool isCLUIImm() const { 371 if (!isImm()) 372 return false; 373 int64_t Imm; 374 RISCVMCExpr::VariantKind VK; 375 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 376 return IsConstantImm && (Imm != 0) && 377 (isUInt<5>(Imm) || (Imm >= 0xfffe0 && Imm <= 0xfffff)) && 378 VK == RISCVMCExpr::VK_RISCV_None; 379 } 380 381 bool isUImm7Lsb00() const { 382 if (!isImm()) 383 return false; 384 int64_t Imm; 385 RISCVMCExpr::VariantKind VK; 386 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 387 return IsConstantImm && isShiftedUInt<5, 2>(Imm) && 388 VK == RISCVMCExpr::VK_RISCV_None; 389 } 390 391 bool isUImm8Lsb00() const { 392 if (!isImm()) 393 return false; 394 int64_t Imm; 395 RISCVMCExpr::VariantKind VK; 396 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 397 return IsConstantImm && isShiftedUInt<6, 2>(Imm) && 398 VK == RISCVMCExpr::VK_RISCV_None; 399 } 400 401 bool isUImm8Lsb000() const { 402 if (!isImm()) 403 return false; 404 int64_t Imm; 405 RISCVMCExpr::VariantKind VK; 406 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 407 return IsConstantImm && isShiftedUInt<5, 3>(Imm) && 408 VK == RISCVMCExpr::VK_RISCV_None; 409 } 410 411 bool isSImm9Lsb0() const { return isBareSimmNLsb0<9>(); } 412 413 bool isUImm9Lsb000() const { 414 if (!isImm()) 415 return false; 416 int64_t Imm; 417 RISCVMCExpr::VariantKind VK; 418 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 419 return IsConstantImm && isShiftedUInt<6, 3>(Imm) && 420 VK == RISCVMCExpr::VK_RISCV_None; 421 } 422 423 bool isUImm10Lsb00NonZero() const { 424 if (!isImm()) 425 return false; 426 int64_t Imm; 427 RISCVMCExpr::VariantKind VK; 428 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 429 return IsConstantImm && isShiftedUInt<8, 2>(Imm) && (Imm != 0) && 430 VK == RISCVMCExpr::VK_RISCV_None; 431 } 432 433 bool isSImm12() const { 434 RISCVMCExpr::VariantKind VK; 435 int64_t Imm; 436 bool IsValid; 437 if (!isImm()) 438 return false; 439 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 440 if (!IsConstantImm) 441 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); 442 else 443 IsValid = isInt<12>(Imm); 444 return IsValid && ((IsConstantImm && VK == RISCVMCExpr::VK_RISCV_None) || 445 VK == RISCVMCExpr::VK_RISCV_LO || 446 VK == RISCVMCExpr::VK_RISCV_PCREL_LO); 447 } 448 449 bool isSImm12Lsb0() const { return isBareSimmNLsb0<12>(); } 450 451 bool isSImm13Lsb0() const { return isBareSimmNLsb0<13>(); } 452 453 bool isSImm10Lsb0000NonZero() const { 454 if (!isImm()) 455 return false; 456 int64_t Imm; 457 RISCVMCExpr::VariantKind VK; 458 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 459 return IsConstantImm && (Imm != 0) && isShiftedInt<6, 4>(Imm) && 460 VK == RISCVMCExpr::VK_RISCV_None; 461 } 462 463 bool isUImm20LUI() const { 464 RISCVMCExpr::VariantKind VK; 465 int64_t Imm; 466 bool IsValid; 467 if (!isImm()) 468 return false; 469 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 470 if (!IsConstantImm) { 471 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); 472 return IsValid && VK == RISCVMCExpr::VK_RISCV_HI; 473 } else { 474 return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None || 475 VK == RISCVMCExpr::VK_RISCV_HI); 476 } 477 } 478 479 bool isUImm20AUIPC() const { 480 RISCVMCExpr::VariantKind VK; 481 int64_t Imm; 482 bool IsValid; 483 if (!isImm()) 484 return false; 485 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 486 if (!IsConstantImm) { 487 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); 488 return IsValid && VK == RISCVMCExpr::VK_RISCV_PCREL_HI; 489 } else { 490 return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None || 491 VK == RISCVMCExpr::VK_RISCV_PCREL_HI); 492 } 493 } 494 495 bool isSImm21Lsb0JAL() const { return isBareSimmNLsb0<21>(); } 496 497 /// getStartLoc - Gets location of the first token of this operand 498 SMLoc getStartLoc() const override { return StartLoc; } 499 /// getEndLoc - Gets location of the last token of this operand 500 SMLoc getEndLoc() const override { return EndLoc; } 501 /// True if this operand is for an RV64 instruction 502 bool isRV64() const { return IsRV64; } 503 504 unsigned getReg() const override { 505 assert(Kind == Register && "Invalid type access!"); 506 return Reg.RegNum; 507 } 508 509 StringRef getSysReg() const { 510 assert(Kind == SystemRegister && "Invalid access!"); 511 return StringRef(SysReg.Data, SysReg.Length); 512 } 513 514 const MCExpr *getImm() const { 515 assert(Kind == Immediate && "Invalid type access!"); 516 return Imm.Val; 517 } 518 519 StringRef getToken() const { 520 assert(Kind == Token && "Invalid type access!"); 521 return Tok; 522 } 523 524 void print(raw_ostream &OS) const override { 525 switch (Kind) { 526 case Immediate: 527 OS << *getImm(); 528 break; 529 case Register: 530 OS << "<register x"; 531 OS << getReg() << ">"; 532 break; 533 case Token: 534 OS << "'" << getToken() << "'"; 535 break; 536 case SystemRegister: 537 OS << "<sysreg: " << getSysReg() << '>'; 538 break; 539 } 540 } 541 542 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S, 543 bool IsRV64) { 544 auto Op = make_unique<RISCVOperand>(Token); 545 Op->Tok = Str; 546 Op->StartLoc = S; 547 Op->EndLoc = S; 548 Op->IsRV64 = IsRV64; 549 return Op; 550 } 551 552 static std::unique_ptr<RISCVOperand> createReg(unsigned RegNo, SMLoc S, 553 SMLoc E, bool IsRV64) { 554 auto Op = make_unique<RISCVOperand>(Register); 555 Op->Reg.RegNum = RegNo; 556 Op->StartLoc = S; 557 Op->EndLoc = E; 558 Op->IsRV64 = IsRV64; 559 return Op; 560 } 561 562 static std::unique_ptr<RISCVOperand> createImm(const MCExpr *Val, SMLoc S, 563 SMLoc E, bool IsRV64) { 564 auto Op = make_unique<RISCVOperand>(Immediate); 565 Op->Imm.Val = Val; 566 Op->StartLoc = S; 567 Op->EndLoc = E; 568 Op->IsRV64 = IsRV64; 569 return Op; 570 } 571 572 static std::unique_ptr<RISCVOperand> 573 createSysReg(StringRef Str, SMLoc S, unsigned Encoding, bool IsRV64) { 574 auto Op = make_unique<RISCVOperand>(SystemRegister); 575 Op->SysReg.Data = Str.data(); 576 Op->SysReg.Length = Str.size(); 577 Op->SysReg.Encoding = Encoding; 578 Op->StartLoc = S; 579 Op->IsRV64 = IsRV64; 580 return Op; 581 } 582 583 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 584 assert(Expr && "Expr shouldn't be null!"); 585 int64_t Imm = 0; 586 RISCVMCExpr::VariantKind VK; 587 bool IsConstant = evaluateConstantImm(Expr, Imm, VK); 588 589 if (IsConstant) 590 Inst.addOperand(MCOperand::createImm(Imm)); 591 else 592 Inst.addOperand(MCOperand::createExpr(Expr)); 593 } 594 595 // Used by the TableGen Code 596 void addRegOperands(MCInst &Inst, unsigned N) const { 597 assert(N == 1 && "Invalid number of operands!"); 598 Inst.addOperand(MCOperand::createReg(getReg())); 599 } 600 601 void addImmOperands(MCInst &Inst, unsigned N) const { 602 assert(N == 1 && "Invalid number of operands!"); 603 addExpr(Inst, getImm()); 604 } 605 606 void addFenceArgOperands(MCInst &Inst, unsigned N) const { 607 assert(N == 1 && "Invalid number of operands!"); 608 // isFenceArg has validated the operand, meaning this cast is safe 609 auto SE = cast<MCSymbolRefExpr>(getImm()); 610 611 unsigned Imm = 0; 612 for (char c : SE->getSymbol().getName()) { 613 switch (c) { 614 default: 615 llvm_unreachable("FenceArg must contain only [iorw]"); 616 case 'i': Imm |= RISCVFenceField::I; break; 617 case 'o': Imm |= RISCVFenceField::O; break; 618 case 'r': Imm |= RISCVFenceField::R; break; 619 case 'w': Imm |= RISCVFenceField::W; break; 620 } 621 } 622 Inst.addOperand(MCOperand::createImm(Imm)); 623 } 624 625 void addCSRSystemRegisterOperands(MCInst &Inst, unsigned N) const { 626 assert(N == 1 && "Invalid number of operands!"); 627 Inst.addOperand(MCOperand::createImm(SysReg.Encoding)); 628 } 629 630 // Returns the rounding mode represented by this RISCVOperand. Should only 631 // be called after checking isFRMArg. 632 RISCVFPRndMode::RoundingMode getRoundingMode() const { 633 // isFRMArg has validated the operand, meaning this cast is safe. 634 auto SE = cast<MCSymbolRefExpr>(getImm()); 635 RISCVFPRndMode::RoundingMode FRM = 636 RISCVFPRndMode::stringToRoundingMode(SE->getSymbol().getName()); 637 assert(FRM != RISCVFPRndMode::Invalid && "Invalid rounding mode"); 638 return FRM; 639 } 640 641 void addFRMArgOperands(MCInst &Inst, unsigned N) const { 642 assert(N == 1 && "Invalid number of operands!"); 643 Inst.addOperand(MCOperand::createImm(getRoundingMode())); 644 } 645 }; 646 } // end anonymous namespace. 647 648 #define GET_REGISTER_MATCHER 649 #define GET_MATCHER_IMPLEMENTATION 650 #include "RISCVGenAsmMatcher.inc" 651 652 // Return the matching FPR64 register for the given FPR32. 653 // FIXME: Ideally this function could be removed in favour of using 654 // information from TableGen. 655 unsigned convertFPR32ToFPR64(unsigned Reg) { 656 switch (Reg) { 657 default: 658 llvm_unreachable("Not a recognised FPR32 register"); 659 case RISCV::F0_32: return RISCV::F0_64; 660 case RISCV::F1_32: return RISCV::F1_64; 661 case RISCV::F2_32: return RISCV::F2_64; 662 case RISCV::F3_32: return RISCV::F3_64; 663 case RISCV::F4_32: return RISCV::F4_64; 664 case RISCV::F5_32: return RISCV::F5_64; 665 case RISCV::F6_32: return RISCV::F6_64; 666 case RISCV::F7_32: return RISCV::F7_64; 667 case RISCV::F8_32: return RISCV::F8_64; 668 case RISCV::F9_32: return RISCV::F9_64; 669 case RISCV::F10_32: return RISCV::F10_64; 670 case RISCV::F11_32: return RISCV::F11_64; 671 case RISCV::F12_32: return RISCV::F12_64; 672 case RISCV::F13_32: return RISCV::F13_64; 673 case RISCV::F14_32: return RISCV::F14_64; 674 case RISCV::F15_32: return RISCV::F15_64; 675 case RISCV::F16_32: return RISCV::F16_64; 676 case RISCV::F17_32: return RISCV::F17_64; 677 case RISCV::F18_32: return RISCV::F18_64; 678 case RISCV::F19_32: return RISCV::F19_64; 679 case RISCV::F20_32: return RISCV::F20_64; 680 case RISCV::F21_32: return RISCV::F21_64; 681 case RISCV::F22_32: return RISCV::F22_64; 682 case RISCV::F23_32: return RISCV::F23_64; 683 case RISCV::F24_32: return RISCV::F24_64; 684 case RISCV::F25_32: return RISCV::F25_64; 685 case RISCV::F26_32: return RISCV::F26_64; 686 case RISCV::F27_32: return RISCV::F27_64; 687 case RISCV::F28_32: return RISCV::F28_64; 688 case RISCV::F29_32: return RISCV::F29_64; 689 case RISCV::F30_32: return RISCV::F30_64; 690 case RISCV::F31_32: return RISCV::F31_64; 691 } 692 } 693 694 unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp, 695 unsigned Kind) { 696 RISCVOperand &Op = static_cast<RISCVOperand &>(AsmOp); 697 if (!Op.isReg()) 698 return Match_InvalidOperand; 699 700 unsigned Reg = Op.getReg(); 701 bool IsRegFPR32 = 702 RISCVMCRegisterClasses[RISCV::FPR32RegClassID].contains(Reg); 703 bool IsRegFPR32C = 704 RISCVMCRegisterClasses[RISCV::FPR32CRegClassID].contains(Reg); 705 706 // As the parser couldn't differentiate an FPR32 from an FPR64, coerce the 707 // register from FPR32 to FPR64 or FPR32C to FPR64C if necessary. 708 if ((IsRegFPR32 && Kind == MCK_FPR64) || 709 (IsRegFPR32C && Kind == MCK_FPR64C)) { 710 Op.Reg.RegNum = convertFPR32ToFPR64(Reg); 711 return Match_Success; 712 } 713 return Match_InvalidOperand; 714 } 715 716 bool RISCVAsmParser::generateImmOutOfRangeError( 717 OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper, 718 Twine Msg = "immediate must be an integer in the range") { 719 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 720 return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]"); 721 } 722 723 bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 724 OperandVector &Operands, 725 MCStreamer &Out, 726 uint64_t &ErrorInfo, 727 bool MatchingInlineAsm) { 728 MCInst Inst; 729 730 auto Result = 731 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); 732 switch (Result) { 733 default: 734 break; 735 case Match_Success: 736 return processInstruction(Inst, IDLoc, Out); 737 case Match_MissingFeature: 738 return Error(IDLoc, "instruction use requires an option to be enabled"); 739 case Match_MnemonicFail: 740 return Error(IDLoc, "unrecognized instruction mnemonic"); 741 case Match_InvalidOperand: { 742 SMLoc ErrorLoc = IDLoc; 743 if (ErrorInfo != ~0U) { 744 if (ErrorInfo >= Operands.size()) 745 return Error(ErrorLoc, "too few operands for instruction"); 746 747 ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 748 if (ErrorLoc == SMLoc()) 749 ErrorLoc = IDLoc; 750 } 751 return Error(ErrorLoc, "invalid operand for instruction"); 752 } 753 } 754 755 // Handle the case when the error message is of specific type 756 // other than the generic Match_InvalidOperand, and the 757 // corresponding operand is missing. 758 if (Result > FIRST_TARGET_MATCH_RESULT_TY) { 759 SMLoc ErrorLoc = IDLoc; 760 if (ErrorInfo != ~0U && ErrorInfo >= Operands.size()) 761 return Error(ErrorLoc, "too few operands for instruction"); 762 } 763 764 switch(Result) { 765 default: 766 break; 767 case Match_InvalidImmXLen: 768 if (isRV64()) { 769 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 770 return Error(ErrorLoc, "operand must be a constant 64-bit integer"); 771 } 772 return generateImmOutOfRangeError(Operands, ErrorInfo, 773 std::numeric_limits<int32_t>::min(), 774 std::numeric_limits<uint32_t>::max()); 775 case Match_InvalidUImmLog2XLen: 776 if (isRV64()) 777 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1); 778 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 779 case Match_InvalidUImmLog2XLenNonZero: 780 if (isRV64()) 781 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1); 782 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1); 783 case Match_InvalidUImm5: 784 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 785 case Match_InvalidSImm6: 786 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5), 787 (1 << 5) - 1); 788 case Match_InvalidSImm6NonZero: 789 return generateImmOutOfRangeError( 790 Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1, 791 "immediate must be non-zero in the range"); 792 case Match_InvalidCLUIImm: 793 return generateImmOutOfRangeError( 794 Operands, ErrorInfo, 1, (1 << 5) - 1, 795 "immediate must be in [0xfffe0, 0xfffff] or"); 796 case Match_InvalidUImm7Lsb00: 797 return generateImmOutOfRangeError( 798 Operands, ErrorInfo, 0, (1 << 7) - 4, 799 "immediate must be a multiple of 4 bytes in the range"); 800 case Match_InvalidUImm8Lsb00: 801 return generateImmOutOfRangeError( 802 Operands, ErrorInfo, 0, (1 << 8) - 4, 803 "immediate must be a multiple of 4 bytes in the range"); 804 case Match_InvalidUImm8Lsb000: 805 return generateImmOutOfRangeError( 806 Operands, ErrorInfo, 0, (1 << 8) - 8, 807 "immediate must be a multiple of 8 bytes in the range"); 808 case Match_InvalidSImm9Lsb0: 809 return generateImmOutOfRangeError( 810 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2, 811 "immediate must be a multiple of 2 bytes in the range"); 812 case Match_InvalidUImm9Lsb000: 813 return generateImmOutOfRangeError( 814 Operands, ErrorInfo, 0, (1 << 9) - 8, 815 "immediate must be a multiple of 8 bytes in the range"); 816 case Match_InvalidUImm10Lsb00NonZero: 817 return generateImmOutOfRangeError( 818 Operands, ErrorInfo, 4, (1 << 10) - 4, 819 "immediate must be a multiple of 4 bytes in the range"); 820 case Match_InvalidSImm10Lsb0000NonZero: 821 return generateImmOutOfRangeError( 822 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16, 823 "immediate must be a multiple of 16 bytes and non-zero in the range"); 824 case Match_InvalidSImm12: 825 return generateImmOutOfRangeError( 826 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1, 827 "operand must be a symbol with %lo/%pcrel_lo modifier or an integer in " 828 "the range"); 829 case Match_InvalidSImm12Lsb0: 830 return generateImmOutOfRangeError( 831 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2, 832 "immediate must be a multiple of 2 bytes in the range"); 833 case Match_InvalidSImm13Lsb0: 834 return generateImmOutOfRangeError( 835 Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2, 836 "immediate must be a multiple of 2 bytes in the range"); 837 case Match_InvalidUImm20LUI: 838 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1, 839 "operand must be a symbol with %hi() " 840 "modifier or an integer in the range"); 841 case Match_InvalidUImm20AUIPC: 842 return generateImmOutOfRangeError( 843 Operands, ErrorInfo, 0, (1 << 20) - 1, 844 "operand must be a symbol with %pcrel_hi() modifier or an integer in " 845 "the range"); 846 case Match_InvalidSImm21Lsb0JAL: 847 return generateImmOutOfRangeError( 848 Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2, 849 "immediate must be a multiple of 2 bytes in the range"); 850 case Match_InvalidCSRSystemRegister: { 851 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1, 852 "operand must be a valid system register " 853 "name or an integer in the range"); 854 } 855 case Match_InvalidFenceArg: { 856 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 857 return Error( 858 ErrorLoc, 859 "operand must be formed of letters selected in-order from 'iorw'"); 860 } 861 case Match_InvalidFRMArg: { 862 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 863 return Error( 864 ErrorLoc, 865 "operand must be a valid floating point rounding mode mnemonic"); 866 } 867 case Match_InvalidBareSymbol: { 868 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 869 return Error(ErrorLoc, "operand must be a bare symbol name"); 870 } 871 } 872 873 llvm_unreachable("Unknown match type detected!"); 874 } 875 876 bool RISCVAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 877 SMLoc &EndLoc) { 878 const AsmToken &Tok = getParser().getTok(); 879 StartLoc = Tok.getLoc(); 880 EndLoc = Tok.getEndLoc(); 881 RegNo = 0; 882 StringRef Name = getLexer().getTok().getIdentifier(); 883 884 if (!MatchRegisterName(Name) || !MatchRegisterAltName(Name)) { 885 getParser().Lex(); // Eat identifier token. 886 return false; 887 } 888 889 return Error(StartLoc, "invalid register name"); 890 } 891 892 OperandMatchResultTy RISCVAsmParser::parseRegister(OperandVector &Operands, 893 bool AllowParens) { 894 SMLoc FirstS = getLoc(); 895 bool HadParens = false; 896 AsmToken Buf[2]; 897 898 // If this a parenthesised register name is allowed, parse it atomically 899 if (AllowParens && getLexer().is(AsmToken::LParen)) { 900 size_t ReadCount = getLexer().peekTokens(Buf); 901 if (ReadCount == 2 && Buf[1].getKind() == AsmToken::RParen) { 902 HadParens = true; 903 getParser().Lex(); // Eat '(' 904 } 905 } 906 907 switch (getLexer().getKind()) { 908 default: 909 return MatchOperand_NoMatch; 910 case AsmToken::Identifier: 911 StringRef Name = getLexer().getTok().getIdentifier(); 912 unsigned RegNo = MatchRegisterName(Name); 913 if (RegNo == 0) { 914 RegNo = MatchRegisterAltName(Name); 915 if (RegNo == 0) { 916 if (HadParens) 917 getLexer().UnLex(Buf[0]); 918 return MatchOperand_NoMatch; 919 } 920 } 921 if (HadParens) 922 Operands.push_back(RISCVOperand::createToken("(", FirstS, isRV64())); 923 SMLoc S = getLoc(); 924 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 925 getLexer().Lex(); 926 Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64())); 927 } 928 929 if (HadParens) { 930 getParser().Lex(); // Eat ')' 931 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64())); 932 } 933 934 return MatchOperand_Success; 935 } 936 937 OperandMatchResultTy 938 RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) { 939 SMLoc S = getLoc(); 940 const MCExpr *Res; 941 942 switch (getLexer().getKind()) { 943 default: 944 return MatchOperand_NoMatch; 945 case AsmToken::LParen: 946 case AsmToken::Minus: 947 case AsmToken::Plus: 948 case AsmToken::Integer: 949 case AsmToken::String: { 950 if (getParser().parseExpression(Res)) 951 return MatchOperand_ParseFail; 952 953 auto *CE = dyn_cast<MCConstantExpr>(Res); 954 if (CE) { 955 int64_t Imm = CE->getValue(); 956 if (isUInt<12>(Imm)) { 957 auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm); 958 // Accept an immediate representing a named or un-named Sys Reg 959 // if the range is valid, regardless of the required features. 960 Operands.push_back(RISCVOperand::createSysReg( 961 SysReg ? SysReg->Name : "", S, Imm, isRV64())); 962 return MatchOperand_Success; 963 } 964 } 965 966 Twine Msg = "immediate must be an integer in the range"; 967 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]"); 968 return MatchOperand_ParseFail; 969 } 970 case AsmToken::Identifier: { 971 StringRef Identifier; 972 if (getParser().parseIdentifier(Identifier)) 973 return MatchOperand_ParseFail; 974 975 auto SysReg = RISCVSysReg::lookupSysRegByName(Identifier); 976 // Accept a named Sys Reg if the required features are present. 977 if (SysReg) { 978 if (!SysReg->haveRequiredFeatures(getSTI().getFeatureBits())) { 979 Error(S, "system register use requires an option to be enabled"); 980 return MatchOperand_ParseFail; 981 } 982 Operands.push_back(RISCVOperand::createSysReg( 983 Identifier, S, SysReg->Encoding, isRV64())); 984 return MatchOperand_Success; 985 } 986 987 Twine Msg = "operand must be a valid system register name " 988 "or an integer in the range"; 989 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]"); 990 return MatchOperand_ParseFail; 991 } 992 case AsmToken::Percent: { 993 // Discard operand with modifier. 994 Twine Msg = "immediate must be an integer in the range"; 995 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]"); 996 return MatchOperand_ParseFail; 997 } 998 } 999 1000 return MatchOperand_NoMatch; 1001 } 1002 1003 OperandMatchResultTy RISCVAsmParser::parseImmediate(OperandVector &Operands) { 1004 SMLoc S = getLoc(); 1005 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1006 const MCExpr *Res; 1007 1008 switch (getLexer().getKind()) { 1009 default: 1010 return MatchOperand_NoMatch; 1011 case AsmToken::LParen: 1012 case AsmToken::Minus: 1013 case AsmToken::Plus: 1014 case AsmToken::Integer: 1015 case AsmToken::String: 1016 if (getParser().parseExpression(Res)) 1017 return MatchOperand_ParseFail; 1018 break; 1019 case AsmToken::Identifier: { 1020 StringRef Identifier; 1021 if (getParser().parseIdentifier(Identifier)) 1022 return MatchOperand_ParseFail; 1023 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); 1024 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1025 break; 1026 } 1027 case AsmToken::Percent: 1028 return parseOperandWithModifier(Operands); 1029 } 1030 1031 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1032 return MatchOperand_Success; 1033 } 1034 1035 OperandMatchResultTy 1036 RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) { 1037 SMLoc S = getLoc(); 1038 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1039 1040 if (getLexer().getKind() != AsmToken::Percent) { 1041 Error(getLoc(), "expected '%' for operand modifier"); 1042 return MatchOperand_ParseFail; 1043 } 1044 1045 getParser().Lex(); // Eat '%' 1046 1047 if (getLexer().getKind() != AsmToken::Identifier) { 1048 Error(getLoc(), "expected valid identifier for operand modifier"); 1049 return MatchOperand_ParseFail; 1050 } 1051 StringRef Identifier = getParser().getTok().getIdentifier(); 1052 RISCVMCExpr::VariantKind VK = RISCVMCExpr::getVariantKindForName(Identifier); 1053 if (VK == RISCVMCExpr::VK_RISCV_Invalid) { 1054 Error(getLoc(), "unrecognized operand modifier"); 1055 return MatchOperand_ParseFail; 1056 } 1057 1058 getParser().Lex(); // Eat the identifier 1059 if (getLexer().getKind() != AsmToken::LParen) { 1060 Error(getLoc(), "expected '('"); 1061 return MatchOperand_ParseFail; 1062 } 1063 getParser().Lex(); // Eat '(' 1064 1065 const MCExpr *SubExpr; 1066 if (getParser().parseParenExpression(SubExpr, E)) { 1067 return MatchOperand_ParseFail; 1068 } 1069 1070 const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, VK, getContext()); 1071 Operands.push_back(RISCVOperand::createImm(ModExpr, S, E, isRV64())); 1072 return MatchOperand_Success; 1073 } 1074 1075 OperandMatchResultTy RISCVAsmParser::parseBareSymbol(OperandVector &Operands) { 1076 SMLoc S = getLoc(); 1077 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1078 const MCExpr *Res; 1079 1080 if (getLexer().getKind() != AsmToken::Identifier) 1081 return MatchOperand_NoMatch; 1082 1083 StringRef Identifier; 1084 if (getParser().parseIdentifier(Identifier)) 1085 return MatchOperand_ParseFail; 1086 1087 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); 1088 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1089 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1090 return MatchOperand_Success; 1091 } 1092 1093 OperandMatchResultTy RISCVAsmParser::parseJALOffset(OperandVector &Operands) { 1094 // Parsing jal operands is fiddly due to the `jal foo` and `jal ra, foo` 1095 // both being acceptable forms. When parsing `jal ra, foo` this function 1096 // will be called for the `ra` register operand in an attempt to match the 1097 // single-operand alias. parseJALOffset must fail for this case. It would 1098 // seem logical to try parse the operand using parseImmediate and return 1099 // NoMatch if the next token is a comma (meaning we must be parsing a jal in 1100 // the second form rather than the first). We can't do this as there's no 1101 // way of rewinding the lexer state. Instead, return NoMatch if this operand 1102 // is an identifier and is followed by a comma. 1103 if (getLexer().is(AsmToken::Identifier) && 1104 getLexer().peekTok().is(AsmToken::Comma)) 1105 return MatchOperand_NoMatch; 1106 1107 return parseImmediate(Operands); 1108 } 1109 1110 OperandMatchResultTy 1111 RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) { 1112 if (getLexer().isNot(AsmToken::LParen)) { 1113 Error(getLoc(), "expected '('"); 1114 return MatchOperand_ParseFail; 1115 } 1116 1117 getParser().Lex(); // Eat '(' 1118 Operands.push_back(RISCVOperand::createToken("(", getLoc(), isRV64())); 1119 1120 if (parseRegister(Operands) != MatchOperand_Success) { 1121 Error(getLoc(), "expected register"); 1122 return MatchOperand_ParseFail; 1123 } 1124 1125 if (getLexer().isNot(AsmToken::RParen)) { 1126 Error(getLoc(), "expected ')'"); 1127 return MatchOperand_ParseFail; 1128 } 1129 1130 getParser().Lex(); // Eat ')' 1131 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64())); 1132 1133 return MatchOperand_Success; 1134 } 1135 1136 /// Looks at a token type and creates the relevant operand from this 1137 /// information, adding to Operands. If operand was parsed, returns false, else 1138 /// true. 1139 bool RISCVAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { 1140 // Check if the current operand has a custom associated parser, if so, try to 1141 // custom parse the operand, or fallback to the general approach. 1142 OperandMatchResultTy Result = 1143 MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true); 1144 if (Result == MatchOperand_Success) 1145 return false; 1146 if (Result == MatchOperand_ParseFail) 1147 return true; 1148 1149 // Attempt to parse token as a register. 1150 if (parseRegister(Operands, true) == MatchOperand_Success) 1151 return false; 1152 1153 // Attempt to parse token as an immediate 1154 if (parseImmediate(Operands) == MatchOperand_Success) { 1155 // Parse memory base register if present 1156 if (getLexer().is(AsmToken::LParen)) 1157 return parseMemOpBaseReg(Operands) != MatchOperand_Success; 1158 return false; 1159 } 1160 1161 // Finally we have exhausted all options and must declare defeat. 1162 Error(getLoc(), "unknown operand"); 1163 return true; 1164 } 1165 1166 bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info, 1167 StringRef Name, SMLoc NameLoc, 1168 OperandVector &Operands) { 1169 // Ensure that if the instruction occurs when relaxation is enabled, 1170 // relocations are forced for the file. Ideally this would be done when there 1171 // is enough information to reliably determine if the instruction itself may 1172 // cause relaxations. Unfortunately instruction processing stage occurs in the 1173 // same pass as relocation emission, so it's too late to set a 'sticky bit' 1174 // for the entire file. 1175 if (getSTI().getFeatureBits()[RISCV::FeatureRelax]) { 1176 auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr(); 1177 if (Assembler != nullptr) { 1178 RISCVAsmBackend &MAB = 1179 static_cast<RISCVAsmBackend &>(Assembler->getBackend()); 1180 MAB.setForceRelocs(); 1181 } 1182 } 1183 1184 // First operand is token for instruction 1185 Operands.push_back(RISCVOperand::createToken(Name, NameLoc, isRV64())); 1186 1187 // If there are no more operands, then finish 1188 if (getLexer().is(AsmToken::EndOfStatement)) 1189 return false; 1190 1191 // Parse first operand 1192 if (parseOperand(Operands, Name)) 1193 return true; 1194 1195 // Parse until end of statement, consuming commas between operands 1196 unsigned OperandIdx = 1; 1197 while (getLexer().is(AsmToken::Comma)) { 1198 // Consume comma token 1199 getLexer().Lex(); 1200 1201 // Parse next operand 1202 if (parseOperand(Operands, Name)) 1203 return true; 1204 1205 ++OperandIdx; 1206 } 1207 1208 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1209 SMLoc Loc = getLexer().getLoc(); 1210 getParser().eatToEndOfStatement(); 1211 return Error(Loc, "unexpected token"); 1212 } 1213 1214 getParser().Lex(); // Consume the EndOfStatement. 1215 return false; 1216 } 1217 1218 bool RISCVAsmParser::classifySymbolRef(const MCExpr *Expr, 1219 RISCVMCExpr::VariantKind &Kind, 1220 int64_t &Addend) { 1221 Kind = RISCVMCExpr::VK_RISCV_None; 1222 Addend = 0; 1223 1224 if (const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) { 1225 Kind = RE->getKind(); 1226 Expr = RE->getSubExpr(); 1227 } 1228 1229 // It's a simple symbol reference or constant with no addend. 1230 if (isa<MCConstantExpr>(Expr) || isa<MCSymbolRefExpr>(Expr)) 1231 return true; 1232 1233 const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr); 1234 if (!BE) 1235 return false; 1236 1237 if (!isa<MCSymbolRefExpr>(BE->getLHS())) 1238 return false; 1239 1240 if (BE->getOpcode() != MCBinaryExpr::Add && 1241 BE->getOpcode() != MCBinaryExpr::Sub) 1242 return false; 1243 1244 // We are able to support the subtraction of two symbol references 1245 if (BE->getOpcode() == MCBinaryExpr::Sub && 1246 isa<MCSymbolRefExpr>(BE->getRHS())) 1247 return true; 1248 1249 // See if the addend is a constant, otherwise there's more going 1250 // on here than we can deal with. 1251 auto AddendExpr = dyn_cast<MCConstantExpr>(BE->getRHS()); 1252 if (!AddendExpr) 1253 return false; 1254 1255 Addend = AddendExpr->getValue(); 1256 if (BE->getOpcode() == MCBinaryExpr::Sub) 1257 Addend = -Addend; 1258 1259 // It's some symbol reference + a constant addend 1260 return Kind != RISCVMCExpr::VK_RISCV_Invalid; 1261 } 1262 1263 bool RISCVAsmParser::ParseDirective(AsmToken DirectiveID) { 1264 // This returns false if this function recognizes the directive 1265 // regardless of whether it is successfully handles or reports an 1266 // error. Otherwise it returns true to give the generic parser a 1267 // chance at recognizing it. 1268 StringRef IDVal = DirectiveID.getString(); 1269 1270 if (IDVal == ".option") 1271 return parseDirectiveOption(); 1272 1273 return true; 1274 } 1275 1276 bool RISCVAsmParser::parseDirectiveOption() { 1277 MCAsmParser &Parser = getParser(); 1278 // Get the option token. 1279 AsmToken Tok = Parser.getTok(); 1280 // At the moment only identifiers are supported. 1281 if (Tok.isNot(AsmToken::Identifier)) 1282 return Error(Parser.getTok().getLoc(), 1283 "unexpected token, expected identifier"); 1284 1285 StringRef Option = Tok.getIdentifier(); 1286 1287 if (Option == "rvc") { 1288 getTargetStreamer().emitDirectiveOptionRVC(); 1289 1290 Parser.Lex(); 1291 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1292 return Error(Parser.getTok().getLoc(), 1293 "unexpected token, expected end of statement"); 1294 1295 setFeatureBits(RISCV::FeatureStdExtC, "c"); 1296 return false; 1297 } 1298 1299 if (Option == "norvc") { 1300 getTargetStreamer().emitDirectiveOptionNoRVC(); 1301 1302 Parser.Lex(); 1303 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1304 return Error(Parser.getTok().getLoc(), 1305 "unexpected token, expected end of statement"); 1306 1307 clearFeatureBits(RISCV::FeatureStdExtC, "c"); 1308 return false; 1309 } 1310 1311 if (Option == "relax") { 1312 getTargetStreamer().emitDirectiveOptionRelax(); 1313 1314 Parser.Lex(); 1315 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1316 return Error(Parser.getTok().getLoc(), 1317 "unexpected token, expected end of statement"); 1318 1319 setFeatureBits(RISCV::FeatureRelax, "relax"); 1320 return false; 1321 } 1322 1323 if (Option == "norelax") { 1324 getTargetStreamer().emitDirectiveOptionNoRelax(); 1325 1326 Parser.Lex(); 1327 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1328 return Error(Parser.getTok().getLoc(), 1329 "unexpected token, expected end of statement"); 1330 1331 clearFeatureBits(RISCV::FeatureRelax, "relax"); 1332 return false; 1333 } 1334 1335 // Unknown option. 1336 Warning(Parser.getTok().getLoc(), 1337 "unknown option, expected 'rvc', 'norvc', 'relax' or 'norelax'"); 1338 Parser.eatToEndOfStatement(); 1339 return false; 1340 } 1341 1342 void RISCVAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) { 1343 MCInst CInst; 1344 bool Res = compressInst(CInst, Inst, getSTI(), S.getContext()); 1345 CInst.setLoc(Inst.getLoc()); 1346 S.EmitInstruction((Res ? CInst : Inst), getSTI()); 1347 } 1348 1349 void RISCVAsmParser::emitLoadImm(unsigned DestReg, int64_t Value, 1350 MCStreamer &Out) { 1351 if (isInt<32>(Value)) { 1352 // Emits the MC instructions for loading a 32-bit constant into a register. 1353 // 1354 // Depending on the active bits in the immediate Value v, the following 1355 // instruction sequences are emitted: 1356 // 1357 // v == 0 : ADDI(W) 1358 // v[0,12) != 0 && v[12,32) == 0 : ADDI(W) 1359 // v[0,12) == 0 && v[12,32) != 0 : LUI 1360 // v[0,32) != 0 : LUI+ADDI(W) 1361 // 1362 int64_t Hi20 = ((Value + 0x800) >> 12) & 0xFFFFF; 1363 int64_t Lo12 = SignExtend64<12>(Value); 1364 unsigned SrcReg = RISCV::X0; 1365 1366 if (Hi20) { 1367 emitToStreamer(Out, 1368 MCInstBuilder(RISCV::LUI).addReg(DestReg).addImm(Hi20)); 1369 SrcReg = DestReg; 1370 } 1371 1372 if (Lo12 || Hi20 == 0) { 1373 unsigned AddiOpcode = 1374 STI->hasFeature(RISCV::Feature64Bit) ? RISCV::ADDIW : RISCV::ADDI; 1375 emitToStreamer(Out, MCInstBuilder(AddiOpcode) 1376 .addReg(DestReg) 1377 .addReg(SrcReg) 1378 .addImm(Lo12)); 1379 } 1380 return; 1381 } 1382 assert(STI->hasFeature(RISCV::Feature64Bit) && 1383 "Target must be 64-bit to support a >32-bit constant"); 1384 1385 // In the worst case, for a full 64-bit constant, a sequence of 8 instructions 1386 // (i.e., LUI+ADDIW+SLLI+ADDI+SLLI+ADDI+SLLI+ADDI) has to be emmitted. Note 1387 // that the first two instructions (LUI+ADDIW) can contribute up to 32 bits 1388 // while the following ADDI instructions contribute up to 12 bits each. 1389 // 1390 // On the first glance, implementing this seems to be possible by simply 1391 // emitting the most significant 32 bits (LUI+ADDIW) followed by as many left 1392 // shift (SLLI) and immediate additions (ADDI) as needed. However, due to the 1393 // fact that ADDI performs a sign extended addition, doing it like that would 1394 // only be possible when at most 11 bits of the ADDI instructions are used. 1395 // Using all 12 bits of the ADDI instructions, like done by GAS, actually 1396 // requires that the constant is processed starting with the least significant 1397 // bit. 1398 // 1399 // In the following, constants are processed from LSB to MSB but instruction 1400 // emission is performed from MSB to LSB by recursively calling 1401 // emitLoadImm. In each recursion, first the lowest 12 bits are removed 1402 // from the constant and the optimal shift amount, which can be greater than 1403 // 12 bits if the constant is sparse, is determined. Then, the shifted 1404 // remaining constant is processed recursively and gets emitted as soon as it 1405 // fits into 32 bits. The emission of the shifts and additions is subsequently 1406 // performed when the recursion returns. 1407 // 1408 int64_t Lo12 = SignExtend64<12>(Value); 1409 int64_t Hi52 = (Value + 0x800) >> 12; 1410 int ShiftAmount = 12 + findFirstSet((uint64_t)Hi52); 1411 Hi52 = SignExtend64(Hi52 >> (ShiftAmount - 12), 64 - ShiftAmount); 1412 1413 emitLoadImm(DestReg, Hi52, Out); 1414 1415 emitToStreamer(Out, MCInstBuilder(RISCV::SLLI) 1416 .addReg(DestReg) 1417 .addReg(DestReg) 1418 .addImm(ShiftAmount)); 1419 1420 if (Lo12) 1421 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI) 1422 .addReg(DestReg) 1423 .addReg(DestReg) 1424 .addImm(Lo12)); 1425 } 1426 1427 void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, 1428 MCStreamer &Out) { 1429 // The local load address pseudo-instruction "lla" is used in PC-relative 1430 // addressing of symbols: 1431 // lla rdest, symbol 1432 // expands to 1433 // TmpLabel: AUIPC rdest, %pcrel_hi(symbol) 1434 // ADDI rdest, %pcrel_lo(TmpLabel) 1435 MCContext &Ctx = getContext(); 1436 1437 MCSymbol *TmpLabel = Ctx.createTempSymbol( 1438 "pcrel_hi", /* AlwaysAddSuffix */ true, /* CanBeUnnamed */ false); 1439 Out.EmitLabel(TmpLabel); 1440 1441 MCOperand DestReg = Inst.getOperand(0); 1442 const RISCVMCExpr *Symbol = RISCVMCExpr::create( 1443 Inst.getOperand(1).getExpr(), RISCVMCExpr::VK_RISCV_PCREL_HI, Ctx); 1444 1445 emitToStreamer( 1446 Out, MCInstBuilder(RISCV::AUIPC).addOperand(DestReg).addExpr(Symbol)); 1447 1448 const MCExpr *RefToLinkTmpLabel = 1449 RISCVMCExpr::create(MCSymbolRefExpr::create(TmpLabel, Ctx), 1450 RISCVMCExpr::VK_RISCV_PCREL_LO, Ctx); 1451 1452 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI) 1453 .addOperand(DestReg) 1454 .addOperand(DestReg) 1455 .addExpr(RefToLinkTmpLabel)); 1456 } 1457 1458 bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 1459 MCStreamer &Out) { 1460 Inst.setLoc(IDLoc); 1461 1462 if (Inst.getOpcode() == RISCV::PseudoLI) { 1463 auto Reg = Inst.getOperand(0).getReg(); 1464 int64_t Imm = Inst.getOperand(1).getImm(); 1465 // On RV32 the immediate here can either be a signed or an unsigned 1466 // 32-bit number. Sign extension has to be performed to ensure that Imm 1467 // represents the expected signed 64-bit number. 1468 if (!isRV64()) 1469 Imm = SignExtend64<32>(Imm); 1470 emitLoadImm(Reg, Imm, Out); 1471 return false; 1472 } else if (Inst.getOpcode() == RISCV::PseudoLLA) { 1473 emitLoadLocalAddress(Inst, IDLoc, Out); 1474 return false; 1475 } 1476 1477 emitToStreamer(Out, Inst); 1478 return false; 1479 } 1480 1481 extern "C" void LLVMInitializeRISCVAsmParser() { 1482 RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target()); 1483 RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target()); 1484 } 1485