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