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 isSImm6NonZero() const { 264 RISCVMCExpr::VariantKind VK; 265 int64_t Imm; 266 bool IsValid; 267 bool IsConstantImm = evaluateConstantImm(Imm, VK); 268 if (!IsConstantImm) 269 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); 270 else 271 IsValid = ((Imm != 0) && isInt<6>(Imm)); 272 return IsValid && 273 (VK == RISCVMCExpr::VK_RISCV_None || VK == RISCVMCExpr::VK_RISCV_LO); 274 } 275 276 bool isUImm6NonZero() const { 277 int64_t Imm; 278 RISCVMCExpr::VariantKind VK; 279 bool IsConstantImm = evaluateConstantImm(Imm, VK); 280 return IsConstantImm && isUInt<6>(Imm) && (Imm != 0) && 281 VK == RISCVMCExpr::VK_RISCV_None; 282 } 283 284 bool isUImm7Lsb00() const { 285 int64_t Imm; 286 RISCVMCExpr::VariantKind VK; 287 bool IsConstantImm = evaluateConstantImm(Imm, VK); 288 return IsConstantImm && isShiftedUInt<5, 2>(Imm) && 289 VK == RISCVMCExpr::VK_RISCV_None; 290 } 291 292 bool isUImm8Lsb00() const { 293 int64_t Imm; 294 RISCVMCExpr::VariantKind VK; 295 bool IsConstantImm = evaluateConstantImm(Imm, VK); 296 return IsConstantImm && isShiftedUInt<6, 2>(Imm) && 297 VK == RISCVMCExpr::VK_RISCV_None; 298 } 299 300 bool isUImm8Lsb000() const { 301 int64_t Imm; 302 RISCVMCExpr::VariantKind VK; 303 bool IsConstantImm = evaluateConstantImm(Imm, VK); 304 return IsConstantImm && isShiftedUInt<5, 3>(Imm) && 305 VK == RISCVMCExpr::VK_RISCV_None; 306 } 307 308 bool isSImm9Lsb0() const { return isBareSimmNLsb0<9>(); } 309 310 bool isUImm9Lsb000() const { 311 int64_t Imm; 312 RISCVMCExpr::VariantKind VK; 313 bool IsConstantImm = evaluateConstantImm(Imm, VK); 314 return IsConstantImm && isShiftedUInt<6, 3>(Imm) && 315 VK == RISCVMCExpr::VK_RISCV_None; 316 } 317 318 bool isUImm10Lsb00NonZero() const { 319 int64_t Imm; 320 RISCVMCExpr::VariantKind VK; 321 bool IsConstantImm = evaluateConstantImm(Imm, VK); 322 return IsConstantImm && isShiftedUInt<8, 2>(Imm) && (Imm != 0) && 323 VK == RISCVMCExpr::VK_RISCV_None; 324 } 325 326 bool isSImm12() const { 327 RISCVMCExpr::VariantKind VK; 328 int64_t Imm; 329 bool IsValid; 330 if (!isImm()) 331 return false; 332 bool IsConstantImm = evaluateConstantImm(Imm, VK); 333 if (!IsConstantImm) 334 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); 335 else 336 IsValid = isInt<12>(Imm); 337 return IsValid && (VK == RISCVMCExpr::VK_RISCV_None || 338 VK == RISCVMCExpr::VK_RISCV_LO || 339 VK == RISCVMCExpr::VK_RISCV_PCREL_LO); 340 } 341 342 bool isSImm12Lsb0() const { return isBareSimmNLsb0<12>(); } 343 344 bool isUImm12() const { 345 int64_t Imm; 346 RISCVMCExpr::VariantKind VK; 347 if (!isImm()) 348 return false; 349 bool IsConstantImm = evaluateConstantImm(Imm, VK); 350 return IsConstantImm && isUInt<12>(Imm) && VK == RISCVMCExpr::VK_RISCV_None; 351 } 352 353 bool isSImm13Lsb0() const { return isBareSimmNLsb0<13>(); } 354 355 bool isSImm10Lsb0000NonZero() const { 356 int64_t Imm; 357 RISCVMCExpr::VariantKind VK; 358 bool IsConstantImm = evaluateConstantImm(Imm, VK); 359 return IsConstantImm && (Imm != 0) && isShiftedInt<6, 4>(Imm) && 360 VK == RISCVMCExpr::VK_RISCV_None; 361 } 362 363 bool isUImm20() const { 364 RISCVMCExpr::VariantKind VK; 365 int64_t Imm; 366 bool IsValid; 367 if (!isImm()) 368 return false; 369 bool IsConstantImm = evaluateConstantImm(Imm, VK); 370 if (!IsConstantImm) 371 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); 372 else 373 IsValid = isUInt<20>(Imm); 374 return IsValid && (VK == RISCVMCExpr::VK_RISCV_None || 375 VK == RISCVMCExpr::VK_RISCV_HI || 376 VK == RISCVMCExpr::VK_RISCV_PCREL_HI); 377 } 378 379 bool isSImm21Lsb0() const { return isBareSimmNLsb0<21>(); } 380 381 /// getStartLoc - Gets location of the first token of this operand 382 SMLoc getStartLoc() const override { return StartLoc; } 383 /// getEndLoc - Gets location of the last token of this operand 384 SMLoc getEndLoc() const override { return EndLoc; } 385 /// True if this operand is for an RV64 instruction 386 bool isRV64() const { return IsRV64; } 387 388 unsigned getReg() const override { 389 assert(Kind == Register && "Invalid type access!"); 390 return Reg.RegNum; 391 } 392 393 const MCExpr *getImm() const { 394 assert(Kind == Immediate && "Invalid type access!"); 395 return Imm.Val; 396 } 397 398 StringRef getToken() const { 399 assert(Kind == Token && "Invalid type access!"); 400 return Tok; 401 } 402 403 void print(raw_ostream &OS) const override { 404 switch (Kind) { 405 case Immediate: 406 OS << *getImm(); 407 break; 408 case Register: 409 OS << "<register x"; 410 OS << getReg() << ">"; 411 break; 412 case Token: 413 OS << "'" << getToken() << "'"; 414 break; 415 } 416 } 417 418 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S, 419 bool IsRV64) { 420 auto Op = make_unique<RISCVOperand>(Token); 421 Op->Tok = Str; 422 Op->StartLoc = S; 423 Op->EndLoc = S; 424 Op->IsRV64 = IsRV64; 425 return Op; 426 } 427 428 static std::unique_ptr<RISCVOperand> createReg(unsigned RegNo, SMLoc S, 429 SMLoc E, bool IsRV64) { 430 auto Op = make_unique<RISCVOperand>(Register); 431 Op->Reg.RegNum = RegNo; 432 Op->StartLoc = S; 433 Op->EndLoc = E; 434 Op->IsRV64 = IsRV64; 435 return Op; 436 } 437 438 static std::unique_ptr<RISCVOperand> createImm(const MCExpr *Val, SMLoc S, 439 SMLoc E, bool IsRV64) { 440 auto Op = make_unique<RISCVOperand>(Immediate); 441 Op->Imm.Val = Val; 442 Op->StartLoc = S; 443 Op->EndLoc = E; 444 Op->IsRV64 = IsRV64; 445 return Op; 446 } 447 448 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 449 assert(Expr && "Expr shouldn't be null!"); 450 int64_t Imm = 0; 451 bool IsConstant = false; 452 if (auto *RE = dyn_cast<RISCVMCExpr>(Expr)) { 453 IsConstant = RE->evaluateAsConstant(Imm); 454 } else if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) { 455 IsConstant = true; 456 Imm = CE->getValue(); 457 } 458 459 if (IsConstant) 460 Inst.addOperand(MCOperand::createImm(Imm)); 461 else 462 Inst.addOperand(MCOperand::createExpr(Expr)); 463 } 464 465 // Used by the TableGen Code 466 void addRegOperands(MCInst &Inst, unsigned N) const { 467 assert(N == 1 && "Invalid number of operands!"); 468 Inst.addOperand(MCOperand::createReg(getReg())); 469 } 470 471 void addImmOperands(MCInst &Inst, unsigned N) const { 472 assert(N == 1 && "Invalid number of operands!"); 473 addExpr(Inst, getImm()); 474 } 475 476 void addFenceArgOperands(MCInst &Inst, unsigned N) const { 477 assert(N == 1 && "Invalid number of operands!"); 478 // isFenceArg has validated the operand, meaning this cast is safe 479 auto SE = cast<MCSymbolRefExpr>(getImm()); 480 481 unsigned Imm = 0; 482 for (char c : SE->getSymbol().getName()) { 483 switch (c) { 484 default: llvm_unreachable("FenceArg must contain only [iorw]"); 485 case 'i': Imm |= RISCVFenceField::I; break; 486 case 'o': Imm |= RISCVFenceField::O; break; 487 case 'r': Imm |= RISCVFenceField::R; break; 488 case 'w': Imm |= RISCVFenceField::W; break; 489 } 490 } 491 Inst.addOperand(MCOperand::createImm(Imm)); 492 } 493 494 // Returns the rounding mode represented by this RISCVOperand. Should only 495 // be called after checking isFRMArg. 496 RISCVFPRndMode::RoundingMode getRoundingMode() const { 497 // isFRMArg has validated the operand, meaning this cast is safe. 498 auto SE = cast<MCSymbolRefExpr>(getImm()); 499 RISCVFPRndMode::RoundingMode FRM = 500 RISCVFPRndMode::stringToRoundingMode(SE->getSymbol().getName()); 501 assert(FRM != RISCVFPRndMode::Invalid && "Invalid rounding mode"); 502 return FRM; 503 } 504 505 void addFRMArgOperands(MCInst &Inst, unsigned N) const { 506 assert(N == 1 && "Invalid number of operands!"); 507 Inst.addOperand(MCOperand::createImm(getRoundingMode())); 508 } 509 }; 510 } // end anonymous namespace. 511 512 #define GET_REGISTER_MATCHER 513 #define GET_MATCHER_IMPLEMENTATION 514 #include "RISCVGenAsmMatcher.inc" 515 516 // Return the matching FPR64 register for the given FPR32. 517 // FIXME: Ideally this function could be removed in favour of using 518 // information from TableGen. 519 unsigned convertFPR32ToFPR64(unsigned Reg) { 520 switch (Reg) { 521 default: 522 llvm_unreachable("Not a recognised FPR32 register"); 523 case RISCV::F0_32: return RISCV::F0_64; 524 case RISCV::F1_32: return RISCV::F1_64; 525 case RISCV::F2_32: return RISCV::F2_64; 526 case RISCV::F3_32: return RISCV::F3_64; 527 case RISCV::F4_32: return RISCV::F4_64; 528 case RISCV::F5_32: return RISCV::F5_64; 529 case RISCV::F6_32: return RISCV::F6_64; 530 case RISCV::F7_32: return RISCV::F7_64; 531 case RISCV::F8_32: return RISCV::F8_64; 532 case RISCV::F9_32: return RISCV::F9_64; 533 case RISCV::F10_32: return RISCV::F10_64; 534 case RISCV::F11_32: return RISCV::F11_64; 535 case RISCV::F12_32: return RISCV::F12_64; 536 case RISCV::F13_32: return RISCV::F13_64; 537 case RISCV::F14_32: return RISCV::F14_64; 538 case RISCV::F15_32: return RISCV::F15_64; 539 case RISCV::F16_32: return RISCV::F16_64; 540 case RISCV::F17_32: return RISCV::F17_64; 541 case RISCV::F18_32: return RISCV::F18_64; 542 case RISCV::F19_32: return RISCV::F19_64; 543 case RISCV::F20_32: return RISCV::F20_64; 544 case RISCV::F21_32: return RISCV::F21_64; 545 case RISCV::F22_32: return RISCV::F22_64; 546 case RISCV::F23_32: return RISCV::F23_64; 547 case RISCV::F24_32: return RISCV::F24_64; 548 case RISCV::F25_32: return RISCV::F25_64; 549 case RISCV::F26_32: return RISCV::F26_64; 550 case RISCV::F27_32: return RISCV::F27_64; 551 case RISCV::F28_32: return RISCV::F28_64; 552 case RISCV::F29_32: return RISCV::F29_64; 553 case RISCV::F30_32: return RISCV::F30_64; 554 case RISCV::F31_32: return RISCV::F31_64; 555 } 556 } 557 558 unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp, 559 unsigned Kind) { 560 RISCVOperand &Op = static_cast<RISCVOperand &>(AsmOp); 561 if (!Op.isReg()) 562 return Match_InvalidOperand; 563 564 unsigned Reg = Op.getReg(); 565 bool IsRegFPR32 = 566 RISCVMCRegisterClasses[RISCV::FPR32RegClassID].contains(Reg); 567 bool IsRegFPR32C = 568 RISCVMCRegisterClasses[RISCV::FPR32CRegClassID].contains(Reg); 569 570 // As the parser couldn't differentiate an FPR32 from an FPR64, coerce the 571 // register from FPR32 to FPR64 or FPR32C to FPR64C if necessary. 572 if ((IsRegFPR32 && Kind == MCK_FPR64) || 573 (IsRegFPR32C && Kind == MCK_FPR64C)) { 574 Op.Reg.RegNum = convertFPR32ToFPR64(Reg); 575 return Match_Success; 576 } 577 return Match_InvalidOperand; 578 } 579 580 bool RISCVAsmParser::generateImmOutOfRangeError( 581 OperandVector &Operands, uint64_t ErrorInfo, int Lower, int Upper, 582 Twine Msg = "immediate must be an integer in the range") { 583 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 584 return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]"); 585 } 586 587 bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 588 OperandVector &Operands, 589 MCStreamer &Out, 590 uint64_t &ErrorInfo, 591 bool MatchingInlineAsm) { 592 MCInst Inst; 593 594 switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) { 595 default: 596 break; 597 case Match_Success: 598 Inst.setLoc(IDLoc); 599 Out.EmitInstruction(Inst, getSTI()); 600 return false; 601 case Match_MissingFeature: 602 return Error(IDLoc, "instruction use requires an option to be enabled"); 603 case Match_MnemonicFail: 604 return Error(IDLoc, "unrecognized instruction mnemonic"); 605 case Match_InvalidOperand: { 606 SMLoc ErrorLoc = IDLoc; 607 if (ErrorInfo != ~0U) { 608 if (ErrorInfo >= Operands.size()) 609 return Error(ErrorLoc, "too few operands for instruction"); 610 611 ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 612 if (ErrorLoc == SMLoc()) 613 ErrorLoc = IDLoc; 614 } 615 return Error(ErrorLoc, "invalid operand for instruction"); 616 } 617 case Match_InvalidUImmLog2XLen: 618 if (isRV64()) 619 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1); 620 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 621 case Match_InvalidUImmLog2XLenNonZero: 622 if (isRV64()) 623 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1); 624 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1); 625 case Match_InvalidUImm5: 626 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 627 case Match_InvalidSImm6: 628 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5), 629 (1 << 5) - 1); 630 case Match_InvalidSImm6NonZero: 631 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5), 632 (1 << 5) - 1, 633 "immediate must be non-zero in the range"); 634 case Match_InvalidUImm6NonZero: 635 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1); 636 case Match_InvalidUImm7Lsb00: 637 return generateImmOutOfRangeError( 638 Operands, ErrorInfo, 0, (1 << 7) - 4, 639 "immediate must be a multiple of 4 bytes in the range"); 640 case Match_InvalidUImm8Lsb00: 641 return generateImmOutOfRangeError( 642 Operands, ErrorInfo, 0, (1 << 8) - 4, 643 "immediate must be a multiple of 4 bytes in the range"); 644 case Match_InvalidUImm8Lsb000: 645 return generateImmOutOfRangeError( 646 Operands, ErrorInfo, 0, (1 << 8) - 8, 647 "immediate must be a multiple of 8 bytes in the range"); 648 case Match_InvalidSImm9Lsb0: 649 return generateImmOutOfRangeError( 650 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2, 651 "immediate must be a multiple of 2 bytes in the range"); 652 case Match_InvalidUImm9Lsb000: 653 return generateImmOutOfRangeError( 654 Operands, ErrorInfo, 0, (1 << 9) - 8, 655 "immediate must be a multiple of 8 bytes in the range"); 656 case Match_InvalidUImm10Lsb00NonZero: 657 return generateImmOutOfRangeError( 658 Operands, ErrorInfo, 4, (1 << 10) - 4, 659 "immediate must be a multiple of 4 bytes in the range"); 660 case Match_InvalidSImm10Lsb0000NonZero: 661 return generateImmOutOfRangeError( 662 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16, 663 "immediate must be a multiple of 16 bytes and non-zero in the range"); 664 case Match_InvalidSImm12: 665 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 11), 666 (1 << 11) - 1); 667 case Match_InvalidSImm12Lsb0: 668 return generateImmOutOfRangeError( 669 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2, 670 "immediate must be a multiple of 2 bytes in the range"); 671 case Match_InvalidUImm12: 672 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1); 673 case Match_InvalidSImm13Lsb0: 674 return generateImmOutOfRangeError( 675 Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2, 676 "immediate must be a multiple of 2 bytes in the range"); 677 case Match_InvalidUImm20: 678 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1); 679 case Match_InvalidSImm21Lsb0: 680 return generateImmOutOfRangeError( 681 Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2, 682 "immediate must be a multiple of 2 bytes in the range"); 683 case Match_InvalidFenceArg: { 684 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 685 return Error( 686 ErrorLoc, 687 "operand must be formed of letters selected in-order from 'iorw'"); 688 } 689 case Match_InvalidFRMArg: { 690 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 691 return Error( 692 ErrorLoc, 693 "operand must be a valid floating point rounding mode mnemonic"); 694 } 695 } 696 697 llvm_unreachable("Unknown match type detected!"); 698 } 699 700 bool RISCVAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 701 SMLoc &EndLoc) { 702 const AsmToken &Tok = getParser().getTok(); 703 StartLoc = Tok.getLoc(); 704 EndLoc = Tok.getEndLoc(); 705 RegNo = 0; 706 StringRef Name = getLexer().getTok().getIdentifier(); 707 708 if (!MatchRegisterName(Name) || !MatchRegisterAltName(Name)) { 709 getParser().Lex(); // Eat identifier token. 710 return false; 711 } 712 713 return Error(StartLoc, "invalid register name"); 714 } 715 716 OperandMatchResultTy RISCVAsmParser::parseRegister(OperandVector &Operands, 717 bool AllowParens) { 718 SMLoc FirstS = getLoc(); 719 bool HadParens = false; 720 AsmToken Buf[2]; 721 722 // If this a parenthesised register name is allowed, parse it atomically 723 if (AllowParens && getLexer().is(AsmToken::LParen)) { 724 size_t ReadCount = getLexer().peekTokens(Buf); 725 if (ReadCount == 2 && Buf[1].getKind() == AsmToken::RParen) { 726 HadParens = true; 727 getParser().Lex(); // Eat '(' 728 } 729 } 730 731 switch (getLexer().getKind()) { 732 default: 733 return MatchOperand_NoMatch; 734 case AsmToken::Identifier: 735 StringRef Name = getLexer().getTok().getIdentifier(); 736 unsigned RegNo = MatchRegisterName(Name); 737 if (RegNo == 0) { 738 RegNo = MatchRegisterAltName(Name); 739 if (RegNo == 0) { 740 if (HadParens) 741 getLexer().UnLex(Buf[0]); 742 return MatchOperand_NoMatch; 743 } 744 } 745 if (HadParens) 746 Operands.push_back(RISCVOperand::createToken("(", FirstS, isRV64())); 747 SMLoc S = getLoc(); 748 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 749 getLexer().Lex(); 750 Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64())); 751 } 752 753 if (HadParens) { 754 getParser().Lex(); // Eat ')' 755 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64())); 756 } 757 758 return MatchOperand_Success; 759 } 760 761 OperandMatchResultTy RISCVAsmParser::parseImmediate(OperandVector &Operands) { 762 SMLoc S = getLoc(); 763 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 764 const MCExpr *Res; 765 766 switch (getLexer().getKind()) { 767 default: 768 return MatchOperand_NoMatch; 769 case AsmToken::LParen: 770 case AsmToken::Minus: 771 case AsmToken::Plus: 772 case AsmToken::Integer: 773 case AsmToken::String: 774 if (getParser().parseExpression(Res)) 775 return MatchOperand_ParseFail; 776 break; 777 case AsmToken::Identifier: { 778 StringRef Identifier; 779 if (getParser().parseIdentifier(Identifier)) 780 return MatchOperand_ParseFail; 781 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); 782 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 783 break; 784 } 785 case AsmToken::Percent: 786 return parseOperandWithModifier(Operands); 787 } 788 789 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 790 return MatchOperand_Success; 791 } 792 793 OperandMatchResultTy 794 RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) { 795 SMLoc S = getLoc(); 796 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 797 798 if (getLexer().getKind() != AsmToken::Percent) { 799 Error(getLoc(), "expected '%' for operand modifier"); 800 return MatchOperand_ParseFail; 801 } 802 803 getParser().Lex(); // Eat '%' 804 805 if (getLexer().getKind() != AsmToken::Identifier) { 806 Error(getLoc(), "expected valid identifier for operand modifier"); 807 return MatchOperand_ParseFail; 808 } 809 StringRef Identifier = getParser().getTok().getIdentifier(); 810 RISCVMCExpr::VariantKind VK = RISCVMCExpr::getVariantKindForName(Identifier); 811 if (VK == RISCVMCExpr::VK_RISCV_Invalid) { 812 Error(getLoc(), "unrecognized operand modifier"); 813 return MatchOperand_ParseFail; 814 } 815 816 getParser().Lex(); // Eat the identifier 817 if (getLexer().getKind() != AsmToken::LParen) { 818 Error(getLoc(), "expected '('"); 819 return MatchOperand_ParseFail; 820 } 821 getParser().Lex(); // Eat '(' 822 823 const MCExpr *SubExpr; 824 if (getParser().parseParenExpression(SubExpr, E)) { 825 return MatchOperand_ParseFail; 826 } 827 828 const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, VK, getContext()); 829 Operands.push_back(RISCVOperand::createImm(ModExpr, S, E, isRV64())); 830 return MatchOperand_Success; 831 } 832 833 OperandMatchResultTy 834 RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) { 835 if (getLexer().isNot(AsmToken::LParen)) { 836 Error(getLoc(), "expected '('"); 837 return MatchOperand_ParseFail; 838 } 839 840 getParser().Lex(); // Eat '(' 841 Operands.push_back(RISCVOperand::createToken("(", getLoc(), isRV64())); 842 843 if (parseRegister(Operands) != MatchOperand_Success) { 844 Error(getLoc(), "expected register"); 845 return MatchOperand_ParseFail; 846 } 847 848 if (getLexer().isNot(AsmToken::RParen)) { 849 Error(getLoc(), "expected ')'"); 850 return MatchOperand_ParseFail; 851 } 852 853 getParser().Lex(); // Eat ')' 854 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64())); 855 856 return MatchOperand_Success; 857 } 858 859 /// Looks at a token type and creates the relevant operand 860 /// from this information, adding to Operands. 861 /// If operand was parsed, returns false, else true. 862 bool RISCVAsmParser::parseOperand(OperandVector &Operands) { 863 // Attempt to parse token as register 864 if (parseRegister(Operands, true) == MatchOperand_Success) 865 return false; 866 867 // Attempt to parse token as an immediate 868 if (parseImmediate(Operands) == MatchOperand_Success) { 869 // Parse memory base register if present 870 if (getLexer().is(AsmToken::LParen)) 871 return parseMemOpBaseReg(Operands) != MatchOperand_Success; 872 return false; 873 } 874 875 // Finally we have exhausted all options and must declare defeat. 876 Error(getLoc(), "unknown operand"); 877 return true; 878 } 879 880 bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info, 881 StringRef Name, SMLoc NameLoc, 882 OperandVector &Operands) { 883 // First operand is token for instruction 884 Operands.push_back(RISCVOperand::createToken(Name, NameLoc, isRV64())); 885 886 // If there are no more operands, then finish 887 if (getLexer().is(AsmToken::EndOfStatement)) 888 return false; 889 890 // Parse first operand 891 if (parseOperand(Operands)) 892 return true; 893 894 // Parse until end of statement, consuming commas between operands 895 while (getLexer().is(AsmToken::Comma)) { 896 // Consume comma token 897 getLexer().Lex(); 898 899 // Parse next operand 900 if (parseOperand(Operands)) 901 return true; 902 } 903 904 if (getLexer().isNot(AsmToken::EndOfStatement)) { 905 SMLoc Loc = getLexer().getLoc(); 906 getParser().eatToEndOfStatement(); 907 return Error(Loc, "unexpected token"); 908 } 909 910 getParser().Lex(); // Consume the EndOfStatement. 911 return false; 912 } 913 914 bool RISCVAsmParser::classifySymbolRef(const MCExpr *Expr, 915 RISCVMCExpr::VariantKind &Kind, 916 int64_t &Addend) { 917 Kind = RISCVMCExpr::VK_RISCV_None; 918 Addend = 0; 919 920 if (const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) { 921 Kind = RE->getKind(); 922 Expr = RE->getSubExpr(); 923 } 924 925 // It's a simple symbol reference or constant with no addend. 926 if (isa<MCConstantExpr>(Expr) || isa<MCSymbolRefExpr>(Expr)) 927 return true; 928 929 const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr); 930 if (!BE) 931 return false; 932 933 if (!isa<MCSymbolRefExpr>(BE->getLHS())) 934 return false; 935 936 if (BE->getOpcode() != MCBinaryExpr::Add && 937 BE->getOpcode() != MCBinaryExpr::Sub) 938 return false; 939 940 // We are able to support the subtraction of two symbol references 941 if (BE->getOpcode() == MCBinaryExpr::Sub && 942 isa<MCSymbolRefExpr>(BE->getRHS())) 943 return true; 944 945 // See if the addend is is a constant, otherwise there's more going 946 // on here than we can deal with. 947 auto AddendExpr = dyn_cast<MCConstantExpr>(BE->getRHS()); 948 if (!AddendExpr) 949 return false; 950 951 Addend = AddendExpr->getValue(); 952 if (BE->getOpcode() == MCBinaryExpr::Sub) 953 Addend = -Addend; 954 955 // It's some symbol reference + a constant addend 956 return Kind != RISCVMCExpr::VK_RISCV_Invalid; 957 } 958 959 bool RISCVAsmParser::ParseDirective(AsmToken DirectiveID) { return true; } 960 961 extern "C" void LLVMInitializeRISCVAsmParser() { 962 RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target()); 963 RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target()); 964 } 965