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 if (!SysReg) 1181 SysReg = RISCVSysReg::lookupSysRegByAltName(Identifier); 1182 // Accept a named Sys Reg if the required features are present. 1183 if (SysReg) { 1184 if (!SysReg->haveRequiredFeatures(getSTI().getFeatureBits())) { 1185 Error(S, "system register use requires an option to be enabled"); 1186 return MatchOperand_ParseFail; 1187 } 1188 Operands.push_back(RISCVOperand::createSysReg( 1189 Identifier, S, SysReg->Encoding, isRV64())); 1190 return MatchOperand_Success; 1191 } 1192 1193 Twine Msg = "operand must be a valid system register name " 1194 "or an integer in the range"; 1195 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]"); 1196 return MatchOperand_ParseFail; 1197 } 1198 case AsmToken::Percent: { 1199 // Discard operand with modifier. 1200 Twine Msg = "immediate must be an integer in the range"; 1201 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]"); 1202 return MatchOperand_ParseFail; 1203 } 1204 } 1205 1206 return MatchOperand_NoMatch; 1207 } 1208 1209 OperandMatchResultTy RISCVAsmParser::parseImmediate(OperandVector &Operands) { 1210 SMLoc S = getLoc(); 1211 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1212 const MCExpr *Res; 1213 1214 switch (getLexer().getKind()) { 1215 default: 1216 return MatchOperand_NoMatch; 1217 case AsmToken::LParen: 1218 case AsmToken::Dot: 1219 case AsmToken::Minus: 1220 case AsmToken::Plus: 1221 case AsmToken::Exclaim: 1222 case AsmToken::Tilde: 1223 case AsmToken::Integer: 1224 case AsmToken::String: 1225 case AsmToken::Identifier: 1226 if (getParser().parseExpression(Res)) 1227 return MatchOperand_ParseFail; 1228 break; 1229 case AsmToken::Percent: 1230 return parseOperandWithModifier(Operands); 1231 } 1232 1233 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1234 return MatchOperand_Success; 1235 } 1236 1237 OperandMatchResultTy 1238 RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) { 1239 SMLoc S = getLoc(); 1240 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1241 1242 if (getLexer().getKind() != AsmToken::Percent) { 1243 Error(getLoc(), "expected '%' for operand modifier"); 1244 return MatchOperand_ParseFail; 1245 } 1246 1247 getParser().Lex(); // Eat '%' 1248 1249 if (getLexer().getKind() != AsmToken::Identifier) { 1250 Error(getLoc(), "expected valid identifier for operand modifier"); 1251 return MatchOperand_ParseFail; 1252 } 1253 StringRef Identifier = getParser().getTok().getIdentifier(); 1254 RISCVMCExpr::VariantKind VK = RISCVMCExpr::getVariantKindForName(Identifier); 1255 if (VK == RISCVMCExpr::VK_RISCV_Invalid) { 1256 Error(getLoc(), "unrecognized operand modifier"); 1257 return MatchOperand_ParseFail; 1258 } 1259 1260 getParser().Lex(); // Eat the identifier 1261 if (getLexer().getKind() != AsmToken::LParen) { 1262 Error(getLoc(), "expected '('"); 1263 return MatchOperand_ParseFail; 1264 } 1265 getParser().Lex(); // Eat '(' 1266 1267 const MCExpr *SubExpr; 1268 if (getParser().parseParenExpression(SubExpr, E)) { 1269 return MatchOperand_ParseFail; 1270 } 1271 1272 const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, VK, getContext()); 1273 Operands.push_back(RISCVOperand::createImm(ModExpr, S, E, isRV64())); 1274 return MatchOperand_Success; 1275 } 1276 1277 OperandMatchResultTy RISCVAsmParser::parseBareSymbol(OperandVector &Operands) { 1278 SMLoc S = getLoc(); 1279 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1280 const MCExpr *Res; 1281 1282 if (getLexer().getKind() != AsmToken::Identifier) 1283 return MatchOperand_NoMatch; 1284 1285 StringRef Identifier; 1286 AsmToken Tok = getLexer().getTok(); 1287 1288 if (getParser().parseIdentifier(Identifier)) 1289 return MatchOperand_ParseFail; 1290 1291 if (Identifier.consume_back("@plt")) { 1292 Error(getLoc(), "'@plt' operand not valid for instruction"); 1293 return MatchOperand_ParseFail; 1294 } 1295 1296 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); 1297 1298 if (Sym->isVariable()) { 1299 const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false); 1300 if (!isa<MCSymbolRefExpr>(V)) { 1301 getLexer().UnLex(Tok); // Put back if it's not a bare symbol. 1302 return MatchOperand_NoMatch; 1303 } 1304 Res = V; 1305 } else 1306 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1307 1308 MCBinaryExpr::Opcode Opcode; 1309 switch (getLexer().getKind()) { 1310 default: 1311 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1312 return MatchOperand_Success; 1313 case AsmToken::Plus: 1314 Opcode = MCBinaryExpr::Add; 1315 break; 1316 case AsmToken::Minus: 1317 Opcode = MCBinaryExpr::Sub; 1318 break; 1319 } 1320 1321 const MCExpr *Expr; 1322 if (getParser().parseExpression(Expr)) 1323 return MatchOperand_ParseFail; 1324 Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext()); 1325 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1326 return MatchOperand_Success; 1327 } 1328 1329 OperandMatchResultTy RISCVAsmParser::parseCallSymbol(OperandVector &Operands) { 1330 SMLoc S = getLoc(); 1331 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1332 const MCExpr *Res; 1333 1334 if (getLexer().getKind() != AsmToken::Identifier) 1335 return MatchOperand_NoMatch; 1336 1337 // Avoid parsing the register in `call rd, foo` as a call symbol. 1338 if (getLexer().peekTok().getKind() != AsmToken::EndOfStatement) 1339 return MatchOperand_NoMatch; 1340 1341 StringRef Identifier; 1342 if (getParser().parseIdentifier(Identifier)) 1343 return MatchOperand_ParseFail; 1344 1345 RISCVMCExpr::VariantKind Kind = RISCVMCExpr::VK_RISCV_CALL; 1346 if (Identifier.consume_back("@plt")) 1347 Kind = RISCVMCExpr::VK_RISCV_CALL_PLT; 1348 1349 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); 1350 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1351 Res = RISCVMCExpr::create(Res, Kind, getContext()); 1352 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1353 return MatchOperand_Success; 1354 } 1355 1356 OperandMatchResultTy 1357 RISCVAsmParser::parsePseudoJumpSymbol(OperandVector &Operands) { 1358 SMLoc S = getLoc(); 1359 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1360 const MCExpr *Res; 1361 1362 if (getParser().parseExpression(Res)) 1363 return MatchOperand_ParseFail; 1364 1365 if (Res->getKind() != MCExpr::ExprKind::SymbolRef || 1366 cast<MCSymbolRefExpr>(Res)->getKind() == 1367 MCSymbolRefExpr::VariantKind::VK_PLT) { 1368 Error(S, "operand must be a valid jump target"); 1369 return MatchOperand_ParseFail; 1370 } 1371 1372 Res = RISCVMCExpr::create(Res, RISCVMCExpr::VK_RISCV_CALL, getContext()); 1373 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1374 return MatchOperand_Success; 1375 } 1376 1377 OperandMatchResultTy RISCVAsmParser::parseJALOffset(OperandVector &Operands) { 1378 // Parsing jal operands is fiddly due to the `jal foo` and `jal ra, foo` 1379 // both being acceptable forms. When parsing `jal ra, foo` this function 1380 // will be called for the `ra` register operand in an attempt to match the 1381 // single-operand alias. parseJALOffset must fail for this case. It would 1382 // seem logical to try parse the operand using parseImmediate and return 1383 // NoMatch if the next token is a comma (meaning we must be parsing a jal in 1384 // the second form rather than the first). We can't do this as there's no 1385 // way of rewinding the lexer state. Instead, return NoMatch if this operand 1386 // is an identifier and is followed by a comma. 1387 if (getLexer().is(AsmToken::Identifier) && 1388 getLexer().peekTok().is(AsmToken::Comma)) 1389 return MatchOperand_NoMatch; 1390 1391 return parseImmediate(Operands); 1392 } 1393 1394 OperandMatchResultTy 1395 RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) { 1396 if (getLexer().isNot(AsmToken::LParen)) { 1397 Error(getLoc(), "expected '('"); 1398 return MatchOperand_ParseFail; 1399 } 1400 1401 getParser().Lex(); // Eat '(' 1402 Operands.push_back(RISCVOperand::createToken("(", getLoc(), isRV64())); 1403 1404 if (parseRegister(Operands) != MatchOperand_Success) { 1405 Error(getLoc(), "expected register"); 1406 return MatchOperand_ParseFail; 1407 } 1408 1409 if (getLexer().isNot(AsmToken::RParen)) { 1410 Error(getLoc(), "expected ')'"); 1411 return MatchOperand_ParseFail; 1412 } 1413 1414 getParser().Lex(); // Eat ')' 1415 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64())); 1416 1417 return MatchOperand_Success; 1418 } 1419 1420 OperandMatchResultTy RISCVAsmParser::parseAtomicMemOp(OperandVector &Operands) { 1421 // Atomic operations such as lr.w, sc.w, and amo*.w accept a "memory operand" 1422 // as one of their register operands, such as `(a0)`. This just denotes that 1423 // the register (in this case `a0`) contains a memory address. 1424 // 1425 // Normally, we would be able to parse these by putting the parens into the 1426 // instruction string. However, GNU as also accepts a zero-offset memory 1427 // operand (such as `0(a0)`), and ignores the 0. Normally this would be parsed 1428 // with parseImmediate followed by parseMemOpBaseReg, but these instructions 1429 // do not accept an immediate operand, and we do not want to add a "dummy" 1430 // operand that is silently dropped. 1431 // 1432 // Instead, we use this custom parser. This will: allow (and discard) an 1433 // offset if it is zero; require (and discard) parentheses; and add only the 1434 // parsed register operand to `Operands`. 1435 // 1436 // These operands are printed with RISCVInstPrinter::printAtomicMemOp, which 1437 // will only print the register surrounded by parentheses (which GNU as also 1438 // uses as its canonical representation for these operands). 1439 std::unique_ptr<RISCVOperand> OptionalImmOp; 1440 1441 if (getLexer().isNot(AsmToken::LParen)) { 1442 // Parse an Integer token. We do not accept arbritrary constant expressions 1443 // in the offset field (because they may include parens, which complicates 1444 // parsing a lot). 1445 int64_t ImmVal; 1446 SMLoc ImmStart = getLoc(); 1447 if (getParser().parseIntToken(ImmVal, 1448 "expected '(' or optional integer offset")) 1449 return MatchOperand_ParseFail; 1450 1451 // Create a RISCVOperand for checking later (so the error messages are 1452 // nicer), but we don't add it to Operands. 1453 SMLoc ImmEnd = getLoc(); 1454 OptionalImmOp = 1455 RISCVOperand::createImm(MCConstantExpr::create(ImmVal, getContext()), 1456 ImmStart, ImmEnd, isRV64()); 1457 } 1458 1459 if (getLexer().isNot(AsmToken::LParen)) { 1460 Error(getLoc(), OptionalImmOp ? "expected '(' after optional integer offset" 1461 : "expected '(' or optional integer offset"); 1462 return MatchOperand_ParseFail; 1463 } 1464 getParser().Lex(); // Eat '(' 1465 1466 if (parseRegister(Operands) != MatchOperand_Success) { 1467 Error(getLoc(), "expected register"); 1468 return MatchOperand_ParseFail; 1469 } 1470 1471 if (getLexer().isNot(AsmToken::RParen)) { 1472 Error(getLoc(), "expected ')'"); 1473 return MatchOperand_ParseFail; 1474 } 1475 getParser().Lex(); // Eat ')' 1476 1477 // Deferred Handling of non-zero offsets. This makes the error messages nicer. 1478 if (OptionalImmOp && !OptionalImmOp->isImmZero()) { 1479 Error(OptionalImmOp->getStartLoc(), "optional integer offset must be 0", 1480 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc())); 1481 return MatchOperand_ParseFail; 1482 } 1483 1484 return MatchOperand_Success; 1485 } 1486 1487 /// Looks at a token type and creates the relevant operand from this 1488 /// information, adding to Operands. If operand was parsed, returns false, else 1489 /// true. 1490 bool RISCVAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { 1491 // Check if the current operand has a custom associated parser, if so, try to 1492 // custom parse the operand, or fallback to the general approach. 1493 OperandMatchResultTy Result = 1494 MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true); 1495 if (Result == MatchOperand_Success) 1496 return false; 1497 if (Result == MatchOperand_ParseFail) 1498 return true; 1499 1500 // Attempt to parse token as a register. 1501 if (parseRegister(Operands, true) == MatchOperand_Success) 1502 return false; 1503 1504 // Attempt to parse token as an immediate 1505 if (parseImmediate(Operands) == MatchOperand_Success) { 1506 // Parse memory base register if present 1507 if (getLexer().is(AsmToken::LParen)) 1508 return parseMemOpBaseReg(Operands) != MatchOperand_Success; 1509 return false; 1510 } 1511 1512 // Finally we have exhausted all options and must declare defeat. 1513 Error(getLoc(), "unknown operand"); 1514 return true; 1515 } 1516 1517 bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info, 1518 StringRef Name, SMLoc NameLoc, 1519 OperandVector &Operands) { 1520 // Ensure that if the instruction occurs when relaxation is enabled, 1521 // relocations are forced for the file. Ideally this would be done when there 1522 // is enough information to reliably determine if the instruction itself may 1523 // cause relaxations. Unfortunately instruction processing stage occurs in the 1524 // same pass as relocation emission, so it's too late to set a 'sticky bit' 1525 // for the entire file. 1526 if (getSTI().getFeatureBits()[RISCV::FeatureRelax]) { 1527 auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr(); 1528 if (Assembler != nullptr) { 1529 RISCVAsmBackend &MAB = 1530 static_cast<RISCVAsmBackend &>(Assembler->getBackend()); 1531 MAB.setForceRelocs(); 1532 } 1533 } 1534 1535 // First operand is token for instruction 1536 Operands.push_back(RISCVOperand::createToken(Name, NameLoc, isRV64())); 1537 1538 // If there are no more operands, then finish 1539 if (getLexer().is(AsmToken::EndOfStatement)) 1540 return false; 1541 1542 // Parse first operand 1543 if (parseOperand(Operands, Name)) 1544 return true; 1545 1546 // Parse until end of statement, consuming commas between operands 1547 unsigned OperandIdx = 1; 1548 while (getLexer().is(AsmToken::Comma)) { 1549 // Consume comma token 1550 getLexer().Lex(); 1551 1552 // Parse next operand 1553 if (parseOperand(Operands, Name)) 1554 return true; 1555 1556 ++OperandIdx; 1557 } 1558 1559 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1560 SMLoc Loc = getLexer().getLoc(); 1561 getParser().eatToEndOfStatement(); 1562 return Error(Loc, "unexpected token"); 1563 } 1564 1565 getParser().Lex(); // Consume the EndOfStatement. 1566 return false; 1567 } 1568 1569 bool RISCVAsmParser::classifySymbolRef(const MCExpr *Expr, 1570 RISCVMCExpr::VariantKind &Kind, 1571 int64_t &Addend) { 1572 Kind = RISCVMCExpr::VK_RISCV_None; 1573 Addend = 0; 1574 1575 if (const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) { 1576 Kind = RE->getKind(); 1577 Expr = RE->getSubExpr(); 1578 } 1579 1580 // It's a simple symbol reference or constant with no addend. 1581 if (isa<MCConstantExpr>(Expr) || isa<MCSymbolRefExpr>(Expr)) 1582 return true; 1583 1584 const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr); 1585 if (!BE) 1586 return false; 1587 1588 if (!isa<MCSymbolRefExpr>(BE->getLHS())) 1589 return false; 1590 1591 if (BE->getOpcode() != MCBinaryExpr::Add && 1592 BE->getOpcode() != MCBinaryExpr::Sub) 1593 return false; 1594 1595 // We are able to support the subtraction of two symbol references 1596 if (BE->getOpcode() == MCBinaryExpr::Sub && 1597 isa<MCSymbolRefExpr>(BE->getRHS())) 1598 return true; 1599 1600 // See if the addend is a constant, otherwise there's more going 1601 // on here than we can deal with. 1602 auto AddendExpr = dyn_cast<MCConstantExpr>(BE->getRHS()); 1603 if (!AddendExpr) 1604 return false; 1605 1606 Addend = AddendExpr->getValue(); 1607 if (BE->getOpcode() == MCBinaryExpr::Sub) 1608 Addend = -Addend; 1609 1610 // It's some symbol reference + a constant addend 1611 return Kind != RISCVMCExpr::VK_RISCV_Invalid; 1612 } 1613 1614 bool RISCVAsmParser::ParseDirective(AsmToken DirectiveID) { 1615 // This returns false if this function recognizes the directive 1616 // regardless of whether it is successfully handles or reports an 1617 // error. Otherwise it returns true to give the generic parser a 1618 // chance at recognizing it. 1619 StringRef IDVal = DirectiveID.getString(); 1620 1621 if (IDVal == ".option") 1622 return parseDirectiveOption(); 1623 else if (IDVal == ".attribute") 1624 return parseDirectiveAttribute(); 1625 1626 return true; 1627 } 1628 1629 bool RISCVAsmParser::parseDirectiveOption() { 1630 MCAsmParser &Parser = getParser(); 1631 // Get the option token. 1632 AsmToken Tok = Parser.getTok(); 1633 // At the moment only identifiers are supported. 1634 if (Tok.isNot(AsmToken::Identifier)) 1635 return Error(Parser.getTok().getLoc(), 1636 "unexpected token, expected identifier"); 1637 1638 StringRef Option = Tok.getIdentifier(); 1639 1640 if (Option == "push") { 1641 getTargetStreamer().emitDirectiveOptionPush(); 1642 1643 Parser.Lex(); 1644 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1645 return Error(Parser.getTok().getLoc(), 1646 "unexpected token, expected end of statement"); 1647 1648 pushFeatureBits(); 1649 return false; 1650 } 1651 1652 if (Option == "pop") { 1653 SMLoc StartLoc = Parser.getTok().getLoc(); 1654 getTargetStreamer().emitDirectiveOptionPop(); 1655 1656 Parser.Lex(); 1657 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1658 return Error(Parser.getTok().getLoc(), 1659 "unexpected token, expected end of statement"); 1660 1661 if (popFeatureBits()) 1662 return Error(StartLoc, ".option pop with no .option push"); 1663 1664 return false; 1665 } 1666 1667 if (Option == "rvc") { 1668 getTargetStreamer().emitDirectiveOptionRVC(); 1669 1670 Parser.Lex(); 1671 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1672 return Error(Parser.getTok().getLoc(), 1673 "unexpected token, expected end of statement"); 1674 1675 setFeatureBits(RISCV::FeatureStdExtC, "c"); 1676 return false; 1677 } 1678 1679 if (Option == "norvc") { 1680 getTargetStreamer().emitDirectiveOptionNoRVC(); 1681 1682 Parser.Lex(); 1683 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1684 return Error(Parser.getTok().getLoc(), 1685 "unexpected token, expected end of statement"); 1686 1687 clearFeatureBits(RISCV::FeatureStdExtC, "c"); 1688 return false; 1689 } 1690 1691 if (Option == "pic") { 1692 getTargetStreamer().emitDirectiveOptionPIC(); 1693 1694 Parser.Lex(); 1695 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1696 return Error(Parser.getTok().getLoc(), 1697 "unexpected token, expected end of statement"); 1698 1699 ParserOptions.IsPicEnabled = true; 1700 return false; 1701 } 1702 1703 if (Option == "nopic") { 1704 getTargetStreamer().emitDirectiveOptionNoPIC(); 1705 1706 Parser.Lex(); 1707 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1708 return Error(Parser.getTok().getLoc(), 1709 "unexpected token, expected end of statement"); 1710 1711 ParserOptions.IsPicEnabled = false; 1712 return false; 1713 } 1714 1715 if (Option == "relax") { 1716 getTargetStreamer().emitDirectiveOptionRelax(); 1717 1718 Parser.Lex(); 1719 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1720 return Error(Parser.getTok().getLoc(), 1721 "unexpected token, expected end of statement"); 1722 1723 setFeatureBits(RISCV::FeatureRelax, "relax"); 1724 return false; 1725 } 1726 1727 if (Option == "norelax") { 1728 getTargetStreamer().emitDirectiveOptionNoRelax(); 1729 1730 Parser.Lex(); 1731 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1732 return Error(Parser.getTok().getLoc(), 1733 "unexpected token, expected end of statement"); 1734 1735 clearFeatureBits(RISCV::FeatureRelax, "relax"); 1736 return false; 1737 } 1738 1739 // Unknown option. 1740 Warning(Parser.getTok().getLoc(), 1741 "unknown option, expected 'push', 'pop', 'rvc', 'norvc', 'relax' or " 1742 "'norelax'"); 1743 Parser.eatToEndOfStatement(); 1744 return false; 1745 } 1746 1747 /// parseDirectiveAttribute 1748 /// ::= .attribute expression ',' ( expression | "string" ) 1749 /// ::= .attribute identifier ',' ( expression | "string" ) 1750 bool RISCVAsmParser::parseDirectiveAttribute() { 1751 MCAsmParser &Parser = getParser(); 1752 int64_t Tag; 1753 SMLoc TagLoc; 1754 TagLoc = Parser.getTok().getLoc(); 1755 if (Parser.getTok().is(AsmToken::Identifier)) { 1756 StringRef Name = Parser.getTok().getIdentifier(); 1757 Optional<unsigned> Ret = 1758 ELFAttrs::attrTypeFromString(Name, RISCVAttrs::RISCVAttributeTags); 1759 if (!Ret.hasValue()) { 1760 Error(TagLoc, "attribute name not recognised: " + Name); 1761 return false; 1762 } 1763 Tag = Ret.getValue(); 1764 Parser.Lex(); 1765 } else { 1766 const MCExpr *AttrExpr; 1767 1768 TagLoc = Parser.getTok().getLoc(); 1769 if (Parser.parseExpression(AttrExpr)) 1770 return true; 1771 1772 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr); 1773 if (check(!CE, TagLoc, "expected numeric constant")) 1774 return true; 1775 1776 Tag = CE->getValue(); 1777 } 1778 1779 if (Parser.parseToken(AsmToken::Comma, "comma expected")) 1780 return true; 1781 1782 StringRef StringValue; 1783 int64_t IntegerValue = 0; 1784 bool IsIntegerValue = true; 1785 1786 // RISC-V attributes have a string value if the tag number is odd 1787 // and an integer value if the tag number is even. 1788 if (Tag % 2) 1789 IsIntegerValue = false; 1790 1791 SMLoc ValueExprLoc = Parser.getTok().getLoc(); 1792 if (IsIntegerValue) { 1793 const MCExpr *ValueExpr; 1794 if (Parser.parseExpression(ValueExpr)) 1795 return true; 1796 1797 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr); 1798 if (!CE) 1799 return Error(ValueExprLoc, "expected numeric constant"); 1800 IntegerValue = CE->getValue(); 1801 } else { 1802 if (Parser.getTok().isNot(AsmToken::String)) 1803 return Error(Parser.getTok().getLoc(), "expected string constant"); 1804 1805 StringValue = Parser.getTok().getStringContents(); 1806 Parser.Lex(); 1807 } 1808 1809 if (Parser.parseToken(AsmToken::EndOfStatement, 1810 "unexpected token in '.attribute' directive")) 1811 return true; 1812 1813 if (Tag == RISCVAttrs::ARCH) { 1814 StringRef Arch = StringValue; 1815 if (Arch.consume_front("rv32")) 1816 clearFeatureBits(RISCV::Feature64Bit, "64bit"); 1817 else if (Arch.consume_front("rv64")) 1818 setFeatureBits(RISCV::Feature64Bit, "64bit"); 1819 else 1820 return Error(ValueExprLoc, "bad arch string " + Arch); 1821 1822 while (!Arch.empty()) { 1823 if (Arch[0] == 'i') 1824 clearFeatureBits(RISCV::FeatureRV32E, "e"); 1825 else if (Arch[0] == 'e') 1826 setFeatureBits(RISCV::FeatureRV32E, "e"); 1827 else if (Arch[0] == 'g') { 1828 clearFeatureBits(RISCV::FeatureRV32E, "e"); 1829 setFeatureBits(RISCV::FeatureStdExtM, "m"); 1830 setFeatureBits(RISCV::FeatureStdExtA, "a"); 1831 setFeatureBits(RISCV::FeatureStdExtF, "f"); 1832 setFeatureBits(RISCV::FeatureStdExtD, "d"); 1833 } else if (Arch[0] == 'm') 1834 setFeatureBits(RISCV::FeatureStdExtM, "m"); 1835 else if (Arch[0] == 'a') 1836 setFeatureBits(RISCV::FeatureStdExtA, "a"); 1837 else if (Arch[0] == 'f') 1838 setFeatureBits(RISCV::FeatureStdExtF, "f"); 1839 else if (Arch[0] == 'd') { 1840 setFeatureBits(RISCV::FeatureStdExtF, "f"); 1841 setFeatureBits(RISCV::FeatureStdExtD, "d"); 1842 } else if (Arch[0] == 'c') { 1843 setFeatureBits(RISCV::FeatureStdExtC, "c"); 1844 } else 1845 return Error(ValueExprLoc, "bad arch string " + Arch); 1846 1847 Arch = Arch.drop_front(1); 1848 int major = 0; 1849 int minor = 0; 1850 Arch.consumeInteger(10, major); 1851 Arch.consume_front("p"); 1852 Arch.consumeInteger(10, minor); 1853 if (major != 0 || minor != 0) { 1854 Arch = Arch.drop_until([](char c) { return c == '_' || c == '"'; }); 1855 Arch = Arch.drop_while([](char c) { return c == '_'; }); 1856 } 1857 } 1858 } 1859 1860 if (IsIntegerValue) 1861 getTargetStreamer().emitAttribute(Tag, IntegerValue); 1862 else { 1863 if (Tag != RISCVAttrs::ARCH) { 1864 getTargetStreamer().emitTextAttribute(Tag, StringValue); 1865 } else { 1866 std::string formalArchStr = "rv32"; 1867 if (getFeatureBits(RISCV::Feature64Bit)) 1868 formalArchStr = "rv64"; 1869 if (getFeatureBits(RISCV::FeatureRV32E)) 1870 formalArchStr = (Twine(formalArchStr) + "e1p9").str(); 1871 else 1872 formalArchStr = (Twine(formalArchStr) + "i2p0").str(); 1873 1874 if (getFeatureBits(RISCV::FeatureStdExtM)) 1875 formalArchStr = (Twine(formalArchStr) + "_m2p0").str(); 1876 if (getFeatureBits(RISCV::FeatureStdExtA)) 1877 formalArchStr = (Twine(formalArchStr) + "_a2p0").str(); 1878 if (getFeatureBits(RISCV::FeatureStdExtF)) 1879 formalArchStr = (Twine(formalArchStr) + "_f2p0").str(); 1880 if (getFeatureBits(RISCV::FeatureStdExtD)) 1881 formalArchStr = (Twine(formalArchStr) + "_d2p0").str(); 1882 if (getFeatureBits(RISCV::FeatureStdExtC)) 1883 formalArchStr = (Twine(formalArchStr) + "_c2p0").str(); 1884 1885 getTargetStreamer().emitTextAttribute(Tag, formalArchStr); 1886 } 1887 } 1888 1889 return false; 1890 } 1891 1892 void RISCVAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) { 1893 MCInst CInst; 1894 bool Res = compressInst(CInst, Inst, getSTI(), S.getContext()); 1895 if (Res) 1896 ++RISCVNumInstrsCompressed; 1897 S.emitInstruction((Res ? CInst : Inst), getSTI()); 1898 } 1899 1900 void RISCVAsmParser::emitLoadImm(Register DestReg, int64_t Value, 1901 MCStreamer &Out) { 1902 RISCVMatInt::InstSeq Seq; 1903 RISCVMatInt::generateInstSeq(Value, isRV64(), Seq); 1904 1905 Register SrcReg = RISCV::X0; 1906 for (RISCVMatInt::Inst &Inst : Seq) { 1907 if (Inst.Opc == RISCV::LUI) { 1908 emitToStreamer( 1909 Out, MCInstBuilder(RISCV::LUI).addReg(DestReg).addImm(Inst.Imm)); 1910 } else { 1911 emitToStreamer( 1912 Out, MCInstBuilder(Inst.Opc).addReg(DestReg).addReg(SrcReg).addImm( 1913 Inst.Imm)); 1914 } 1915 1916 // Only the first instruction has X0 as its source. 1917 SrcReg = DestReg; 1918 } 1919 } 1920 1921 void RISCVAsmParser::emitAuipcInstPair(MCOperand DestReg, MCOperand TmpReg, 1922 const MCExpr *Symbol, 1923 RISCVMCExpr::VariantKind VKHi, 1924 unsigned SecondOpcode, SMLoc IDLoc, 1925 MCStreamer &Out) { 1926 // A pair of instructions for PC-relative addressing; expands to 1927 // TmpLabel: AUIPC TmpReg, VKHi(symbol) 1928 // OP DestReg, TmpReg, %pcrel_lo(TmpLabel) 1929 MCContext &Ctx = getContext(); 1930 1931 MCSymbol *TmpLabel = Ctx.createTempSymbol( 1932 "pcrel_hi", /* AlwaysAddSuffix */ true, /* CanBeUnnamed */ false); 1933 Out.emitLabel(TmpLabel); 1934 1935 const RISCVMCExpr *SymbolHi = RISCVMCExpr::create(Symbol, VKHi, Ctx); 1936 emitToStreamer( 1937 Out, MCInstBuilder(RISCV::AUIPC).addOperand(TmpReg).addExpr(SymbolHi)); 1938 1939 const MCExpr *RefToLinkTmpLabel = 1940 RISCVMCExpr::create(MCSymbolRefExpr::create(TmpLabel, Ctx), 1941 RISCVMCExpr::VK_RISCV_PCREL_LO, Ctx); 1942 1943 emitToStreamer(Out, MCInstBuilder(SecondOpcode) 1944 .addOperand(DestReg) 1945 .addOperand(TmpReg) 1946 .addExpr(RefToLinkTmpLabel)); 1947 } 1948 1949 void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, 1950 MCStreamer &Out) { 1951 // The load local address pseudo-instruction "lla" is used in PC-relative 1952 // addressing of local symbols: 1953 // lla rdest, symbol 1954 // expands to 1955 // TmpLabel: AUIPC rdest, %pcrel_hi(symbol) 1956 // ADDI rdest, rdest, %pcrel_lo(TmpLabel) 1957 MCOperand DestReg = Inst.getOperand(0); 1958 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 1959 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI, 1960 RISCV::ADDI, IDLoc, Out); 1961 } 1962 1963 void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc, 1964 MCStreamer &Out) { 1965 // The load address pseudo-instruction "la" is used in PC-relative and 1966 // GOT-indirect addressing of global symbols: 1967 // la rdest, symbol 1968 // expands to either (for non-PIC) 1969 // TmpLabel: AUIPC rdest, %pcrel_hi(symbol) 1970 // ADDI rdest, rdest, %pcrel_lo(TmpLabel) 1971 // or (for PIC) 1972 // TmpLabel: AUIPC rdest, %got_pcrel_hi(symbol) 1973 // Lx rdest, %pcrel_lo(TmpLabel)(rdest) 1974 MCOperand DestReg = Inst.getOperand(0); 1975 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 1976 unsigned SecondOpcode; 1977 RISCVMCExpr::VariantKind VKHi; 1978 if (ParserOptions.IsPicEnabled) { 1979 SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW; 1980 VKHi = RISCVMCExpr::VK_RISCV_GOT_HI; 1981 } else { 1982 SecondOpcode = RISCV::ADDI; 1983 VKHi = RISCVMCExpr::VK_RISCV_PCREL_HI; 1984 } 1985 emitAuipcInstPair(DestReg, DestReg, Symbol, VKHi, SecondOpcode, IDLoc, Out); 1986 } 1987 1988 void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc, 1989 MCStreamer &Out) { 1990 // The load TLS IE address pseudo-instruction "la.tls.ie" is used in 1991 // initial-exec TLS model addressing of global symbols: 1992 // la.tls.ie rdest, symbol 1993 // expands to 1994 // TmpLabel: AUIPC rdest, %tls_ie_pcrel_hi(symbol) 1995 // Lx rdest, %pcrel_lo(TmpLabel)(rdest) 1996 MCOperand DestReg = Inst.getOperand(0); 1997 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 1998 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW; 1999 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_TLS_GOT_HI, 2000 SecondOpcode, IDLoc, Out); 2001 } 2002 2003 void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, 2004 MCStreamer &Out) { 2005 // The load TLS GD address pseudo-instruction "la.tls.gd" is used in 2006 // global-dynamic TLS model addressing of global symbols: 2007 // la.tls.gd rdest, symbol 2008 // expands to 2009 // TmpLabel: AUIPC rdest, %tls_gd_pcrel_hi(symbol) 2010 // ADDI rdest, rdest, %pcrel_lo(TmpLabel) 2011 MCOperand DestReg = Inst.getOperand(0); 2012 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 2013 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_TLS_GD_HI, 2014 RISCV::ADDI, IDLoc, Out); 2015 } 2016 2017 void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode, 2018 SMLoc IDLoc, MCStreamer &Out, 2019 bool HasTmpReg) { 2020 // The load/store pseudo-instruction does a pc-relative load with 2021 // a symbol. 2022 // 2023 // The expansion looks like this 2024 // 2025 // TmpLabel: AUIPC tmp, %pcrel_hi(symbol) 2026 // [S|L]X rd, %pcrel_lo(TmpLabel)(tmp) 2027 MCOperand DestReg = Inst.getOperand(0); 2028 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1; 2029 unsigned TmpRegOpIdx = HasTmpReg ? 1 : 0; 2030 MCOperand TmpReg = Inst.getOperand(TmpRegOpIdx); 2031 const MCExpr *Symbol = Inst.getOperand(SymbolOpIdx).getExpr(); 2032 emitAuipcInstPair(DestReg, TmpReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI, 2033 Opcode, IDLoc, Out); 2034 } 2035 2036 bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst, 2037 OperandVector &Operands) { 2038 assert(Inst.getOpcode() == RISCV::PseudoAddTPRel && "Invalid instruction"); 2039 assert(Inst.getOperand(2).isReg() && "Unexpected second operand kind"); 2040 if (Inst.getOperand(2).getReg() != RISCV::X4) { 2041 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc(); 2042 return Error(ErrorLoc, "the second input operand must be tp/x4 when using " 2043 "%tprel_add modifier"); 2044 } 2045 2046 return false; 2047 } 2048 2049 bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 2050 OperandVector &Operands, 2051 MCStreamer &Out) { 2052 Inst.setLoc(IDLoc); 2053 2054 switch (Inst.getOpcode()) { 2055 default: 2056 break; 2057 case RISCV::PseudoLI: { 2058 Register Reg = Inst.getOperand(0).getReg(); 2059 const MCOperand &Op1 = Inst.getOperand(1); 2060 if (Op1.isExpr()) { 2061 // We must have li reg, %lo(sym) or li reg, %pcrel_lo(sym) or similar. 2062 // Just convert to an addi. This allows compatibility with gas. 2063 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI) 2064 .addReg(Reg) 2065 .addReg(RISCV::X0) 2066 .addExpr(Op1.getExpr())); 2067 return false; 2068 } 2069 int64_t Imm = Inst.getOperand(1).getImm(); 2070 // On RV32 the immediate here can either be a signed or an unsigned 2071 // 32-bit number. Sign extension has to be performed to ensure that Imm 2072 // represents the expected signed 64-bit number. 2073 if (!isRV64()) 2074 Imm = SignExtend64<32>(Imm); 2075 emitLoadImm(Reg, Imm, Out); 2076 return false; 2077 } 2078 case RISCV::PseudoLLA: 2079 emitLoadLocalAddress(Inst, IDLoc, Out); 2080 return false; 2081 case RISCV::PseudoLA: 2082 emitLoadAddress(Inst, IDLoc, Out); 2083 return false; 2084 case RISCV::PseudoLA_TLS_IE: 2085 emitLoadTLSIEAddress(Inst, IDLoc, Out); 2086 return false; 2087 case RISCV::PseudoLA_TLS_GD: 2088 emitLoadTLSGDAddress(Inst, IDLoc, Out); 2089 return false; 2090 case RISCV::PseudoLB: 2091 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out, /*HasTmpReg=*/false); 2092 return false; 2093 case RISCV::PseudoLBU: 2094 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out, /*HasTmpReg=*/false); 2095 return false; 2096 case RISCV::PseudoLH: 2097 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out, /*HasTmpReg=*/false); 2098 return false; 2099 case RISCV::PseudoLHU: 2100 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out, /*HasTmpReg=*/false); 2101 return false; 2102 case RISCV::PseudoLW: 2103 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out, /*HasTmpReg=*/false); 2104 return false; 2105 case RISCV::PseudoLWU: 2106 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out, /*HasTmpReg=*/false); 2107 return false; 2108 case RISCV::PseudoLD: 2109 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out, /*HasTmpReg=*/false); 2110 return false; 2111 case RISCV::PseudoFLW: 2112 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out, /*HasTmpReg=*/true); 2113 return false; 2114 case RISCV::PseudoFLD: 2115 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out, /*HasTmpReg=*/true); 2116 return false; 2117 case RISCV::PseudoSB: 2118 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out, /*HasTmpReg=*/true); 2119 return false; 2120 case RISCV::PseudoSH: 2121 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out, /*HasTmpReg=*/true); 2122 return false; 2123 case RISCV::PseudoSW: 2124 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out, /*HasTmpReg=*/true); 2125 return false; 2126 case RISCV::PseudoSD: 2127 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out, /*HasTmpReg=*/true); 2128 return false; 2129 case RISCV::PseudoFSW: 2130 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out, /*HasTmpReg=*/true); 2131 return false; 2132 case RISCV::PseudoFSD: 2133 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out, /*HasTmpReg=*/true); 2134 return false; 2135 case RISCV::PseudoAddTPRel: 2136 if (checkPseudoAddTPRel(Inst, Operands)) 2137 return true; 2138 break; 2139 } 2140 2141 emitToStreamer(Out, Inst); 2142 return false; 2143 } 2144 2145 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVAsmParser() { 2146 RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target()); 2147 RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target()); 2148 } 2149