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