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