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