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