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