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 "TargetInfo/RISCVTargetInfo.h" 14 #include "Utils/RISCVBaseInfo.h" 15 #include "Utils/RISCVMatInt.h" 16 #include "llvm/ADT/STLExtras.h" 17 #include "llvm/ADT/SmallVector.h" 18 #include "llvm/ADT/Statistic.h" 19 #include "llvm/ADT/StringSwitch.h" 20 #include "llvm/CodeGen/Register.h" 21 #include "llvm/MC/MCAssembler.h" 22 #include "llvm/MC/MCContext.h" 23 #include "llvm/MC/MCExpr.h" 24 #include "llvm/MC/MCInst.h" 25 #include "llvm/MC/MCInstBuilder.h" 26 #include "llvm/MC/MCObjectFileInfo.h" 27 #include "llvm/MC/MCParser/MCAsmLexer.h" 28 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 29 #include "llvm/MC/MCParser/MCTargetAsmParser.h" 30 #include "llvm/MC/MCRegisterInfo.h" 31 #include "llvm/MC/MCStreamer.h" 32 #include "llvm/MC/MCSubtargetInfo.h" 33 #include "llvm/Support/Casting.h" 34 #include "llvm/Support/MathExtras.h" 35 #include "llvm/Support/RISCVAttributes.h" 36 #include "llvm/Support/TargetRegistry.h" 37 38 #include <limits> 39 40 using namespace llvm; 41 42 #define DEBUG_TYPE "riscv-asm-parser" 43 44 // Include the auto-generated portion of the compress emitter. 45 #define GEN_COMPRESS_INSTR 46 #include "RISCVGenCompressInstEmitter.inc" 47 48 STATISTIC(RISCVNumInstrsCompressed, 49 "Number of RISC-V Compressed instructions emitted"); 50 51 namespace { 52 struct RISCVOperand; 53 54 struct ParserOptionsSet { 55 bool IsPicEnabled; 56 }; 57 58 class RISCVAsmParser : public MCTargetAsmParser { 59 SmallVector<FeatureBitset, 4> FeatureBitStack; 60 61 SmallVector<ParserOptionsSet, 4> ParserOptionsStack; 62 ParserOptionsSet ParserOptions; 63 64 SMLoc getLoc() const { return getParser().getTok().getLoc(); } 65 bool isRV64() const { return getSTI().hasFeature(RISCV::Feature64Bit); } 66 bool isRV32E() const { return getSTI().hasFeature(RISCV::FeatureRV32E); } 67 68 RISCVTargetStreamer &getTargetStreamer() { 69 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer(); 70 return static_cast<RISCVTargetStreamer &>(TS); 71 } 72 73 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, 74 unsigned Kind) override; 75 76 bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo, 77 int64_t Lower, int64_t Upper, Twine Msg); 78 79 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 80 OperandVector &Operands, MCStreamer &Out, 81 uint64_t &ErrorInfo, 82 bool MatchingInlineAsm) override; 83 84 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; 85 OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc, 86 SMLoc &EndLoc) override; 87 88 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 89 SMLoc NameLoc, OperandVector &Operands) override; 90 91 bool ParseDirective(AsmToken DirectiveID) override; 92 93 // Helper to actually emit an instruction to the MCStreamer. Also, when 94 // possible, compression of the instruction is performed. 95 void emitToStreamer(MCStreamer &S, const MCInst &Inst); 96 97 // Helper to emit a combination of LUI, ADDI(W), and SLLI instructions that 98 // synthesize the desired immedate value into the destination register. 99 void emitLoadImm(Register DestReg, int64_t Value, MCStreamer &Out); 100 101 // Helper to emit a combination of AUIPC and SecondOpcode. Used to implement 102 // helpers such as emitLoadLocalAddress and emitLoadAddress. 103 void emitAuipcInstPair(MCOperand DestReg, MCOperand TmpReg, 104 const MCExpr *Symbol, RISCVMCExpr::VariantKind VKHi, 105 unsigned SecondOpcode, SMLoc IDLoc, MCStreamer &Out); 106 107 // Helper to emit pseudo instruction "lla" used in PC-rel addressing. 108 void emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 109 110 // Helper to emit pseudo instruction "la" used in GOT/PC-rel addressing. 111 void emitLoadAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 112 113 // Helper to emit pseudo instruction "la.tls.ie" used in initial-exec TLS 114 // addressing. 115 void emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 116 117 // Helper to emit pseudo instruction "la.tls.gd" used in global-dynamic TLS 118 // addressing. 119 void emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 120 121 // Helper to emit pseudo load/store instruction with a symbol. 122 void emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode, SMLoc IDLoc, 123 MCStreamer &Out, bool HasTmpReg); 124 125 // Checks that a PseudoAddTPRel is using x4/tp in its second input operand. 126 // Enforcing this using a restricted register class for the second input 127 // operand of PseudoAddTPRel results in a poor diagnostic due to the fact 128 // 'add' is an overloaded mnemonic. 129 bool checkPseudoAddTPRel(MCInst &Inst, OperandVector &Operands); 130 131 /// Helper for processing MC instructions that have been successfully matched 132 /// by MatchAndEmitInstruction. Modifications to the emitted instructions, 133 /// like the expansion of pseudo instructions (e.g., "li"), can be performed 134 /// in this method. 135 bool processInstruction(MCInst &Inst, SMLoc IDLoc, OperandVector &Operands, 136 MCStreamer &Out); 137 138 // Auto-generated instruction matching functions 139 #define GET_ASSEMBLER_HEADER 140 #include "RISCVGenAsmMatcher.inc" 141 142 OperandMatchResultTy parseCSRSystemRegister(OperandVector &Operands); 143 OperandMatchResultTy parseImmediate(OperandVector &Operands); 144 OperandMatchResultTy parseRegister(OperandVector &Operands, 145 bool AllowParens = false); 146 OperandMatchResultTy parseMemOpBaseReg(OperandVector &Operands); 147 OperandMatchResultTy parseAtomicMemOp(OperandVector &Operands); 148 OperandMatchResultTy parseOperandWithModifier(OperandVector &Operands); 149 OperandMatchResultTy parseBareSymbol(OperandVector &Operands); 150 OperandMatchResultTy parseCallSymbol(OperandVector &Operands); 151 OperandMatchResultTy parsePseudoJumpSymbol(OperandVector &Operands); 152 OperandMatchResultTy parseJALOffset(OperandVector &Operands); 153 154 bool parseOperand(OperandVector &Operands, StringRef Mnemonic); 155 156 bool parseDirectiveOption(); 157 bool parseDirectiveAttribute(); 158 159 void setFeatureBits(uint64_t Feature, StringRef FeatureString) { 160 if (!(getSTI().getFeatureBits()[Feature])) { 161 MCSubtargetInfo &STI = copySTI(); 162 setAvailableFeatures( 163 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); 164 } 165 } 166 167 bool getFeatureBits(uint64_t Feature) { 168 return getSTI().getFeatureBits()[Feature]; 169 } 170 171 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) { 172 if (getSTI().getFeatureBits()[Feature]) { 173 MCSubtargetInfo &STI = copySTI(); 174 setAvailableFeatures( 175 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); 176 } 177 } 178 179 void pushFeatureBits() { 180 assert(FeatureBitStack.size() == ParserOptionsStack.size() && 181 "These two stacks must be kept synchronized"); 182 FeatureBitStack.push_back(getSTI().getFeatureBits()); 183 ParserOptionsStack.push_back(ParserOptions); 184 } 185 186 bool popFeatureBits() { 187 assert(FeatureBitStack.size() == ParserOptionsStack.size() && 188 "These two stacks must be kept synchronized"); 189 if (FeatureBitStack.empty()) 190 return true; 191 192 FeatureBitset FeatureBits = FeatureBitStack.pop_back_val(); 193 copySTI().setFeatureBits(FeatureBits); 194 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits)); 195 196 ParserOptions = ParserOptionsStack.pop_back_val(); 197 198 return false; 199 } 200 201 public: 202 enum RISCVMatchResultTy { 203 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY, 204 #define GET_OPERAND_DIAGNOSTIC_TYPES 205 #include "RISCVGenAsmMatcher.inc" 206 #undef GET_OPERAND_DIAGNOSTIC_TYPES 207 }; 208 209 static bool classifySymbolRef(const MCExpr *Expr, 210 RISCVMCExpr::VariantKind &Kind, 211 int64_t &Addend); 212 213 RISCVAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, 214 const MCInstrInfo &MII, const MCTargetOptions &Options) 215 : MCTargetAsmParser(Options, STI, MII) { 216 Parser.addAliasForDirective(".half", ".2byte"); 217 Parser.addAliasForDirective(".hword", ".2byte"); 218 Parser.addAliasForDirective(".word", ".4byte"); 219 Parser.addAliasForDirective(".dword", ".8byte"); 220 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 221 222 auto ABIName = StringRef(Options.ABIName); 223 if (ABIName.endswith("f") && 224 !getSTI().getFeatureBits()[RISCV::FeatureStdExtF]) { 225 errs() << "Hard-float 'f' ABI can't be used for a target that " 226 "doesn't support the F instruction set extension (ignoring " 227 "target-abi)\n"; 228 } else if (ABIName.endswith("d") && 229 !getSTI().getFeatureBits()[RISCV::FeatureStdExtD]) { 230 errs() << "Hard-float 'd' ABI can't be used for a target that " 231 "doesn't support the D instruction set extension (ignoring " 232 "target-abi)\n"; 233 } 234 235 const MCObjectFileInfo *MOFI = Parser.getContext().getObjectFileInfo(); 236 ParserOptions.IsPicEnabled = MOFI->isPositionIndependent(); 237 } 238 }; 239 240 /// RISCVOperand - Instances of this class represent a parsed machine 241 /// instruction 242 struct RISCVOperand : public MCParsedAsmOperand { 243 244 enum class KindTy { 245 Token, 246 Register, 247 Immediate, 248 SystemRegister 249 } Kind; 250 251 bool IsRV64; 252 253 struct RegOp { 254 Register RegNum; 255 }; 256 257 struct ImmOp { 258 const MCExpr *Val; 259 }; 260 261 struct SysRegOp { 262 const char *Data; 263 unsigned Length; 264 unsigned Encoding; 265 // FIXME: Add the Encoding parsed fields as needed for checks, 266 // e.g.: read/write or user/supervisor/machine privileges. 267 }; 268 269 SMLoc StartLoc, EndLoc; 270 union { 271 StringRef Tok; 272 RegOp Reg; 273 ImmOp Imm; 274 struct SysRegOp SysReg; 275 }; 276 277 RISCVOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 278 279 public: 280 RISCVOperand(const RISCVOperand &o) : MCParsedAsmOperand() { 281 Kind = o.Kind; 282 IsRV64 = o.IsRV64; 283 StartLoc = o.StartLoc; 284 EndLoc = o.EndLoc; 285 switch (Kind) { 286 case KindTy::Register: 287 Reg = o.Reg; 288 break; 289 case KindTy::Immediate: 290 Imm = o.Imm; 291 break; 292 case KindTy::Token: 293 Tok = o.Tok; 294 break; 295 case KindTy::SystemRegister: 296 SysReg = o.SysReg; 297 break; 298 } 299 } 300 301 bool isToken() const override { return Kind == KindTy::Token; } 302 bool isReg() const override { return Kind == KindTy::Register; } 303 bool isImm() const override { return Kind == KindTy::Immediate; } 304 bool isMem() const override { return false; } 305 bool isSystemRegister() const { return Kind == KindTy::SystemRegister; } 306 307 bool isGPR() const { 308 return Kind == KindTy::Register && 309 RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(Reg.RegNum); 310 } 311 312 static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm, 313 RISCVMCExpr::VariantKind &VK) { 314 if (auto *RE = dyn_cast<RISCVMCExpr>(Expr)) { 315 VK = RE->getKind(); 316 return RE->evaluateAsConstant(Imm); 317 } 318 319 if (auto CE = dyn_cast<MCConstantExpr>(Expr)) { 320 VK = RISCVMCExpr::VK_RISCV_None; 321 Imm = CE->getValue(); 322 return true; 323 } 324 325 return false; 326 } 327 328 // True if operand is a symbol with no modifiers, or a constant with no 329 // modifiers and isShiftedInt<N-1, 1>(Op). 330 template <int N> bool isBareSimmNLsb0() const { 331 int64_t Imm; 332 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 333 if (!isImm()) 334 return false; 335 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 336 bool IsValid; 337 if (!IsConstantImm) 338 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); 339 else 340 IsValid = isShiftedInt<N - 1, 1>(Imm); 341 return IsValid && VK == RISCVMCExpr::VK_RISCV_None; 342 } 343 344 // Predicate methods for AsmOperands defined in RISCVInstrInfo.td 345 346 bool isBareSymbol() const { 347 int64_t Imm; 348 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 349 // Must be of 'immediate' type but not a constant. 350 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK)) 351 return false; 352 return RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm) && 353 VK == RISCVMCExpr::VK_RISCV_None; 354 } 355 356 bool isCallSymbol() const { 357 int64_t Imm; 358 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 359 // Must be of 'immediate' type but not a constant. 360 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK)) 361 return false; 362 return RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm) && 363 (VK == RISCVMCExpr::VK_RISCV_CALL || 364 VK == RISCVMCExpr::VK_RISCV_CALL_PLT); 365 } 366 367 bool isPseudoJumpSymbol() const { 368 int64_t Imm; 369 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 370 // Must be of 'immediate' type but not a constant. 371 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK)) 372 return false; 373 return RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm) && 374 VK == RISCVMCExpr::VK_RISCV_CALL; 375 } 376 377 bool isTPRelAddSymbol() const { 378 int64_t Imm; 379 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 380 // Must be of 'immediate' type but not a constant. 381 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK)) 382 return false; 383 return RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm) && 384 VK == RISCVMCExpr::VK_RISCV_TPREL_ADD; 385 } 386 387 bool isCSRSystemRegister() const { return isSystemRegister(); } 388 389 /// Return true if the operand is a valid for the fence instruction e.g. 390 /// ('iorw'). 391 bool isFenceArg() const { 392 if (!isImm()) 393 return false; 394 const MCExpr *Val = getImm(); 395 auto *SVal = dyn_cast<MCSymbolRefExpr>(Val); 396 if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None) 397 return false; 398 399 StringRef Str = SVal->getSymbol().getName(); 400 // Letters must be unique, taken from 'iorw', and in ascending order. This 401 // holds as long as each individual character is one of 'iorw' and is 402 // greater than the previous character. 403 char Prev = '\0'; 404 for (char c : Str) { 405 if (c != 'i' && c != 'o' && c != 'r' && c != 'w') 406 return false; 407 if (c <= Prev) 408 return false; 409 Prev = c; 410 } 411 return true; 412 } 413 414 /// Return true if the operand is a valid floating point rounding mode. 415 bool isFRMArg() const { 416 if (!isImm()) 417 return false; 418 const MCExpr *Val = getImm(); 419 auto *SVal = dyn_cast<MCSymbolRefExpr>(Val); 420 if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None) 421 return false; 422 423 StringRef Str = SVal->getSymbol().getName(); 424 425 return RISCVFPRndMode::stringToRoundingMode(Str) != RISCVFPRndMode::Invalid; 426 } 427 428 bool isImmXLenLI() const { 429 int64_t Imm; 430 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 431 if (!isImm()) 432 return false; 433 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 434 if (VK == RISCVMCExpr::VK_RISCV_LO || VK == RISCVMCExpr::VK_RISCV_PCREL_LO) 435 return true; 436 // Given only Imm, ensuring that the actually specified constant is either 437 // a signed or unsigned 64-bit number is unfortunately impossible. 438 return IsConstantImm && VK == RISCVMCExpr::VK_RISCV_None && 439 (isRV64() || (isInt<32>(Imm) || isUInt<32>(Imm))); 440 } 441 442 bool isUImmLog2XLen() const { 443 int64_t Imm; 444 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 445 if (!isImm()) 446 return false; 447 if (!evaluateConstantImm(getImm(), Imm, VK) || 448 VK != RISCVMCExpr::VK_RISCV_None) 449 return false; 450 return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm); 451 } 452 453 bool isUImmLog2XLenNonZero() const { 454 int64_t Imm; 455 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 456 if (!isImm()) 457 return false; 458 if (!evaluateConstantImm(getImm(), Imm, VK) || 459 VK != RISCVMCExpr::VK_RISCV_None) 460 return false; 461 if (Imm == 0) 462 return false; 463 return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm); 464 } 465 466 bool isUImmLog2XLenHalf() const { 467 int64_t Imm; 468 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 469 if (!isImm()) 470 return false; 471 if (!evaluateConstantImm(getImm(), Imm, VK) || 472 VK != RISCVMCExpr::VK_RISCV_None) 473 return false; 474 return (isRV64() && isUInt<5>(Imm)) || isUInt<4>(Imm); 475 } 476 477 bool isUImm5() const { 478 int64_t Imm; 479 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 480 if (!isImm()) 481 return false; 482 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 483 return IsConstantImm && isUInt<5>(Imm) && VK == RISCVMCExpr::VK_RISCV_None; 484 } 485 486 bool isUImm5NonZero() const { 487 int64_t Imm; 488 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 489 if (!isImm()) 490 return false; 491 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 492 return IsConstantImm && isUInt<5>(Imm) && (Imm != 0) && 493 VK == RISCVMCExpr::VK_RISCV_None; 494 } 495 496 bool isSImm6() const { 497 if (!isImm()) 498 return false; 499 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 500 int64_t Imm; 501 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 502 return IsConstantImm && isInt<6>(Imm) && 503 VK == RISCVMCExpr::VK_RISCV_None; 504 } 505 506 bool isSImm6NonZero() const { 507 if (!isImm()) 508 return false; 509 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 510 int64_t Imm; 511 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 512 return IsConstantImm && isInt<6>(Imm) && (Imm != 0) && 513 VK == RISCVMCExpr::VK_RISCV_None; 514 } 515 516 bool isCLUIImm() const { 517 if (!isImm()) 518 return false; 519 int64_t Imm; 520 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 521 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 522 return IsConstantImm && (Imm != 0) && 523 (isUInt<5>(Imm) || (Imm >= 0xfffe0 && Imm <= 0xfffff)) && 524 VK == RISCVMCExpr::VK_RISCV_None; 525 } 526 527 bool isUImm7Lsb00() const { 528 if (!isImm()) 529 return false; 530 int64_t Imm; 531 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 532 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 533 return IsConstantImm && isShiftedUInt<5, 2>(Imm) && 534 VK == RISCVMCExpr::VK_RISCV_None; 535 } 536 537 bool isUImm8Lsb00() const { 538 if (!isImm()) 539 return false; 540 int64_t Imm; 541 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 542 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 543 return IsConstantImm && isShiftedUInt<6, 2>(Imm) && 544 VK == RISCVMCExpr::VK_RISCV_None; 545 } 546 547 bool isUImm8Lsb000() const { 548 if (!isImm()) 549 return false; 550 int64_t Imm; 551 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 552 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 553 return IsConstantImm && isShiftedUInt<5, 3>(Imm) && 554 VK == RISCVMCExpr::VK_RISCV_None; 555 } 556 557 bool isSImm9Lsb0() const { return isBareSimmNLsb0<9>(); } 558 559 bool isUImm9Lsb000() const { 560 if (!isImm()) 561 return false; 562 int64_t Imm; 563 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 564 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 565 return IsConstantImm && isShiftedUInt<6, 3>(Imm) && 566 VK == RISCVMCExpr::VK_RISCV_None; 567 } 568 569 bool isUImm10Lsb00NonZero() const { 570 if (!isImm()) 571 return false; 572 int64_t Imm; 573 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 574 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 575 return IsConstantImm && isShiftedUInt<8, 2>(Imm) && (Imm != 0) && 576 VK == RISCVMCExpr::VK_RISCV_None; 577 } 578 579 bool isSImm12() const { 580 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 581 int64_t Imm; 582 bool IsValid; 583 if (!isImm()) 584 return false; 585 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 586 if (!IsConstantImm) 587 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); 588 else 589 IsValid = isInt<12>(Imm); 590 return IsValid && ((IsConstantImm && VK == RISCVMCExpr::VK_RISCV_None) || 591 VK == RISCVMCExpr::VK_RISCV_LO || 592 VK == RISCVMCExpr::VK_RISCV_PCREL_LO || 593 VK == RISCVMCExpr::VK_RISCV_TPREL_LO); 594 } 595 596 bool isSImm12Lsb0() const { return isBareSimmNLsb0<12>(); } 597 598 bool isSImm13Lsb0() const { return isBareSimmNLsb0<13>(); } 599 600 bool isSImm10Lsb0000NonZero() const { 601 if (!isImm()) 602 return false; 603 int64_t Imm; 604 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 605 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 606 return IsConstantImm && (Imm != 0) && isShiftedInt<6, 4>(Imm) && 607 VK == RISCVMCExpr::VK_RISCV_None; 608 } 609 610 bool isUImm20LUI() const { 611 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 612 int64_t Imm; 613 bool IsValid; 614 if (!isImm()) 615 return false; 616 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 617 if (!IsConstantImm) { 618 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); 619 return IsValid && (VK == RISCVMCExpr::VK_RISCV_HI || 620 VK == RISCVMCExpr::VK_RISCV_TPREL_HI); 621 } else { 622 return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None || 623 VK == RISCVMCExpr::VK_RISCV_HI || 624 VK == RISCVMCExpr::VK_RISCV_TPREL_HI); 625 } 626 } 627 628 bool isUImm20AUIPC() const { 629 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 630 int64_t Imm; 631 bool IsValid; 632 if (!isImm()) 633 return false; 634 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 635 if (!IsConstantImm) { 636 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); 637 return IsValid && (VK == RISCVMCExpr::VK_RISCV_PCREL_HI || 638 VK == RISCVMCExpr::VK_RISCV_GOT_HI || 639 VK == RISCVMCExpr::VK_RISCV_TLS_GOT_HI || 640 VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI); 641 } else { 642 return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None || 643 VK == RISCVMCExpr::VK_RISCV_PCREL_HI || 644 VK == RISCVMCExpr::VK_RISCV_GOT_HI || 645 VK == RISCVMCExpr::VK_RISCV_TLS_GOT_HI || 646 VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI); 647 } 648 } 649 650 bool isSImm21Lsb0JAL() const { return isBareSimmNLsb0<21>(); } 651 652 bool isImmZero() const { 653 if (!isImm()) 654 return false; 655 int64_t Imm; 656 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 657 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 658 return IsConstantImm && (Imm == 0) && VK == RISCVMCExpr::VK_RISCV_None; 659 } 660 661 /// getStartLoc - Gets location of the first token of this operand 662 SMLoc getStartLoc() const override { return StartLoc; } 663 /// getEndLoc - Gets location of the last token of this operand 664 SMLoc getEndLoc() const override { return EndLoc; } 665 /// True if this operand is for an RV64 instruction 666 bool isRV64() const { return IsRV64; } 667 668 unsigned getReg() const override { 669 assert(Kind == KindTy::Register && "Invalid type access!"); 670 return Reg.RegNum.id(); 671 } 672 673 StringRef getSysReg() const { 674 assert(Kind == KindTy::SystemRegister && "Invalid access!"); 675 return StringRef(SysReg.Data, SysReg.Length); 676 } 677 678 const MCExpr *getImm() const { 679 assert(Kind == KindTy::Immediate && "Invalid type access!"); 680 return Imm.Val; 681 } 682 683 StringRef getToken() const { 684 assert(Kind == KindTy::Token && "Invalid type access!"); 685 return Tok; 686 } 687 688 void print(raw_ostream &OS) const override { 689 switch (Kind) { 690 case KindTy::Immediate: 691 OS << *getImm(); 692 break; 693 case KindTy::Register: 694 OS << "<register x"; 695 OS << getReg() << ">"; 696 break; 697 case KindTy::Token: 698 OS << "'" << getToken() << "'"; 699 break; 700 case KindTy::SystemRegister: 701 OS << "<sysreg: " << getSysReg() << '>'; 702 break; 703 } 704 } 705 706 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S, 707 bool IsRV64) { 708 auto Op = std::make_unique<RISCVOperand>(KindTy::Token); 709 Op->Tok = Str; 710 Op->StartLoc = S; 711 Op->EndLoc = S; 712 Op->IsRV64 = IsRV64; 713 return Op; 714 } 715 716 static std::unique_ptr<RISCVOperand> createReg(unsigned RegNo, SMLoc S, 717 SMLoc E, bool IsRV64) { 718 auto Op = std::make_unique<RISCVOperand>(KindTy::Register); 719 Op->Reg.RegNum = RegNo; 720 Op->StartLoc = S; 721 Op->EndLoc = E; 722 Op->IsRV64 = IsRV64; 723 return Op; 724 } 725 726 static std::unique_ptr<RISCVOperand> createImm(const MCExpr *Val, SMLoc S, 727 SMLoc E, bool IsRV64) { 728 auto Op = std::make_unique<RISCVOperand>(KindTy::Immediate); 729 Op->Imm.Val = Val; 730 Op->StartLoc = S; 731 Op->EndLoc = E; 732 Op->IsRV64 = IsRV64; 733 return Op; 734 } 735 736 static std::unique_ptr<RISCVOperand> 737 createSysReg(StringRef Str, SMLoc S, unsigned Encoding, bool IsRV64) { 738 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister); 739 Op->SysReg.Data = Str.data(); 740 Op->SysReg.Length = Str.size(); 741 Op->SysReg.Encoding = Encoding; 742 Op->StartLoc = S; 743 Op->IsRV64 = IsRV64; 744 return Op; 745 } 746 747 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 748 assert(Expr && "Expr shouldn't be null!"); 749 int64_t Imm = 0; 750 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 751 bool IsConstant = evaluateConstantImm(Expr, Imm, VK); 752 753 if (IsConstant) 754 Inst.addOperand(MCOperand::createImm(Imm)); 755 else 756 Inst.addOperand(MCOperand::createExpr(Expr)); 757 } 758 759 // Used by the TableGen Code 760 void addRegOperands(MCInst &Inst, unsigned N) const { 761 assert(N == 1 && "Invalid number of operands!"); 762 Inst.addOperand(MCOperand::createReg(getReg())); 763 } 764 765 void addImmOperands(MCInst &Inst, unsigned N) const { 766 assert(N == 1 && "Invalid number of operands!"); 767 addExpr(Inst, getImm()); 768 } 769 770 void addFenceArgOperands(MCInst &Inst, unsigned N) const { 771 assert(N == 1 && "Invalid number of operands!"); 772 // isFenceArg has validated the operand, meaning this cast is safe 773 auto SE = cast<MCSymbolRefExpr>(getImm()); 774 775 unsigned Imm = 0; 776 for (char c : SE->getSymbol().getName()) { 777 switch (c) { 778 default: 779 llvm_unreachable("FenceArg must contain only [iorw]"); 780 case 'i': Imm |= RISCVFenceField::I; break; 781 case 'o': Imm |= RISCVFenceField::O; break; 782 case 'r': Imm |= RISCVFenceField::R; break; 783 case 'w': Imm |= RISCVFenceField::W; break; 784 } 785 } 786 Inst.addOperand(MCOperand::createImm(Imm)); 787 } 788 789 void addCSRSystemRegisterOperands(MCInst &Inst, unsigned N) const { 790 assert(N == 1 && "Invalid number of operands!"); 791 Inst.addOperand(MCOperand::createImm(SysReg.Encoding)); 792 } 793 794 // Returns the rounding mode represented by this RISCVOperand. Should only 795 // be called after checking isFRMArg. 796 RISCVFPRndMode::RoundingMode getRoundingMode() const { 797 // isFRMArg has validated the operand, meaning this cast is safe. 798 auto SE = cast<MCSymbolRefExpr>(getImm()); 799 RISCVFPRndMode::RoundingMode FRM = 800 RISCVFPRndMode::stringToRoundingMode(SE->getSymbol().getName()); 801 assert(FRM != RISCVFPRndMode::Invalid && "Invalid rounding mode"); 802 return FRM; 803 } 804 805 void addFRMArgOperands(MCInst &Inst, unsigned N) const { 806 assert(N == 1 && "Invalid number of operands!"); 807 Inst.addOperand(MCOperand::createImm(getRoundingMode())); 808 } 809 }; 810 } // end anonymous namespace. 811 812 #define GET_REGISTER_MATCHER 813 #define GET_SUBTARGET_FEATURE_NAME 814 #define GET_MATCHER_IMPLEMENTATION 815 #define GET_MNEMONIC_SPELL_CHECKER 816 #include "RISCVGenAsmMatcher.inc" 817 818 static Register convertFPR64ToFPR32(Register Reg) { 819 assert(Reg >= RISCV::F0_D && Reg <= RISCV::F31_D && "Invalid register"); 820 return Reg - RISCV::F0_D + RISCV::F0_F; 821 } 822 823 unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp, 824 unsigned Kind) { 825 RISCVOperand &Op = static_cast<RISCVOperand &>(AsmOp); 826 if (!Op.isReg()) 827 return Match_InvalidOperand; 828 829 Register Reg = Op.getReg(); 830 bool IsRegFPR64 = 831 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(Reg); 832 bool IsRegFPR64C = 833 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(Reg); 834 835 // As the parser couldn't differentiate an FPR32 from an FPR64, coerce the 836 // register from FPR64 to FPR32 or FPR64C to FPR32C if necessary. 837 if ((IsRegFPR64 && Kind == MCK_FPR32) || 838 (IsRegFPR64C && Kind == MCK_FPR32C)) { 839 Op.Reg.RegNum = convertFPR64ToFPR32(Reg); 840 return Match_Success; 841 } 842 return Match_InvalidOperand; 843 } 844 845 bool RISCVAsmParser::generateImmOutOfRangeError( 846 OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper, 847 Twine Msg = "immediate must be an integer in the range") { 848 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 849 return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]"); 850 } 851 852 static std::string RISCVMnemonicSpellCheck(StringRef S, 853 const FeatureBitset &FBS, 854 unsigned VariantID = 0); 855 856 bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 857 OperandVector &Operands, 858 MCStreamer &Out, 859 uint64_t &ErrorInfo, 860 bool MatchingInlineAsm) { 861 MCInst Inst; 862 FeatureBitset MissingFeatures; 863 864 auto Result = 865 MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures, 866 MatchingInlineAsm); 867 switch (Result) { 868 default: 869 break; 870 case Match_Success: 871 return processInstruction(Inst, IDLoc, Operands, Out); 872 case Match_MissingFeature: { 873 assert(MissingFeatures.any() && "Unknown missing features!"); 874 bool FirstFeature = true; 875 std::string Msg = "instruction requires the following:"; 876 for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) { 877 if (MissingFeatures[i]) { 878 Msg += FirstFeature ? " " : ", "; 879 Msg += getSubtargetFeatureName(i); 880 FirstFeature = false; 881 } 882 } 883 return Error(IDLoc, Msg); 884 } 885 case Match_MnemonicFail: { 886 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits()); 887 std::string Suggestion = RISCVMnemonicSpellCheck( 888 ((RISCVOperand &)*Operands[0]).getToken(), FBS); 889 return Error(IDLoc, "unrecognized instruction mnemonic" + Suggestion); 890 } 891 case Match_InvalidOperand: { 892 SMLoc ErrorLoc = IDLoc; 893 if (ErrorInfo != ~0U) { 894 if (ErrorInfo >= Operands.size()) 895 return Error(ErrorLoc, "too few operands for instruction"); 896 897 ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 898 if (ErrorLoc == SMLoc()) 899 ErrorLoc = IDLoc; 900 } 901 return Error(ErrorLoc, "invalid operand for instruction"); 902 } 903 } 904 905 // Handle the case when the error message is of specific type 906 // other than the generic Match_InvalidOperand, and the 907 // corresponding operand is missing. 908 if (Result > FIRST_TARGET_MATCH_RESULT_TY) { 909 SMLoc ErrorLoc = IDLoc; 910 if (ErrorInfo != ~0U && ErrorInfo >= Operands.size()) 911 return Error(ErrorLoc, "too few operands for instruction"); 912 } 913 914 switch(Result) { 915 default: 916 break; 917 case Match_InvalidImmXLenLI: 918 if (isRV64()) { 919 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 920 return Error(ErrorLoc, "operand must be a constant 64-bit integer"); 921 } 922 return generateImmOutOfRangeError(Operands, ErrorInfo, 923 std::numeric_limits<int32_t>::min(), 924 std::numeric_limits<uint32_t>::max()); 925 case Match_InvalidImmZero: { 926 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 927 return Error(ErrorLoc, "immediate must be zero"); 928 } 929 case Match_InvalidUImmLog2XLen: 930 if (isRV64()) 931 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1); 932 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 933 case Match_InvalidUImmLog2XLenNonZero: 934 if (isRV64()) 935 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1); 936 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1); 937 case Match_InvalidUImmLog2XLenHalf: 938 if (isRV64()) 939 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 940 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1); 941 case Match_InvalidUImm5: 942 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 943 case Match_InvalidSImm6: 944 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5), 945 (1 << 5) - 1); 946 case Match_InvalidSImm6NonZero: 947 return generateImmOutOfRangeError( 948 Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1, 949 "immediate must be non-zero in the range"); 950 case Match_InvalidCLUIImm: 951 return generateImmOutOfRangeError( 952 Operands, ErrorInfo, 1, (1 << 5) - 1, 953 "immediate must be in [0xfffe0, 0xfffff] or"); 954 case Match_InvalidUImm7Lsb00: 955 return generateImmOutOfRangeError( 956 Operands, ErrorInfo, 0, (1 << 7) - 4, 957 "immediate must be a multiple of 4 bytes in the range"); 958 case Match_InvalidUImm8Lsb00: 959 return generateImmOutOfRangeError( 960 Operands, ErrorInfo, 0, (1 << 8) - 4, 961 "immediate must be a multiple of 4 bytes in the range"); 962 case Match_InvalidUImm8Lsb000: 963 return generateImmOutOfRangeError( 964 Operands, ErrorInfo, 0, (1 << 8) - 8, 965 "immediate must be a multiple of 8 bytes in the range"); 966 case Match_InvalidSImm9Lsb0: 967 return generateImmOutOfRangeError( 968 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2, 969 "immediate must be a multiple of 2 bytes in the range"); 970 case Match_InvalidUImm9Lsb000: 971 return generateImmOutOfRangeError( 972 Operands, ErrorInfo, 0, (1 << 9) - 8, 973 "immediate must be a multiple of 8 bytes in the range"); 974 case Match_InvalidUImm10Lsb00NonZero: 975 return generateImmOutOfRangeError( 976 Operands, ErrorInfo, 4, (1 << 10) - 4, 977 "immediate must be a multiple of 4 bytes in the range"); 978 case Match_InvalidSImm10Lsb0000NonZero: 979 return generateImmOutOfRangeError( 980 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16, 981 "immediate must be a multiple of 16 bytes and non-zero in the range"); 982 case Match_InvalidSImm12: 983 return generateImmOutOfRangeError( 984 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1, 985 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an " 986 "integer in the range"); 987 case Match_InvalidSImm12Lsb0: 988 return generateImmOutOfRangeError( 989 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2, 990 "immediate must be a multiple of 2 bytes in the range"); 991 case Match_InvalidSImm13Lsb0: 992 return generateImmOutOfRangeError( 993 Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2, 994 "immediate must be a multiple of 2 bytes in the range"); 995 case Match_InvalidUImm20LUI: 996 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1, 997 "operand must be a symbol with " 998 "%hi/%tprel_hi modifier or an integer in " 999 "the range"); 1000 case Match_InvalidUImm20AUIPC: 1001 return generateImmOutOfRangeError( 1002 Operands, ErrorInfo, 0, (1 << 20) - 1, 1003 "operand must be a symbol with a " 1004 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or " 1005 "an integer in the range"); 1006 case Match_InvalidSImm21Lsb0JAL: 1007 return generateImmOutOfRangeError( 1008 Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2, 1009 "immediate must be a multiple of 2 bytes in the range"); 1010 case Match_InvalidCSRSystemRegister: { 1011 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1, 1012 "operand must be a valid system register " 1013 "name or an integer in the range"); 1014 } 1015 case Match_InvalidFenceArg: { 1016 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1017 return Error( 1018 ErrorLoc, 1019 "operand must be formed of letters selected in-order from 'iorw'"); 1020 } 1021 case Match_InvalidFRMArg: { 1022 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1023 return Error( 1024 ErrorLoc, 1025 "operand must be a valid floating point rounding mode mnemonic"); 1026 } 1027 case Match_InvalidBareSymbol: { 1028 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1029 return Error(ErrorLoc, "operand must be a bare symbol name"); 1030 } 1031 case Match_InvalidPseudoJumpSymbol: { 1032 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1033 return Error(ErrorLoc, "operand must be a valid jump target"); 1034 } 1035 case Match_InvalidCallSymbol: { 1036 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1037 return Error(ErrorLoc, "operand must be a bare symbol name"); 1038 } 1039 case Match_InvalidTPRelAddSymbol: { 1040 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1041 return Error(ErrorLoc, "operand must be a symbol with %tprel_add modifier"); 1042 } 1043 } 1044 1045 llvm_unreachable("Unknown match type detected!"); 1046 } 1047 1048 // Attempts to match Name as a register (either using the default name or 1049 // alternative ABI names), setting RegNo to the matching register. Upon 1050 // failure, returns true and sets RegNo to 0. If IsRV32E then registers 1051 // x16-x31 will be rejected. 1052 static bool matchRegisterNameHelper(bool IsRV32E, Register &RegNo, 1053 StringRef Name) { 1054 RegNo = MatchRegisterName(Name); 1055 // The 32- and 64-bit FPRs have the same asm name. Check that the initial 1056 // match always matches the 64-bit variant, and not the 32-bit one. 1057 assert(!(RegNo >= RISCV::F0_F && RegNo <= RISCV::F31_F)); 1058 // The default FPR register class is based on the tablegen enum ordering. 1059 static_assert(RISCV::F0_D < RISCV::F0_F, "FPR matching must be updated"); 1060 if (RegNo == RISCV::NoRegister) 1061 RegNo = MatchRegisterAltName(Name); 1062 if (IsRV32E && RegNo >= RISCV::X16 && RegNo <= RISCV::X31) 1063 RegNo = RISCV::NoRegister; 1064 return RegNo == RISCV::NoRegister; 1065 } 1066 1067 bool RISCVAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 1068 SMLoc &EndLoc) { 1069 if (tryParseRegister(RegNo, StartLoc, EndLoc) != MatchOperand_Success) 1070 return Error(StartLoc, "invalid register name"); 1071 return false; 1072 } 1073 1074 OperandMatchResultTy RISCVAsmParser::tryParseRegister(unsigned &RegNo, 1075 SMLoc &StartLoc, 1076 SMLoc &EndLoc) { 1077 const AsmToken &Tok = getParser().getTok(); 1078 StartLoc = Tok.getLoc(); 1079 EndLoc = Tok.getEndLoc(); 1080 RegNo = 0; 1081 StringRef Name = getLexer().getTok().getIdentifier(); 1082 1083 if (matchRegisterNameHelper(isRV32E(), (Register &)RegNo, Name)) 1084 return MatchOperand_NoMatch; 1085 1086 getParser().Lex(); // Eat identifier token. 1087 return MatchOperand_Success; 1088 } 1089 1090 OperandMatchResultTy RISCVAsmParser::parseRegister(OperandVector &Operands, 1091 bool AllowParens) { 1092 SMLoc FirstS = getLoc(); 1093 bool HadParens = false; 1094 AsmToken LParen; 1095 1096 // If this is an LParen and a parenthesised register name is allowed, parse it 1097 // atomically. 1098 if (AllowParens && getLexer().is(AsmToken::LParen)) { 1099 AsmToken Buf[2]; 1100 size_t ReadCount = getLexer().peekTokens(Buf); 1101 if (ReadCount == 2 && Buf[1].getKind() == AsmToken::RParen) { 1102 HadParens = true; 1103 LParen = getParser().getTok(); 1104 getParser().Lex(); // Eat '(' 1105 } 1106 } 1107 1108 switch (getLexer().getKind()) { 1109 default: 1110 if (HadParens) 1111 getLexer().UnLex(LParen); 1112 return MatchOperand_NoMatch; 1113 case AsmToken::Identifier: 1114 StringRef Name = getLexer().getTok().getIdentifier(); 1115 Register RegNo; 1116 matchRegisterNameHelper(isRV32E(), RegNo, Name); 1117 1118 if (RegNo == RISCV::NoRegister) { 1119 if (HadParens) 1120 getLexer().UnLex(LParen); 1121 return MatchOperand_NoMatch; 1122 } 1123 if (HadParens) 1124 Operands.push_back(RISCVOperand::createToken("(", FirstS, isRV64())); 1125 SMLoc S = getLoc(); 1126 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1127 getLexer().Lex(); 1128 Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64())); 1129 } 1130 1131 if (HadParens) { 1132 getParser().Lex(); // Eat ')' 1133 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64())); 1134 } 1135 1136 return MatchOperand_Success; 1137 } 1138 1139 OperandMatchResultTy 1140 RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) { 1141 SMLoc S = getLoc(); 1142 const MCExpr *Res; 1143 1144 switch (getLexer().getKind()) { 1145 default: 1146 return MatchOperand_NoMatch; 1147 case AsmToken::LParen: 1148 case AsmToken::Minus: 1149 case AsmToken::Plus: 1150 case AsmToken::Exclaim: 1151 case AsmToken::Tilde: 1152 case AsmToken::Integer: 1153 case AsmToken::String: { 1154 if (getParser().parseExpression(Res)) 1155 return MatchOperand_ParseFail; 1156 1157 auto *CE = dyn_cast<MCConstantExpr>(Res); 1158 if (CE) { 1159 int64_t Imm = CE->getValue(); 1160 if (isUInt<12>(Imm)) { 1161 auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm); 1162 // Accept an immediate representing a named or un-named Sys Reg 1163 // if the range is valid, regardless of the required features. 1164 Operands.push_back(RISCVOperand::createSysReg( 1165 SysReg ? SysReg->Name : "", S, Imm, isRV64())); 1166 return MatchOperand_Success; 1167 } 1168 } 1169 1170 Twine Msg = "immediate must be an integer in the range"; 1171 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]"); 1172 return MatchOperand_ParseFail; 1173 } 1174 case AsmToken::Identifier: { 1175 StringRef Identifier; 1176 if (getParser().parseIdentifier(Identifier)) 1177 return MatchOperand_ParseFail; 1178 1179 auto SysReg = RISCVSysReg::lookupSysRegByName(Identifier); 1180 // Accept a named Sys Reg if the required features are present. 1181 if (SysReg) { 1182 if (!SysReg->haveRequiredFeatures(getSTI().getFeatureBits())) { 1183 Error(S, "system register use requires an option to be enabled"); 1184 return MatchOperand_ParseFail; 1185 } 1186 Operands.push_back(RISCVOperand::createSysReg( 1187 Identifier, S, SysReg->Encoding, isRV64())); 1188 return MatchOperand_Success; 1189 } 1190 1191 Twine Msg = "operand must be a valid system register name " 1192 "or an integer in the range"; 1193 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]"); 1194 return MatchOperand_ParseFail; 1195 } 1196 case AsmToken::Percent: { 1197 // Discard operand with modifier. 1198 Twine Msg = "immediate must be an integer in the range"; 1199 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]"); 1200 return MatchOperand_ParseFail; 1201 } 1202 } 1203 1204 return MatchOperand_NoMatch; 1205 } 1206 1207 OperandMatchResultTy RISCVAsmParser::parseImmediate(OperandVector &Operands) { 1208 SMLoc S = getLoc(); 1209 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1210 const MCExpr *Res; 1211 1212 switch (getLexer().getKind()) { 1213 default: 1214 return MatchOperand_NoMatch; 1215 case AsmToken::LParen: 1216 case AsmToken::Dot: 1217 case AsmToken::Minus: 1218 case AsmToken::Plus: 1219 case AsmToken::Exclaim: 1220 case AsmToken::Tilde: 1221 case AsmToken::Integer: 1222 case AsmToken::String: 1223 case AsmToken::Identifier: 1224 if (getParser().parseExpression(Res)) 1225 return MatchOperand_ParseFail; 1226 break; 1227 case AsmToken::Percent: 1228 return parseOperandWithModifier(Operands); 1229 } 1230 1231 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1232 return MatchOperand_Success; 1233 } 1234 1235 OperandMatchResultTy 1236 RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) { 1237 SMLoc S = getLoc(); 1238 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1239 1240 if (getLexer().getKind() != AsmToken::Percent) { 1241 Error(getLoc(), "expected '%' for operand modifier"); 1242 return MatchOperand_ParseFail; 1243 } 1244 1245 getParser().Lex(); // Eat '%' 1246 1247 if (getLexer().getKind() != AsmToken::Identifier) { 1248 Error(getLoc(), "expected valid identifier for operand modifier"); 1249 return MatchOperand_ParseFail; 1250 } 1251 StringRef Identifier = getParser().getTok().getIdentifier(); 1252 RISCVMCExpr::VariantKind VK = RISCVMCExpr::getVariantKindForName(Identifier); 1253 if (VK == RISCVMCExpr::VK_RISCV_Invalid) { 1254 Error(getLoc(), "unrecognized operand modifier"); 1255 return MatchOperand_ParseFail; 1256 } 1257 1258 getParser().Lex(); // Eat the identifier 1259 if (getLexer().getKind() != AsmToken::LParen) { 1260 Error(getLoc(), "expected '('"); 1261 return MatchOperand_ParseFail; 1262 } 1263 getParser().Lex(); // Eat '(' 1264 1265 const MCExpr *SubExpr; 1266 if (getParser().parseParenExpression(SubExpr, E)) { 1267 return MatchOperand_ParseFail; 1268 } 1269 1270 const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, VK, getContext()); 1271 Operands.push_back(RISCVOperand::createImm(ModExpr, S, E, isRV64())); 1272 return MatchOperand_Success; 1273 } 1274 1275 OperandMatchResultTy RISCVAsmParser::parseBareSymbol(OperandVector &Operands) { 1276 SMLoc S = getLoc(); 1277 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1278 const MCExpr *Res; 1279 1280 if (getLexer().getKind() != AsmToken::Identifier) 1281 return MatchOperand_NoMatch; 1282 1283 StringRef Identifier; 1284 AsmToken Tok = getLexer().getTok(); 1285 1286 if (getParser().parseIdentifier(Identifier)) 1287 return MatchOperand_ParseFail; 1288 1289 if (Identifier.consume_back("@plt")) { 1290 Error(getLoc(), "'@plt' operand not valid for instruction"); 1291 return MatchOperand_ParseFail; 1292 } 1293 1294 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); 1295 1296 if (Sym->isVariable()) { 1297 const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false); 1298 if (!isa<MCSymbolRefExpr>(V)) { 1299 getLexer().UnLex(Tok); // Put back if it's not a bare symbol. 1300 return MatchOperand_NoMatch; 1301 } 1302 Res = V; 1303 } else 1304 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1305 1306 MCBinaryExpr::Opcode Opcode; 1307 switch (getLexer().getKind()) { 1308 default: 1309 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1310 return MatchOperand_Success; 1311 case AsmToken::Plus: 1312 Opcode = MCBinaryExpr::Add; 1313 break; 1314 case AsmToken::Minus: 1315 Opcode = MCBinaryExpr::Sub; 1316 break; 1317 } 1318 1319 const MCExpr *Expr; 1320 if (getParser().parseExpression(Expr)) 1321 return MatchOperand_ParseFail; 1322 Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext()); 1323 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1324 return MatchOperand_Success; 1325 } 1326 1327 OperandMatchResultTy RISCVAsmParser::parseCallSymbol(OperandVector &Operands) { 1328 SMLoc S = getLoc(); 1329 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1330 const MCExpr *Res; 1331 1332 if (getLexer().getKind() != AsmToken::Identifier) 1333 return MatchOperand_NoMatch; 1334 1335 // Avoid parsing the register in `call rd, foo` as a call symbol. 1336 if (getLexer().peekTok().getKind() != AsmToken::EndOfStatement) 1337 return MatchOperand_NoMatch; 1338 1339 StringRef Identifier; 1340 if (getParser().parseIdentifier(Identifier)) 1341 return MatchOperand_ParseFail; 1342 1343 RISCVMCExpr::VariantKind Kind = RISCVMCExpr::VK_RISCV_CALL; 1344 if (Identifier.consume_back("@plt")) 1345 Kind = RISCVMCExpr::VK_RISCV_CALL_PLT; 1346 1347 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); 1348 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1349 Res = RISCVMCExpr::create(Res, Kind, getContext()); 1350 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1351 return MatchOperand_Success; 1352 } 1353 1354 OperandMatchResultTy 1355 RISCVAsmParser::parsePseudoJumpSymbol(OperandVector &Operands) { 1356 SMLoc S = getLoc(); 1357 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1358 const MCExpr *Res; 1359 1360 if (getParser().parseExpression(Res)) 1361 return MatchOperand_ParseFail; 1362 1363 if (Res->getKind() != MCExpr::ExprKind::SymbolRef || 1364 cast<MCSymbolRefExpr>(Res)->getKind() == 1365 MCSymbolRefExpr::VariantKind::VK_PLT) { 1366 Error(S, "operand must be a valid jump target"); 1367 return MatchOperand_ParseFail; 1368 } 1369 1370 Res = RISCVMCExpr::create(Res, RISCVMCExpr::VK_RISCV_CALL, getContext()); 1371 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1372 return MatchOperand_Success; 1373 } 1374 1375 OperandMatchResultTy RISCVAsmParser::parseJALOffset(OperandVector &Operands) { 1376 // Parsing jal operands is fiddly due to the `jal foo` and `jal ra, foo` 1377 // both being acceptable forms. When parsing `jal ra, foo` this function 1378 // will be called for the `ra` register operand in an attempt to match the 1379 // single-operand alias. parseJALOffset must fail for this case. It would 1380 // seem logical to try parse the operand using parseImmediate and return 1381 // NoMatch if the next token is a comma (meaning we must be parsing a jal in 1382 // the second form rather than the first). We can't do this as there's no 1383 // way of rewinding the lexer state. Instead, return NoMatch if this operand 1384 // is an identifier and is followed by a comma. 1385 if (getLexer().is(AsmToken::Identifier) && 1386 getLexer().peekTok().is(AsmToken::Comma)) 1387 return MatchOperand_NoMatch; 1388 1389 return parseImmediate(Operands); 1390 } 1391 1392 OperandMatchResultTy 1393 RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) { 1394 if (getLexer().isNot(AsmToken::LParen)) { 1395 Error(getLoc(), "expected '('"); 1396 return MatchOperand_ParseFail; 1397 } 1398 1399 getParser().Lex(); // Eat '(' 1400 Operands.push_back(RISCVOperand::createToken("(", getLoc(), isRV64())); 1401 1402 if (parseRegister(Operands) != MatchOperand_Success) { 1403 Error(getLoc(), "expected register"); 1404 return MatchOperand_ParseFail; 1405 } 1406 1407 if (getLexer().isNot(AsmToken::RParen)) { 1408 Error(getLoc(), "expected ')'"); 1409 return MatchOperand_ParseFail; 1410 } 1411 1412 getParser().Lex(); // Eat ')' 1413 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64())); 1414 1415 return MatchOperand_Success; 1416 } 1417 1418 OperandMatchResultTy RISCVAsmParser::parseAtomicMemOp(OperandVector &Operands) { 1419 // Atomic operations such as lr.w, sc.w, and amo*.w accept a "memory operand" 1420 // as one of their register operands, such as `(a0)`. This just denotes that 1421 // the register (in this case `a0`) contains a memory address. 1422 // 1423 // Normally, we would be able to parse these by putting the parens into the 1424 // instruction string. However, GNU as also accepts a zero-offset memory 1425 // operand (such as `0(a0)`), and ignores the 0. Normally this would be parsed 1426 // with parseImmediate followed by parseMemOpBaseReg, but these instructions 1427 // do not accept an immediate operand, and we do not want to add a "dummy" 1428 // operand that is silently dropped. 1429 // 1430 // Instead, we use this custom parser. This will: allow (and discard) an 1431 // offset if it is zero; require (and discard) parentheses; and add only the 1432 // parsed register operand to `Operands`. 1433 // 1434 // These operands are printed with RISCVInstPrinter::printAtomicMemOp, which 1435 // will only print the register surrounded by parentheses (which GNU as also 1436 // uses as its canonical representation for these operands). 1437 std::unique_ptr<RISCVOperand> OptionalImmOp; 1438 1439 if (getLexer().isNot(AsmToken::LParen)) { 1440 // Parse an Integer token. We do not accept arbritrary constant expressions 1441 // in the offset field (because they may include parens, which complicates 1442 // parsing a lot). 1443 int64_t ImmVal; 1444 SMLoc ImmStart = getLoc(); 1445 if (getParser().parseIntToken(ImmVal, 1446 "expected '(' or optional integer offset")) 1447 return MatchOperand_ParseFail; 1448 1449 // Create a RISCVOperand for checking later (so the error messages are 1450 // nicer), but we don't add it to Operands. 1451 SMLoc ImmEnd = getLoc(); 1452 OptionalImmOp = 1453 RISCVOperand::createImm(MCConstantExpr::create(ImmVal, getContext()), 1454 ImmStart, ImmEnd, isRV64()); 1455 } 1456 1457 if (getLexer().isNot(AsmToken::LParen)) { 1458 Error(getLoc(), OptionalImmOp ? "expected '(' after optional integer offset" 1459 : "expected '(' or optional integer offset"); 1460 return MatchOperand_ParseFail; 1461 } 1462 getParser().Lex(); // Eat '(' 1463 1464 if (parseRegister(Operands) != MatchOperand_Success) { 1465 Error(getLoc(), "expected register"); 1466 return MatchOperand_ParseFail; 1467 } 1468 1469 if (getLexer().isNot(AsmToken::RParen)) { 1470 Error(getLoc(), "expected ')'"); 1471 return MatchOperand_ParseFail; 1472 } 1473 getParser().Lex(); // Eat ')' 1474 1475 // Deferred Handling of non-zero offsets. This makes the error messages nicer. 1476 if (OptionalImmOp && !OptionalImmOp->isImmZero()) { 1477 Error(OptionalImmOp->getStartLoc(), "optional integer offset must be 0", 1478 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc())); 1479 return MatchOperand_ParseFail; 1480 } 1481 1482 return MatchOperand_Success; 1483 } 1484 1485 /// Looks at a token type and creates the relevant operand from this 1486 /// information, adding to Operands. If operand was parsed, returns false, else 1487 /// true. 1488 bool RISCVAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { 1489 // Check if the current operand has a custom associated parser, if so, try to 1490 // custom parse the operand, or fallback to the general approach. 1491 OperandMatchResultTy Result = 1492 MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true); 1493 if (Result == MatchOperand_Success) 1494 return false; 1495 if (Result == MatchOperand_ParseFail) 1496 return true; 1497 1498 // Attempt to parse token as a register. 1499 if (parseRegister(Operands, true) == MatchOperand_Success) 1500 return false; 1501 1502 // Attempt to parse token as an immediate 1503 if (parseImmediate(Operands) == MatchOperand_Success) { 1504 // Parse memory base register if present 1505 if (getLexer().is(AsmToken::LParen)) 1506 return parseMemOpBaseReg(Operands) != MatchOperand_Success; 1507 return false; 1508 } 1509 1510 // Finally we have exhausted all options and must declare defeat. 1511 Error(getLoc(), "unknown operand"); 1512 return true; 1513 } 1514 1515 bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info, 1516 StringRef Name, SMLoc NameLoc, 1517 OperandVector &Operands) { 1518 // Ensure that if the instruction occurs when relaxation is enabled, 1519 // relocations are forced for the file. Ideally this would be done when there 1520 // is enough information to reliably determine if the instruction itself may 1521 // cause relaxations. Unfortunately instruction processing stage occurs in the 1522 // same pass as relocation emission, so it's too late to set a 'sticky bit' 1523 // for the entire file. 1524 if (getSTI().getFeatureBits()[RISCV::FeatureRelax]) { 1525 auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr(); 1526 if (Assembler != nullptr) { 1527 RISCVAsmBackend &MAB = 1528 static_cast<RISCVAsmBackend &>(Assembler->getBackend()); 1529 MAB.setForceRelocs(); 1530 } 1531 } 1532 1533 // First operand is token for instruction 1534 Operands.push_back(RISCVOperand::createToken(Name, NameLoc, isRV64())); 1535 1536 // If there are no more operands, then finish 1537 if (getLexer().is(AsmToken::EndOfStatement)) 1538 return false; 1539 1540 // Parse first operand 1541 if (parseOperand(Operands, Name)) 1542 return true; 1543 1544 // Parse until end of statement, consuming commas between operands 1545 unsigned OperandIdx = 1; 1546 while (getLexer().is(AsmToken::Comma)) { 1547 // Consume comma token 1548 getLexer().Lex(); 1549 1550 // Parse next operand 1551 if (parseOperand(Operands, Name)) 1552 return true; 1553 1554 ++OperandIdx; 1555 } 1556 1557 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1558 SMLoc Loc = getLexer().getLoc(); 1559 getParser().eatToEndOfStatement(); 1560 return Error(Loc, "unexpected token"); 1561 } 1562 1563 getParser().Lex(); // Consume the EndOfStatement. 1564 return false; 1565 } 1566 1567 bool RISCVAsmParser::classifySymbolRef(const MCExpr *Expr, 1568 RISCVMCExpr::VariantKind &Kind, 1569 int64_t &Addend) { 1570 Kind = RISCVMCExpr::VK_RISCV_None; 1571 Addend = 0; 1572 1573 if (const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) { 1574 Kind = RE->getKind(); 1575 Expr = RE->getSubExpr(); 1576 } 1577 1578 // It's a simple symbol reference or constant with no addend. 1579 if (isa<MCConstantExpr>(Expr) || isa<MCSymbolRefExpr>(Expr)) 1580 return true; 1581 1582 const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr); 1583 if (!BE) 1584 return false; 1585 1586 if (!isa<MCSymbolRefExpr>(BE->getLHS())) 1587 return false; 1588 1589 if (BE->getOpcode() != MCBinaryExpr::Add && 1590 BE->getOpcode() != MCBinaryExpr::Sub) 1591 return false; 1592 1593 // We are able to support the subtraction of two symbol references 1594 if (BE->getOpcode() == MCBinaryExpr::Sub && 1595 isa<MCSymbolRefExpr>(BE->getRHS())) 1596 return true; 1597 1598 // See if the addend is a constant, otherwise there's more going 1599 // on here than we can deal with. 1600 auto AddendExpr = dyn_cast<MCConstantExpr>(BE->getRHS()); 1601 if (!AddendExpr) 1602 return false; 1603 1604 Addend = AddendExpr->getValue(); 1605 if (BE->getOpcode() == MCBinaryExpr::Sub) 1606 Addend = -Addend; 1607 1608 // It's some symbol reference + a constant addend 1609 return Kind != RISCVMCExpr::VK_RISCV_Invalid; 1610 } 1611 1612 bool RISCVAsmParser::ParseDirective(AsmToken DirectiveID) { 1613 // This returns false if this function recognizes the directive 1614 // regardless of whether it is successfully handles or reports an 1615 // error. Otherwise it returns true to give the generic parser a 1616 // chance at recognizing it. 1617 StringRef IDVal = DirectiveID.getString(); 1618 1619 if (IDVal == ".option") 1620 return parseDirectiveOption(); 1621 else if (IDVal == ".attribute") 1622 return parseDirectiveAttribute(); 1623 1624 return true; 1625 } 1626 1627 bool RISCVAsmParser::parseDirectiveOption() { 1628 MCAsmParser &Parser = getParser(); 1629 // Get the option token. 1630 AsmToken Tok = Parser.getTok(); 1631 // At the moment only identifiers are supported. 1632 if (Tok.isNot(AsmToken::Identifier)) 1633 return Error(Parser.getTok().getLoc(), 1634 "unexpected token, expected identifier"); 1635 1636 StringRef Option = Tok.getIdentifier(); 1637 1638 if (Option == "push") { 1639 getTargetStreamer().emitDirectiveOptionPush(); 1640 1641 Parser.Lex(); 1642 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1643 return Error(Parser.getTok().getLoc(), 1644 "unexpected token, expected end of statement"); 1645 1646 pushFeatureBits(); 1647 return false; 1648 } 1649 1650 if (Option == "pop") { 1651 SMLoc StartLoc = Parser.getTok().getLoc(); 1652 getTargetStreamer().emitDirectiveOptionPop(); 1653 1654 Parser.Lex(); 1655 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1656 return Error(Parser.getTok().getLoc(), 1657 "unexpected token, expected end of statement"); 1658 1659 if (popFeatureBits()) 1660 return Error(StartLoc, ".option pop with no .option push"); 1661 1662 return false; 1663 } 1664 1665 if (Option == "rvc") { 1666 getTargetStreamer().emitDirectiveOptionRVC(); 1667 1668 Parser.Lex(); 1669 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1670 return Error(Parser.getTok().getLoc(), 1671 "unexpected token, expected end of statement"); 1672 1673 setFeatureBits(RISCV::FeatureStdExtC, "c"); 1674 return false; 1675 } 1676 1677 if (Option == "norvc") { 1678 getTargetStreamer().emitDirectiveOptionNoRVC(); 1679 1680 Parser.Lex(); 1681 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1682 return Error(Parser.getTok().getLoc(), 1683 "unexpected token, expected end of statement"); 1684 1685 clearFeatureBits(RISCV::FeatureStdExtC, "c"); 1686 return false; 1687 } 1688 1689 if (Option == "pic") { 1690 getTargetStreamer().emitDirectiveOptionPIC(); 1691 1692 Parser.Lex(); 1693 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1694 return Error(Parser.getTok().getLoc(), 1695 "unexpected token, expected end of statement"); 1696 1697 ParserOptions.IsPicEnabled = true; 1698 return false; 1699 } 1700 1701 if (Option == "nopic") { 1702 getTargetStreamer().emitDirectiveOptionNoPIC(); 1703 1704 Parser.Lex(); 1705 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1706 return Error(Parser.getTok().getLoc(), 1707 "unexpected token, expected end of statement"); 1708 1709 ParserOptions.IsPicEnabled = false; 1710 return false; 1711 } 1712 1713 if (Option == "relax") { 1714 getTargetStreamer().emitDirectiveOptionRelax(); 1715 1716 Parser.Lex(); 1717 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1718 return Error(Parser.getTok().getLoc(), 1719 "unexpected token, expected end of statement"); 1720 1721 setFeatureBits(RISCV::FeatureRelax, "relax"); 1722 return false; 1723 } 1724 1725 if (Option == "norelax") { 1726 getTargetStreamer().emitDirectiveOptionNoRelax(); 1727 1728 Parser.Lex(); 1729 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1730 return Error(Parser.getTok().getLoc(), 1731 "unexpected token, expected end of statement"); 1732 1733 clearFeatureBits(RISCV::FeatureRelax, "relax"); 1734 return false; 1735 } 1736 1737 // Unknown option. 1738 Warning(Parser.getTok().getLoc(), 1739 "unknown option, expected 'push', 'pop', 'rvc', 'norvc', 'relax' or " 1740 "'norelax'"); 1741 Parser.eatToEndOfStatement(); 1742 return false; 1743 } 1744 1745 /// parseDirectiveAttribute 1746 /// ::= .attribute expression ',' ( expression | "string" ) 1747 /// ::= .attribute identifier ',' ( expression | "string" ) 1748 bool RISCVAsmParser::parseDirectiveAttribute() { 1749 MCAsmParser &Parser = getParser(); 1750 int64_t Tag; 1751 SMLoc TagLoc; 1752 TagLoc = Parser.getTok().getLoc(); 1753 if (Parser.getTok().is(AsmToken::Identifier)) { 1754 StringRef Name = Parser.getTok().getIdentifier(); 1755 Optional<unsigned> Ret = 1756 ELFAttrs::attrTypeFromString(Name, RISCVAttrs::RISCVAttributeTags); 1757 if (!Ret.hasValue()) { 1758 Error(TagLoc, "attribute name not recognised: " + Name); 1759 return false; 1760 } 1761 Tag = Ret.getValue(); 1762 Parser.Lex(); 1763 } else { 1764 const MCExpr *AttrExpr; 1765 1766 TagLoc = Parser.getTok().getLoc(); 1767 if (Parser.parseExpression(AttrExpr)) 1768 return true; 1769 1770 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr); 1771 if (check(!CE, TagLoc, "expected numeric constant")) 1772 return true; 1773 1774 Tag = CE->getValue(); 1775 } 1776 1777 if (Parser.parseToken(AsmToken::Comma, "comma expected")) 1778 return true; 1779 1780 StringRef StringValue; 1781 int64_t IntegerValue = 0; 1782 bool IsIntegerValue = true; 1783 1784 // RISC-V attributes have a string value if the tag number is odd 1785 // and an integer value if the tag number is even. 1786 if (Tag % 2) 1787 IsIntegerValue = false; 1788 1789 SMLoc ValueExprLoc = Parser.getTok().getLoc(); 1790 if (IsIntegerValue) { 1791 const MCExpr *ValueExpr; 1792 if (Parser.parseExpression(ValueExpr)) 1793 return true; 1794 1795 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr); 1796 if (!CE) 1797 return Error(ValueExprLoc, "expected numeric constant"); 1798 IntegerValue = CE->getValue(); 1799 } else { 1800 if (Parser.getTok().isNot(AsmToken::String)) 1801 return Error(Parser.getTok().getLoc(), "expected string constant"); 1802 1803 StringValue = Parser.getTok().getStringContents(); 1804 Parser.Lex(); 1805 } 1806 1807 if (Parser.parseToken(AsmToken::EndOfStatement, 1808 "unexpected token in '.attribute' directive")) 1809 return true; 1810 1811 if (Tag == RISCVAttrs::ARCH) { 1812 StringRef Arch = StringValue; 1813 if (Arch.consume_front("rv32")) 1814 clearFeatureBits(RISCV::Feature64Bit, "64bit"); 1815 else if (Arch.consume_front("rv64")) 1816 setFeatureBits(RISCV::Feature64Bit, "64bit"); 1817 else 1818 return Error(ValueExprLoc, "bad arch string " + Arch); 1819 1820 while (!Arch.empty()) { 1821 if (Arch[0] == 'i') 1822 clearFeatureBits(RISCV::FeatureRV32E, "e"); 1823 else if (Arch[0] == 'e') 1824 setFeatureBits(RISCV::FeatureRV32E, "e"); 1825 else if (Arch[0] == 'g') { 1826 clearFeatureBits(RISCV::FeatureRV32E, "e"); 1827 setFeatureBits(RISCV::FeatureStdExtM, "m"); 1828 setFeatureBits(RISCV::FeatureStdExtA, "a"); 1829 setFeatureBits(RISCV::FeatureStdExtF, "f"); 1830 setFeatureBits(RISCV::FeatureStdExtD, "d"); 1831 } else if (Arch[0] == 'm') 1832 setFeatureBits(RISCV::FeatureStdExtM, "m"); 1833 else if (Arch[0] == 'a') 1834 setFeatureBits(RISCV::FeatureStdExtA, "a"); 1835 else if (Arch[0] == 'f') 1836 setFeatureBits(RISCV::FeatureStdExtF, "f"); 1837 else if (Arch[0] == 'd') { 1838 setFeatureBits(RISCV::FeatureStdExtF, "f"); 1839 setFeatureBits(RISCV::FeatureStdExtD, "d"); 1840 } else if (Arch[0] == 'c') { 1841 setFeatureBits(RISCV::FeatureStdExtC, "c"); 1842 } else 1843 return Error(ValueExprLoc, "bad arch string " + Arch); 1844 1845 Arch = Arch.drop_front(1); 1846 int major = 0; 1847 int minor = 0; 1848 Arch.consumeInteger(10, major); 1849 Arch.consume_front("p"); 1850 Arch.consumeInteger(10, minor); 1851 if (major != 0 || minor != 0) { 1852 Arch = Arch.drop_until([](char c) { return c == '_' || c == '"'; }); 1853 Arch = Arch.drop_while([](char c) { return c == '_'; }); 1854 } 1855 } 1856 } 1857 1858 if (IsIntegerValue) 1859 getTargetStreamer().emitAttribute(Tag, IntegerValue); 1860 else { 1861 if (Tag != RISCVAttrs::ARCH) { 1862 getTargetStreamer().emitTextAttribute(Tag, StringValue); 1863 } else { 1864 std::string formalArchStr = "rv32"; 1865 if (getFeatureBits(RISCV::Feature64Bit)) 1866 formalArchStr = "rv64"; 1867 if (getFeatureBits(RISCV::FeatureRV32E)) 1868 formalArchStr = (Twine(formalArchStr) + "e1p9").str(); 1869 else 1870 formalArchStr = (Twine(formalArchStr) + "i2p0").str(); 1871 1872 if (getFeatureBits(RISCV::FeatureStdExtM)) 1873 formalArchStr = (Twine(formalArchStr) + "_m2p0").str(); 1874 if (getFeatureBits(RISCV::FeatureStdExtA)) 1875 formalArchStr = (Twine(formalArchStr) + "_a2p0").str(); 1876 if (getFeatureBits(RISCV::FeatureStdExtF)) 1877 formalArchStr = (Twine(formalArchStr) + "_f2p0").str(); 1878 if (getFeatureBits(RISCV::FeatureStdExtD)) 1879 formalArchStr = (Twine(formalArchStr) + "_d2p0").str(); 1880 if (getFeatureBits(RISCV::FeatureStdExtC)) 1881 formalArchStr = (Twine(formalArchStr) + "_c2p0").str(); 1882 1883 getTargetStreamer().emitTextAttribute(Tag, formalArchStr); 1884 } 1885 } 1886 1887 return false; 1888 } 1889 1890 void RISCVAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) { 1891 MCInst CInst; 1892 bool Res = compressInst(CInst, Inst, getSTI(), S.getContext()); 1893 if (Res) 1894 ++RISCVNumInstrsCompressed; 1895 S.emitInstruction((Res ? CInst : Inst), getSTI()); 1896 } 1897 1898 void RISCVAsmParser::emitLoadImm(Register DestReg, int64_t Value, 1899 MCStreamer &Out) { 1900 RISCVMatInt::InstSeq Seq; 1901 RISCVMatInt::generateInstSeq(Value, isRV64(), Seq); 1902 1903 Register SrcReg = RISCV::X0; 1904 for (RISCVMatInt::Inst &Inst : Seq) { 1905 if (Inst.Opc == RISCV::LUI) { 1906 emitToStreamer( 1907 Out, MCInstBuilder(RISCV::LUI).addReg(DestReg).addImm(Inst.Imm)); 1908 } else { 1909 emitToStreamer( 1910 Out, MCInstBuilder(Inst.Opc).addReg(DestReg).addReg(SrcReg).addImm( 1911 Inst.Imm)); 1912 } 1913 1914 // Only the first instruction has X0 as its source. 1915 SrcReg = DestReg; 1916 } 1917 } 1918 1919 void RISCVAsmParser::emitAuipcInstPair(MCOperand DestReg, MCOperand TmpReg, 1920 const MCExpr *Symbol, 1921 RISCVMCExpr::VariantKind VKHi, 1922 unsigned SecondOpcode, SMLoc IDLoc, 1923 MCStreamer &Out) { 1924 // A pair of instructions for PC-relative addressing; expands to 1925 // TmpLabel: AUIPC TmpReg, VKHi(symbol) 1926 // OP DestReg, TmpReg, %pcrel_lo(TmpLabel) 1927 MCContext &Ctx = getContext(); 1928 1929 MCSymbol *TmpLabel = Ctx.createTempSymbol( 1930 "pcrel_hi", /* AlwaysAddSuffix */ true, /* CanBeUnnamed */ false); 1931 Out.emitLabel(TmpLabel); 1932 1933 const RISCVMCExpr *SymbolHi = RISCVMCExpr::create(Symbol, VKHi, Ctx); 1934 emitToStreamer( 1935 Out, MCInstBuilder(RISCV::AUIPC).addOperand(TmpReg).addExpr(SymbolHi)); 1936 1937 const MCExpr *RefToLinkTmpLabel = 1938 RISCVMCExpr::create(MCSymbolRefExpr::create(TmpLabel, Ctx), 1939 RISCVMCExpr::VK_RISCV_PCREL_LO, Ctx); 1940 1941 emitToStreamer(Out, MCInstBuilder(SecondOpcode) 1942 .addOperand(DestReg) 1943 .addOperand(TmpReg) 1944 .addExpr(RefToLinkTmpLabel)); 1945 } 1946 1947 void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, 1948 MCStreamer &Out) { 1949 // The load local address pseudo-instruction "lla" is used in PC-relative 1950 // addressing of local symbols: 1951 // lla rdest, symbol 1952 // expands to 1953 // TmpLabel: AUIPC rdest, %pcrel_hi(symbol) 1954 // ADDI rdest, rdest, %pcrel_lo(TmpLabel) 1955 MCOperand DestReg = Inst.getOperand(0); 1956 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 1957 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI, 1958 RISCV::ADDI, IDLoc, Out); 1959 } 1960 1961 void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc, 1962 MCStreamer &Out) { 1963 // The load address pseudo-instruction "la" is used in PC-relative and 1964 // GOT-indirect addressing of global symbols: 1965 // la rdest, symbol 1966 // expands to either (for non-PIC) 1967 // TmpLabel: AUIPC rdest, %pcrel_hi(symbol) 1968 // ADDI rdest, rdest, %pcrel_lo(TmpLabel) 1969 // or (for PIC) 1970 // TmpLabel: AUIPC rdest, %got_pcrel_hi(symbol) 1971 // Lx rdest, %pcrel_lo(TmpLabel)(rdest) 1972 MCOperand DestReg = Inst.getOperand(0); 1973 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 1974 unsigned SecondOpcode; 1975 RISCVMCExpr::VariantKind VKHi; 1976 if (ParserOptions.IsPicEnabled) { 1977 SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW; 1978 VKHi = RISCVMCExpr::VK_RISCV_GOT_HI; 1979 } else { 1980 SecondOpcode = RISCV::ADDI; 1981 VKHi = RISCVMCExpr::VK_RISCV_PCREL_HI; 1982 } 1983 emitAuipcInstPair(DestReg, DestReg, Symbol, VKHi, SecondOpcode, IDLoc, Out); 1984 } 1985 1986 void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc, 1987 MCStreamer &Out) { 1988 // The load TLS IE address pseudo-instruction "la.tls.ie" is used in 1989 // initial-exec TLS model addressing of global symbols: 1990 // la.tls.ie rdest, symbol 1991 // expands to 1992 // TmpLabel: AUIPC rdest, %tls_ie_pcrel_hi(symbol) 1993 // Lx rdest, %pcrel_lo(TmpLabel)(rdest) 1994 MCOperand DestReg = Inst.getOperand(0); 1995 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 1996 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW; 1997 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_TLS_GOT_HI, 1998 SecondOpcode, IDLoc, Out); 1999 } 2000 2001 void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, 2002 MCStreamer &Out) { 2003 // The load TLS GD address pseudo-instruction "la.tls.gd" is used in 2004 // global-dynamic TLS model addressing of global symbols: 2005 // la.tls.gd rdest, symbol 2006 // expands to 2007 // TmpLabel: AUIPC rdest, %tls_gd_pcrel_hi(symbol) 2008 // ADDI rdest, rdest, %pcrel_lo(TmpLabel) 2009 MCOperand DestReg = Inst.getOperand(0); 2010 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 2011 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_TLS_GD_HI, 2012 RISCV::ADDI, IDLoc, Out); 2013 } 2014 2015 void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode, 2016 SMLoc IDLoc, MCStreamer &Out, 2017 bool HasTmpReg) { 2018 // The load/store pseudo-instruction does a pc-relative load with 2019 // a symbol. 2020 // 2021 // The expansion looks like this 2022 // 2023 // TmpLabel: AUIPC tmp, %pcrel_hi(symbol) 2024 // [S|L]X rd, %pcrel_lo(TmpLabel)(tmp) 2025 MCOperand DestReg = Inst.getOperand(0); 2026 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1; 2027 unsigned TmpRegOpIdx = HasTmpReg ? 1 : 0; 2028 MCOperand TmpReg = Inst.getOperand(TmpRegOpIdx); 2029 const MCExpr *Symbol = Inst.getOperand(SymbolOpIdx).getExpr(); 2030 emitAuipcInstPair(DestReg, TmpReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI, 2031 Opcode, IDLoc, Out); 2032 } 2033 2034 bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst, 2035 OperandVector &Operands) { 2036 assert(Inst.getOpcode() == RISCV::PseudoAddTPRel && "Invalid instruction"); 2037 assert(Inst.getOperand(2).isReg() && "Unexpected second operand kind"); 2038 if (Inst.getOperand(2).getReg() != RISCV::X4) { 2039 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc(); 2040 return Error(ErrorLoc, "the second input operand must be tp/x4 when using " 2041 "%tprel_add modifier"); 2042 } 2043 2044 return false; 2045 } 2046 2047 bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 2048 OperandVector &Operands, 2049 MCStreamer &Out) { 2050 Inst.setLoc(IDLoc); 2051 2052 switch (Inst.getOpcode()) { 2053 default: 2054 break; 2055 case RISCV::PseudoLI: { 2056 Register Reg = Inst.getOperand(0).getReg(); 2057 const MCOperand &Op1 = Inst.getOperand(1); 2058 if (Op1.isExpr()) { 2059 // We must have li reg, %lo(sym) or li reg, %pcrel_lo(sym) or similar. 2060 // Just convert to an addi. This allows compatibility with gas. 2061 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI) 2062 .addReg(Reg) 2063 .addReg(RISCV::X0) 2064 .addExpr(Op1.getExpr())); 2065 return false; 2066 } 2067 int64_t Imm = Inst.getOperand(1).getImm(); 2068 // On RV32 the immediate here can either be a signed or an unsigned 2069 // 32-bit number. Sign extension has to be performed to ensure that Imm 2070 // represents the expected signed 64-bit number. 2071 if (!isRV64()) 2072 Imm = SignExtend64<32>(Imm); 2073 emitLoadImm(Reg, Imm, Out); 2074 return false; 2075 } 2076 case RISCV::PseudoLLA: 2077 emitLoadLocalAddress(Inst, IDLoc, Out); 2078 return false; 2079 case RISCV::PseudoLA: 2080 emitLoadAddress(Inst, IDLoc, Out); 2081 return false; 2082 case RISCV::PseudoLA_TLS_IE: 2083 emitLoadTLSIEAddress(Inst, IDLoc, Out); 2084 return false; 2085 case RISCV::PseudoLA_TLS_GD: 2086 emitLoadTLSGDAddress(Inst, IDLoc, Out); 2087 return false; 2088 case RISCV::PseudoLB: 2089 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out, /*HasTmpReg=*/false); 2090 return false; 2091 case RISCV::PseudoLBU: 2092 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out, /*HasTmpReg=*/false); 2093 return false; 2094 case RISCV::PseudoLH: 2095 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out, /*HasTmpReg=*/false); 2096 return false; 2097 case RISCV::PseudoLHU: 2098 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out, /*HasTmpReg=*/false); 2099 return false; 2100 case RISCV::PseudoLW: 2101 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out, /*HasTmpReg=*/false); 2102 return false; 2103 case RISCV::PseudoLWU: 2104 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out, /*HasTmpReg=*/false); 2105 return false; 2106 case RISCV::PseudoLD: 2107 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out, /*HasTmpReg=*/false); 2108 return false; 2109 case RISCV::PseudoFLW: 2110 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out, /*HasTmpReg=*/true); 2111 return false; 2112 case RISCV::PseudoFLD: 2113 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out, /*HasTmpReg=*/true); 2114 return false; 2115 case RISCV::PseudoSB: 2116 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out, /*HasTmpReg=*/true); 2117 return false; 2118 case RISCV::PseudoSH: 2119 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out, /*HasTmpReg=*/true); 2120 return false; 2121 case RISCV::PseudoSW: 2122 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out, /*HasTmpReg=*/true); 2123 return false; 2124 case RISCV::PseudoSD: 2125 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out, /*HasTmpReg=*/true); 2126 return false; 2127 case RISCV::PseudoFSW: 2128 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out, /*HasTmpReg=*/true); 2129 return false; 2130 case RISCV::PseudoFSD: 2131 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out, /*HasTmpReg=*/true); 2132 return false; 2133 case RISCV::PseudoAddTPRel: 2134 if (checkPseudoAddTPRel(Inst, Operands)) 2135 return true; 2136 break; 2137 } 2138 2139 emitToStreamer(Out, Inst); 2140 return false; 2141 } 2142 2143 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVAsmParser() { 2144 RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target()); 2145 RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target()); 2146 } 2147