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