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