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