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