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/RISCVBaseInfo.h" 11 #include "MCTargetDesc/RISCVMCExpr.h" 12 #include "MCTargetDesc/RISCVMCTargetDesc.h" 13 #include "llvm/ADT/STLExtras.h" 14 #include "llvm/ADT/StringSwitch.h" 15 #include "llvm/MC/MCContext.h" 16 #include "llvm/MC/MCExpr.h" 17 #include "llvm/MC/MCInst.h" 18 #include "llvm/MC/MCParser/MCAsmLexer.h" 19 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 20 #include "llvm/MC/MCParser/MCTargetAsmParser.h" 21 #include "llvm/MC/MCRegisterInfo.h" 22 #include "llvm/MC/MCStreamer.h" 23 #include "llvm/MC/MCSubtargetInfo.h" 24 #include "llvm/Support/Casting.h" 25 #include "llvm/Support/TargetRegistry.h" 26 27 using namespace llvm; 28 29 namespace { 30 struct RISCVOperand; 31 32 class RISCVAsmParser : public MCTargetAsmParser { 33 SMLoc getLoc() const { return getParser().getTok().getLoc(); } 34 bool isRV64() const { return getSTI().hasFeature(RISCV::Feature64Bit); } 35 36 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, 37 unsigned Kind) override; 38 39 bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo, 40 int Lower, int Upper, Twine Msg); 41 42 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 43 OperandVector &Operands, MCStreamer &Out, 44 uint64_t &ErrorInfo, 45 bool MatchingInlineAsm) override; 46 47 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; 48 49 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 50 SMLoc NameLoc, OperandVector &Operands) override; 51 52 bool ParseDirective(AsmToken DirectiveID) override; 53 54 // Auto-generated instruction matching functions 55 #define GET_ASSEMBLER_HEADER 56 #include "RISCVGenAsmMatcher.inc" 57 58 OperandMatchResultTy parseImmediate(OperandVector &Operands); 59 OperandMatchResultTy parseRegister(OperandVector &Operands, 60 bool AllowParens = false); 61 OperandMatchResultTy parseMemOpBaseReg(OperandVector &Operands); 62 OperandMatchResultTy parseOperandWithModifier(OperandVector &Operands); 63 64 bool parseOperand(OperandVector &Operands); 65 66 public: 67 enum RISCVMatchResultTy { 68 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY, 69 #define GET_OPERAND_DIAGNOSTIC_TYPES 70 #include "RISCVGenAsmMatcher.inc" 71 #undef GET_OPERAND_DIAGNOSTIC_TYPES 72 }; 73 74 static bool classifySymbolRef(const MCExpr *Expr, 75 RISCVMCExpr::VariantKind &Kind, 76 int64_t &Addend); 77 78 RISCVAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, 79 const MCInstrInfo &MII, const MCTargetOptions &Options) 80 : MCTargetAsmParser(Options, STI, MII) { 81 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 82 } 83 }; 84 85 /// RISCVOperand - Instances of this class represent a parsed machine 86 /// instruction 87 struct RISCVOperand : public MCParsedAsmOperand { 88 89 enum KindTy { 90 Token, 91 Register, 92 Immediate, 93 } Kind; 94 95 bool IsRV64; 96 97 struct RegOp { 98 unsigned RegNum; 99 }; 100 101 struct ImmOp { 102 const MCExpr *Val; 103 }; 104 105 SMLoc StartLoc, EndLoc; 106 union { 107 StringRef Tok; 108 RegOp Reg; 109 ImmOp Imm; 110 }; 111 112 RISCVOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 113 114 public: 115 RISCVOperand(const RISCVOperand &o) : MCParsedAsmOperand() { 116 Kind = o.Kind; 117 IsRV64 = o.IsRV64; 118 StartLoc = o.StartLoc; 119 EndLoc = o.EndLoc; 120 switch (Kind) { 121 case Register: 122 Reg = o.Reg; 123 break; 124 case Immediate: 125 Imm = o.Imm; 126 break; 127 case Token: 128 Tok = o.Tok; 129 break; 130 } 131 } 132 133 bool isToken() const override { return Kind == Token; } 134 bool isReg() const override { return Kind == Register; } 135 bool isImm() const override { return Kind == Immediate; } 136 bool isMem() const override { return false; } 137 138 bool evaluateConstantImm(int64_t &Imm, RISCVMCExpr::VariantKind &VK) const { 139 const MCExpr *Val = getImm(); 140 bool Ret = false; 141 if (auto *RE = dyn_cast<RISCVMCExpr>(Val)) { 142 Ret = RE->evaluateAsConstant(Imm); 143 VK = RE->getKind(); 144 } else if (auto CE = dyn_cast<MCConstantExpr>(Val)) { 145 Ret = true; 146 VK = RISCVMCExpr::VK_RISCV_None; 147 Imm = CE->getValue(); 148 } 149 return Ret; 150 } 151 152 // True if operand is a symbol with no modifiers, or a constant with no 153 // modifiers and isShiftedInt<N-1, 1>(Op). 154 template <int N> bool isBareSimmNLsb0() const { 155 int64_t Imm; 156 RISCVMCExpr::VariantKind VK; 157 if (!isImm()) 158 return false; 159 bool IsConstantImm = evaluateConstantImm(Imm, VK); 160 bool IsValid; 161 if (!IsConstantImm) 162 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); 163 else 164 IsValid = isShiftedInt<N - 1, 1>(Imm); 165 return IsValid && VK == RISCVMCExpr::VK_RISCV_None; 166 } 167 168 // Predicate methods for AsmOperands defined in RISCVInstrInfo.td 169 170 /// Return true if the operand is a valid for the fence instruction e.g. 171 /// ('iorw'). 172 bool isFenceArg() const { 173 if (!isImm()) 174 return false; 175 const MCExpr *Val = getImm(); 176 auto *SVal = dyn_cast<MCSymbolRefExpr>(Val); 177 if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None) 178 return false; 179 180 StringRef Str = SVal->getSymbol().getName(); 181 // Letters must be unique, taken from 'iorw', and in ascending order. This 182 // holds as long as each individual character is one of 'iorw' and is 183 // greater than the previous character. 184 char Prev = '\0'; 185 for (char c : Str) { 186 if (c != 'i' && c != 'o' && c != 'r' && c != 'w') 187 return false; 188 if (c <= Prev) 189 return false; 190 Prev = c; 191 } 192 return true; 193 } 194 195 /// Return true if the operand is a valid floating point rounding mode. 196 bool isFRMArg() const { 197 if (!isImm()) 198 return false; 199 const MCExpr *Val = getImm(); 200 auto *SVal = dyn_cast<MCSymbolRefExpr>(Val); 201 if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None) 202 return false; 203 204 StringRef Str = SVal->getSymbol().getName(); 205 206 return RISCVFPRndMode::stringToRoundingMode(Str) != RISCVFPRndMode::Invalid; 207 } 208 209 bool isUImmLog2XLen() const { 210 int64_t Imm; 211 RISCVMCExpr::VariantKind VK; 212 if (!isImm()) 213 return false; 214 if (!evaluateConstantImm(Imm, VK) || VK != RISCVMCExpr::VK_RISCV_None) 215 return false; 216 return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm); 217 } 218 219 bool isUImmLog2XLenNonZero() const { 220 int64_t Imm; 221 RISCVMCExpr::VariantKind VK; 222 if (!isImm()) 223 return false; 224 if (!evaluateConstantImm(Imm, VK) || VK != RISCVMCExpr::VK_RISCV_None) 225 return false; 226 if (Imm == 0) 227 return false; 228 return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm); 229 } 230 231 bool isUImm5() const { 232 int64_t Imm; 233 RISCVMCExpr::VariantKind VK; 234 if (!isImm()) 235 return false; 236 bool IsConstantImm = evaluateConstantImm(Imm, VK); 237 return IsConstantImm && isUInt<5>(Imm) && VK == RISCVMCExpr::VK_RISCV_None; 238 } 239 240 bool isUImm5NonZero() const { 241 int64_t Imm; 242 RISCVMCExpr::VariantKind VK; 243 if (!isImm()) 244 return false; 245 bool IsConstantImm = evaluateConstantImm(Imm, VK); 246 return IsConstantImm && isUInt<5>(Imm) && (Imm != 0) && 247 VK == RISCVMCExpr::VK_RISCV_None; 248 } 249 250 bool isSImm6() const { 251 RISCVMCExpr::VariantKind VK; 252 int64_t Imm; 253 bool IsValid; 254 bool IsConstantImm = evaluateConstantImm(Imm, VK); 255 if (!IsConstantImm) 256 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); 257 else 258 IsValid = isInt<6>(Imm); 259 return IsValid && 260 (VK == RISCVMCExpr::VK_RISCV_None || VK == RISCVMCExpr::VK_RISCV_LO); 261 } 262 263 bool isUImm6NonZero() const { 264 int64_t Imm; 265 RISCVMCExpr::VariantKind VK; 266 bool IsConstantImm = evaluateConstantImm(Imm, VK); 267 return IsConstantImm && isUInt<6>(Imm) && (Imm != 0) && 268 VK == RISCVMCExpr::VK_RISCV_None; 269 } 270 271 bool isUImm7Lsb00() const { 272 int64_t Imm; 273 RISCVMCExpr::VariantKind VK; 274 bool IsConstantImm = evaluateConstantImm(Imm, VK); 275 return IsConstantImm && isShiftedUInt<5, 2>(Imm) && 276 VK == RISCVMCExpr::VK_RISCV_None; 277 } 278 279 bool isUImm8Lsb00() const { 280 int64_t Imm; 281 RISCVMCExpr::VariantKind VK; 282 bool IsConstantImm = evaluateConstantImm(Imm, VK); 283 return IsConstantImm && isShiftedUInt<6, 2>(Imm) && 284 VK == RISCVMCExpr::VK_RISCV_None; 285 } 286 287 bool isUImm8Lsb000() const { 288 int64_t Imm; 289 RISCVMCExpr::VariantKind VK; 290 bool IsConstantImm = evaluateConstantImm(Imm, VK); 291 return IsConstantImm && isShiftedUInt<5, 3>(Imm) && 292 VK == RISCVMCExpr::VK_RISCV_None; 293 } 294 295 bool isSImm9Lsb0() const { return isBareSimmNLsb0<9>(); } 296 297 bool isUImm9Lsb000() const { 298 int64_t Imm; 299 RISCVMCExpr::VariantKind VK; 300 bool IsConstantImm = evaluateConstantImm(Imm, VK); 301 return IsConstantImm && isShiftedUInt<6, 3>(Imm) && 302 VK == RISCVMCExpr::VK_RISCV_None; 303 } 304 305 bool isUImm10Lsb00NonZero() const { 306 int64_t Imm; 307 RISCVMCExpr::VariantKind VK; 308 bool IsConstantImm = evaluateConstantImm(Imm, VK); 309 return IsConstantImm && isShiftedUInt<8, 2>(Imm) && (Imm != 0) && 310 VK == RISCVMCExpr::VK_RISCV_None; 311 } 312 313 bool isSImm12() const { 314 RISCVMCExpr::VariantKind VK; 315 int64_t Imm; 316 bool IsValid; 317 if (!isImm()) 318 return false; 319 bool IsConstantImm = evaluateConstantImm(Imm, VK); 320 if (!IsConstantImm) 321 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); 322 else 323 IsValid = isInt<12>(Imm); 324 return IsValid && 325 (VK == RISCVMCExpr::VK_RISCV_None || VK == RISCVMCExpr::VK_RISCV_LO); 326 } 327 328 bool isSImm12Lsb0() const { return isBareSimmNLsb0<12>(); } 329 330 bool isUImm12() const { 331 int64_t Imm; 332 RISCVMCExpr::VariantKind VK; 333 if (!isImm()) 334 return false; 335 bool IsConstantImm = evaluateConstantImm(Imm, VK); 336 return IsConstantImm && isUInt<12>(Imm) && VK == RISCVMCExpr::VK_RISCV_None; 337 } 338 339 bool isSImm13Lsb0() const { return isBareSimmNLsb0<13>(); } 340 341 bool isSImm10Lsb0000() const { 342 int64_t Imm; 343 RISCVMCExpr::VariantKind VK; 344 bool IsConstantImm = evaluateConstantImm(Imm, VK); 345 return IsConstantImm && isShiftedInt<6, 4>(Imm) && 346 VK == RISCVMCExpr::VK_RISCV_None; 347 } 348 349 bool isUImm20() const { 350 RISCVMCExpr::VariantKind VK; 351 int64_t Imm; 352 bool IsValid; 353 if (!isImm()) 354 return false; 355 bool IsConstantImm = evaluateConstantImm(Imm, VK); 356 if (!IsConstantImm) 357 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); 358 else 359 IsValid = isUInt<20>(Imm); 360 return IsValid && (VK == RISCVMCExpr::VK_RISCV_None || 361 VK == RISCVMCExpr::VK_RISCV_HI || 362 VK == RISCVMCExpr::VK_RISCV_PCREL_HI); 363 } 364 365 bool isSImm21Lsb0() const { return isBareSimmNLsb0<21>(); } 366 367 /// getStartLoc - Gets location of the first token of this operand 368 SMLoc getStartLoc() const override { return StartLoc; } 369 /// getEndLoc - Gets location of the last token of this operand 370 SMLoc getEndLoc() const override { return EndLoc; } 371 /// True if this operand is for an RV64 instruction 372 bool isRV64() const { return IsRV64; } 373 374 unsigned getReg() const override { 375 assert(Kind == Register && "Invalid type access!"); 376 return Reg.RegNum; 377 } 378 379 const MCExpr *getImm() const { 380 assert(Kind == Immediate && "Invalid type access!"); 381 return Imm.Val; 382 } 383 384 StringRef getToken() const { 385 assert(Kind == Token && "Invalid type access!"); 386 return Tok; 387 } 388 389 void print(raw_ostream &OS) const override { 390 switch (Kind) { 391 case Immediate: 392 OS << *getImm(); 393 break; 394 case Register: 395 OS << "<register x"; 396 OS << getReg() << ">"; 397 break; 398 case Token: 399 OS << "'" << getToken() << "'"; 400 break; 401 } 402 } 403 404 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S, 405 bool IsRV64) { 406 auto Op = make_unique<RISCVOperand>(Token); 407 Op->Tok = Str; 408 Op->StartLoc = S; 409 Op->EndLoc = S; 410 Op->IsRV64 = IsRV64; 411 return Op; 412 } 413 414 static std::unique_ptr<RISCVOperand> createReg(unsigned RegNo, SMLoc S, 415 SMLoc E, bool IsRV64) { 416 auto Op = make_unique<RISCVOperand>(Register); 417 Op->Reg.RegNum = RegNo; 418 Op->StartLoc = S; 419 Op->EndLoc = E; 420 Op->IsRV64 = IsRV64; 421 return Op; 422 } 423 424 static std::unique_ptr<RISCVOperand> createImm(const MCExpr *Val, SMLoc S, 425 SMLoc E, bool IsRV64) { 426 auto Op = make_unique<RISCVOperand>(Immediate); 427 Op->Imm.Val = Val; 428 Op->StartLoc = S; 429 Op->EndLoc = E; 430 Op->IsRV64 = IsRV64; 431 return Op; 432 } 433 434 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 435 assert(Expr && "Expr shouldn't be null!"); 436 int64_t Imm = 0; 437 bool IsConstant = false; 438 if (auto *RE = dyn_cast<RISCVMCExpr>(Expr)) { 439 IsConstant = RE->evaluateAsConstant(Imm); 440 } else if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) { 441 IsConstant = true; 442 Imm = CE->getValue(); 443 } 444 445 if (IsConstant) 446 Inst.addOperand(MCOperand::createImm(Imm)); 447 else 448 Inst.addOperand(MCOperand::createExpr(Expr)); 449 } 450 451 // Used by the TableGen Code 452 void addRegOperands(MCInst &Inst, unsigned N) const { 453 assert(N == 1 && "Invalid number of operands!"); 454 Inst.addOperand(MCOperand::createReg(getReg())); 455 } 456 457 void addImmOperands(MCInst &Inst, unsigned N) const { 458 assert(N == 1 && "Invalid number of operands!"); 459 addExpr(Inst, getImm()); 460 } 461 462 void addFenceArgOperands(MCInst &Inst, unsigned N) const { 463 assert(N == 1 && "Invalid number of operands!"); 464 // isFenceArg has validated the operand, meaning this cast is safe 465 auto SE = cast<MCSymbolRefExpr>(getImm()); 466 467 unsigned Imm = 0; 468 for (char c : SE->getSymbol().getName()) { 469 switch (c) { 470 default: llvm_unreachable("FenceArg must contain only [iorw]"); 471 case 'i': Imm |= RISCVFenceField::I; break; 472 case 'o': Imm |= RISCVFenceField::O; break; 473 case 'r': Imm |= RISCVFenceField::R; break; 474 case 'w': Imm |= RISCVFenceField::W; break; 475 } 476 } 477 Inst.addOperand(MCOperand::createImm(Imm)); 478 } 479 480 // Returns the rounding mode represented by this RISCVOperand. Should only 481 // be called after checking isFRMArg. 482 RISCVFPRndMode::RoundingMode getRoundingMode() const { 483 // isFRMArg has validated the operand, meaning this cast is safe. 484 auto SE = cast<MCSymbolRefExpr>(getImm()); 485 RISCVFPRndMode::RoundingMode FRM = 486 RISCVFPRndMode::stringToRoundingMode(SE->getSymbol().getName()); 487 assert(FRM != RISCVFPRndMode::Invalid && "Invalid rounding mode"); 488 return FRM; 489 } 490 491 void addFRMArgOperands(MCInst &Inst, unsigned N) const { 492 assert(N == 1 && "Invalid number of operands!"); 493 Inst.addOperand(MCOperand::createImm(getRoundingMode())); 494 } 495 }; 496 } // end anonymous namespace. 497 498 #define GET_REGISTER_MATCHER 499 #define GET_MATCHER_IMPLEMENTATION 500 #include "RISCVGenAsmMatcher.inc" 501 502 // Return the matching FPR64 register for the given FPR32. 503 // FIXME: Ideally this function could be removed in favour of using 504 // information from TableGen. 505 unsigned convertFPR32ToFPR64(unsigned Reg) { 506 switch (Reg) { 507 default: 508 llvm_unreachable("Not a recognised FPR32 register"); 509 case RISCV::F0_32: return RISCV::F0_64; 510 case RISCV::F1_32: return RISCV::F1_64; 511 case RISCV::F2_32: return RISCV::F2_64; 512 case RISCV::F3_32: return RISCV::F3_64; 513 case RISCV::F4_32: return RISCV::F4_64; 514 case RISCV::F5_32: return RISCV::F5_64; 515 case RISCV::F6_32: return RISCV::F6_64; 516 case RISCV::F7_32: return RISCV::F7_64; 517 case RISCV::F8_32: return RISCV::F8_64; 518 case RISCV::F9_32: return RISCV::F9_64; 519 case RISCV::F10_32: return RISCV::F10_64; 520 case RISCV::F11_32: return RISCV::F11_64; 521 case RISCV::F12_32: return RISCV::F12_64; 522 case RISCV::F13_32: return RISCV::F13_64; 523 case RISCV::F14_32: return RISCV::F14_64; 524 case RISCV::F15_32: return RISCV::F15_64; 525 case RISCV::F16_32: return RISCV::F16_64; 526 case RISCV::F17_32: return RISCV::F17_64; 527 case RISCV::F18_32: return RISCV::F18_64; 528 case RISCV::F19_32: return RISCV::F19_64; 529 case RISCV::F20_32: return RISCV::F20_64; 530 case RISCV::F21_32: return RISCV::F21_64; 531 case RISCV::F22_32: return RISCV::F22_64; 532 case RISCV::F23_32: return RISCV::F23_64; 533 case RISCV::F24_32: return RISCV::F24_64; 534 case RISCV::F25_32: return RISCV::F25_64; 535 case RISCV::F26_32: return RISCV::F26_64; 536 case RISCV::F27_32: return RISCV::F27_64; 537 case RISCV::F28_32: return RISCV::F28_64; 538 case RISCV::F29_32: return RISCV::F29_64; 539 case RISCV::F30_32: return RISCV::F30_64; 540 case RISCV::F31_32: return RISCV::F31_64; 541 } 542 } 543 544 unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp, 545 unsigned Kind) { 546 RISCVOperand &Op = static_cast<RISCVOperand &>(AsmOp); 547 if (!Op.isReg()) 548 return Match_InvalidOperand; 549 550 unsigned Reg = Op.getReg(); 551 bool IsRegFPR32 = 552 RISCVMCRegisterClasses[RISCV::FPR32RegClassID].contains(Reg); 553 bool IsRegFPR32C = 554 RISCVMCRegisterClasses[RISCV::FPR32CRegClassID].contains(Reg); 555 556 // As the parser couldn't differentiate an FPR32 from an FPR64, coerce the 557 // register from FPR32 to FPR64 or FPR32C to FPR64C if necessary. 558 if ((IsRegFPR32 && Kind == MCK_FPR64) || 559 (IsRegFPR32C && Kind == MCK_FPR64C)) { 560 Op.Reg.RegNum = convertFPR32ToFPR64(Reg); 561 return Match_Success; 562 } 563 return Match_InvalidOperand; 564 } 565 566 bool RISCVAsmParser::generateImmOutOfRangeError( 567 OperandVector &Operands, uint64_t ErrorInfo, int Lower, int Upper, 568 Twine Msg = "immediate must be an integer in the range") { 569 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 570 return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]"); 571 } 572 573 bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 574 OperandVector &Operands, 575 MCStreamer &Out, 576 uint64_t &ErrorInfo, 577 bool MatchingInlineAsm) { 578 MCInst Inst; 579 580 switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) { 581 default: 582 break; 583 case Match_Success: 584 Inst.setLoc(IDLoc); 585 Out.EmitInstruction(Inst, getSTI()); 586 return false; 587 case Match_MissingFeature: 588 return Error(IDLoc, "instruction use requires an option to be enabled"); 589 case Match_MnemonicFail: 590 return Error(IDLoc, "unrecognized instruction mnemonic"); 591 case Match_InvalidOperand: { 592 SMLoc ErrorLoc = IDLoc; 593 if (ErrorInfo != ~0U) { 594 if (ErrorInfo >= Operands.size()) 595 return Error(ErrorLoc, "too few operands for instruction"); 596 597 ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 598 if (ErrorLoc == SMLoc()) 599 ErrorLoc = IDLoc; 600 } 601 return Error(ErrorLoc, "invalid operand for instruction"); 602 } 603 case Match_InvalidUImmLog2XLen: 604 if (isRV64()) 605 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1); 606 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 607 case Match_InvalidUImmLog2XLenNonZero: 608 if (isRV64()) 609 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1); 610 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1); 611 case Match_InvalidUImm5: 612 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 613 case Match_InvalidSImm6: 614 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5), 615 (1 << 5) - 1); 616 case Match_InvalidUImm6NonZero: 617 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1); 618 case Match_InvalidUImm7Lsb00: 619 return generateImmOutOfRangeError( 620 Operands, ErrorInfo, 0, (1 << 7) - 4, 621 "immediate must be a multiple of 4 bytes in the range"); 622 case Match_InvalidUImm8Lsb00: 623 return generateImmOutOfRangeError( 624 Operands, ErrorInfo, 0, (1 << 8) - 4, 625 "immediate must be a multiple of 4 bytes in the range"); 626 case Match_InvalidUImm8Lsb000: 627 return generateImmOutOfRangeError( 628 Operands, ErrorInfo, 0, (1 << 8) - 8, 629 "immediate must be a multiple of 8 bytes in the range"); 630 case Match_InvalidSImm9Lsb0: 631 return generateImmOutOfRangeError( 632 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2, 633 "immediate must be a multiple of 2 bytes in the range"); 634 case Match_InvalidUImm9Lsb000: 635 return generateImmOutOfRangeError( 636 Operands, ErrorInfo, 0, (1 << 9) - 8, 637 "immediate must be a multiple of 8 bytes in the range"); 638 case Match_InvalidUImm10Lsb00NonZero: 639 return generateImmOutOfRangeError( 640 Operands, ErrorInfo, 4, (1 << 10) - 4, 641 "immediate must be a multiple of 4 bytes in the range"); 642 case Match_InvalidSImm10Lsb0000: 643 return generateImmOutOfRangeError( 644 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16, 645 "immediate must be a multiple of 16 bytes in the range"); 646 case Match_InvalidSImm12: 647 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 11), 648 (1 << 11) - 1); 649 case Match_InvalidSImm12Lsb0: 650 return generateImmOutOfRangeError( 651 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2, 652 "immediate must be a multiple of 2 bytes in the range"); 653 case Match_InvalidUImm12: 654 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1); 655 case Match_InvalidSImm13Lsb0: 656 return generateImmOutOfRangeError( 657 Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2, 658 "immediate must be a multiple of 2 bytes in the range"); 659 case Match_InvalidUImm20: 660 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1); 661 case Match_InvalidSImm21Lsb0: 662 return generateImmOutOfRangeError( 663 Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2, 664 "immediate must be a multiple of 2 bytes in the range"); 665 case Match_InvalidFenceArg: { 666 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 667 return Error( 668 ErrorLoc, 669 "operand must be formed of letters selected in-order from 'iorw'"); 670 } 671 case Match_InvalidFRMArg: { 672 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 673 return Error( 674 ErrorLoc, 675 "operand must be a valid floating point rounding mode mnemonic"); 676 } 677 } 678 679 llvm_unreachable("Unknown match type detected!"); 680 } 681 682 bool RISCVAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 683 SMLoc &EndLoc) { 684 const AsmToken &Tok = getParser().getTok(); 685 StartLoc = Tok.getLoc(); 686 EndLoc = Tok.getEndLoc(); 687 RegNo = 0; 688 StringRef Name = getLexer().getTok().getIdentifier(); 689 690 if (!MatchRegisterName(Name) || !MatchRegisterAltName(Name)) { 691 getParser().Lex(); // Eat identifier token. 692 return false; 693 } 694 695 return Error(StartLoc, "invalid register name"); 696 } 697 698 OperandMatchResultTy RISCVAsmParser::parseRegister(OperandVector &Operands, 699 bool AllowParens) { 700 SMLoc FirstS = getLoc(); 701 bool HadParens = false; 702 AsmToken Buf[2]; 703 704 // If this a parenthesised register name is allowed, parse it atomically 705 if (AllowParens && getLexer().is(AsmToken::LParen)) { 706 size_t ReadCount = getLexer().peekTokens(Buf); 707 if (ReadCount == 2 && Buf[1].getKind() == AsmToken::RParen) { 708 HadParens = true; 709 getParser().Lex(); // Eat '(' 710 } 711 } 712 713 switch (getLexer().getKind()) { 714 default: 715 return MatchOperand_NoMatch; 716 case AsmToken::Identifier: 717 StringRef Name = getLexer().getTok().getIdentifier(); 718 unsigned RegNo = MatchRegisterName(Name); 719 if (RegNo == 0) { 720 RegNo = MatchRegisterAltName(Name); 721 if (RegNo == 0) { 722 if (HadParens) 723 getLexer().UnLex(Buf[0]); 724 return MatchOperand_NoMatch; 725 } 726 } 727 if (HadParens) 728 Operands.push_back(RISCVOperand::createToken("(", FirstS, isRV64())); 729 SMLoc S = getLoc(); 730 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 731 getLexer().Lex(); 732 Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64())); 733 } 734 735 if (HadParens) { 736 getParser().Lex(); // Eat ')' 737 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64())); 738 } 739 740 return MatchOperand_Success; 741 } 742 743 OperandMatchResultTy RISCVAsmParser::parseImmediate(OperandVector &Operands) { 744 SMLoc S = getLoc(); 745 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 746 const MCExpr *Res; 747 748 switch (getLexer().getKind()) { 749 default: 750 return MatchOperand_NoMatch; 751 case AsmToken::LParen: 752 case AsmToken::Minus: 753 case AsmToken::Plus: 754 case AsmToken::Integer: 755 case AsmToken::String: 756 if (getParser().parseExpression(Res)) 757 return MatchOperand_ParseFail; 758 break; 759 case AsmToken::Identifier: { 760 StringRef Identifier; 761 if (getParser().parseIdentifier(Identifier)) 762 return MatchOperand_ParseFail; 763 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); 764 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 765 break; 766 } 767 case AsmToken::Percent: 768 return parseOperandWithModifier(Operands); 769 } 770 771 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 772 return MatchOperand_Success; 773 } 774 775 OperandMatchResultTy 776 RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) { 777 SMLoc S = getLoc(); 778 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 779 780 if (getLexer().getKind() != AsmToken::Percent) { 781 Error(getLoc(), "expected '%' for operand modifier"); 782 return MatchOperand_ParseFail; 783 } 784 785 getParser().Lex(); // Eat '%' 786 787 if (getLexer().getKind() != AsmToken::Identifier) { 788 Error(getLoc(), "expected valid identifier for operand modifier"); 789 return MatchOperand_ParseFail; 790 } 791 StringRef Identifier = getParser().getTok().getIdentifier(); 792 RISCVMCExpr::VariantKind VK = RISCVMCExpr::getVariantKindForName(Identifier); 793 if (VK == RISCVMCExpr::VK_RISCV_Invalid) { 794 Error(getLoc(), "unrecognized operand modifier"); 795 return MatchOperand_ParseFail; 796 } 797 798 getParser().Lex(); // Eat the identifier 799 if (getLexer().getKind() != AsmToken::LParen) { 800 Error(getLoc(), "expected '('"); 801 return MatchOperand_ParseFail; 802 } 803 getParser().Lex(); // Eat '(' 804 805 const MCExpr *SubExpr; 806 if (getParser().parseParenExpression(SubExpr, E)) { 807 return MatchOperand_ParseFail; 808 } 809 810 const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, VK, getContext()); 811 Operands.push_back(RISCVOperand::createImm(ModExpr, S, E, isRV64())); 812 return MatchOperand_Success; 813 } 814 815 OperandMatchResultTy 816 RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) { 817 if (getLexer().isNot(AsmToken::LParen)) { 818 Error(getLoc(), "expected '('"); 819 return MatchOperand_ParseFail; 820 } 821 822 getParser().Lex(); // Eat '(' 823 Operands.push_back(RISCVOperand::createToken("(", getLoc(), isRV64())); 824 825 if (parseRegister(Operands) != MatchOperand_Success) { 826 Error(getLoc(), "expected register"); 827 return MatchOperand_ParseFail; 828 } 829 830 if (getLexer().isNot(AsmToken::RParen)) { 831 Error(getLoc(), "expected ')'"); 832 return MatchOperand_ParseFail; 833 } 834 835 getParser().Lex(); // Eat ')' 836 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64())); 837 838 return MatchOperand_Success; 839 } 840 841 /// Looks at a token type and creates the relevant operand 842 /// from this information, adding to Operands. 843 /// If operand was parsed, returns false, else true. 844 bool RISCVAsmParser::parseOperand(OperandVector &Operands) { 845 // Attempt to parse token as register 846 if (parseRegister(Operands, true) == MatchOperand_Success) 847 return false; 848 849 // Attempt to parse token as an immediate 850 if (parseImmediate(Operands) == MatchOperand_Success) { 851 // Parse memory base register if present 852 if (getLexer().is(AsmToken::LParen)) 853 return parseMemOpBaseReg(Operands) != MatchOperand_Success; 854 return false; 855 } 856 857 // Finally we have exhausted all options and must declare defeat. 858 Error(getLoc(), "unknown operand"); 859 return true; 860 } 861 862 bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info, 863 StringRef Name, SMLoc NameLoc, 864 OperandVector &Operands) { 865 // First operand is token for instruction 866 Operands.push_back(RISCVOperand::createToken(Name, NameLoc, isRV64())); 867 868 // If there are no more operands, then finish 869 if (getLexer().is(AsmToken::EndOfStatement)) 870 return false; 871 872 // Parse first operand 873 if (parseOperand(Operands)) 874 return true; 875 876 // Parse until end of statement, consuming commas between operands 877 while (getLexer().is(AsmToken::Comma)) { 878 // Consume comma token 879 getLexer().Lex(); 880 881 // Parse next operand 882 if (parseOperand(Operands)) 883 return true; 884 } 885 886 if (getLexer().isNot(AsmToken::EndOfStatement)) { 887 SMLoc Loc = getLexer().getLoc(); 888 getParser().eatToEndOfStatement(); 889 return Error(Loc, "unexpected token"); 890 } 891 892 getParser().Lex(); // Consume the EndOfStatement. 893 return false; 894 } 895 896 bool RISCVAsmParser::classifySymbolRef(const MCExpr *Expr, 897 RISCVMCExpr::VariantKind &Kind, 898 int64_t &Addend) { 899 Kind = RISCVMCExpr::VK_RISCV_None; 900 Addend = 0; 901 902 if (const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) { 903 Kind = RE->getKind(); 904 Expr = RE->getSubExpr(); 905 } 906 907 // It's a simple symbol reference or constant with no addend. 908 if (isa<MCConstantExpr>(Expr) || isa<MCSymbolRefExpr>(Expr)) 909 return true; 910 911 const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr); 912 if (!BE) 913 return false; 914 915 if (!isa<MCSymbolRefExpr>(BE->getLHS())) 916 return false; 917 918 if (BE->getOpcode() != MCBinaryExpr::Add && 919 BE->getOpcode() != MCBinaryExpr::Sub) 920 return false; 921 922 // We are able to support the subtraction of two symbol references 923 if (BE->getOpcode() == MCBinaryExpr::Sub && 924 isa<MCSymbolRefExpr>(BE->getRHS())) 925 return true; 926 927 // See if the addend is is a constant, otherwise there's more going 928 // on here than we can deal with. 929 auto AddendExpr = dyn_cast<MCConstantExpr>(BE->getRHS()); 930 if (!AddendExpr) 931 return false; 932 933 Addend = AddendExpr->getValue(); 934 if (BE->getOpcode() == MCBinaryExpr::Sub) 935 Addend = -Addend; 936 937 // It's some symbol reference + a constant addend 938 return Kind != RISCVMCExpr::VK_RISCV_Invalid; 939 } 940 941 bool RISCVAsmParser::ParseDirective(AsmToken DirectiveID) { return true; } 942 943 extern "C" void LLVMInitializeRISCVAsmParser() { 944 RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target()); 945 RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target()); 946 } 947