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 parseAtomicMemOp(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 break; 1617 case AsmToken::Minus: 1618 Opcode = MCBinaryExpr::Sub; 1619 break; 1620 } 1621 1622 const MCExpr *Expr; 1623 if (getParser().parseExpression(Expr, E)) 1624 return MatchOperand_ParseFail; 1625 Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext()); 1626 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1627 return MatchOperand_Success; 1628 } 1629 1630 OperandMatchResultTy RISCVAsmParser::parseCallSymbol(OperandVector &Operands) { 1631 SMLoc S = getLoc(); 1632 const MCExpr *Res; 1633 1634 if (getLexer().getKind() != AsmToken::Identifier) 1635 return MatchOperand_NoMatch; 1636 1637 // Avoid parsing the register in `call rd, foo` as a call symbol. 1638 if (getLexer().peekTok().getKind() != AsmToken::EndOfStatement) 1639 return MatchOperand_NoMatch; 1640 1641 StringRef Identifier; 1642 if (getParser().parseIdentifier(Identifier)) 1643 return MatchOperand_ParseFail; 1644 1645 SMLoc E = SMLoc::getFromPointer(S.getPointer() + Identifier.size()); 1646 1647 RISCVMCExpr::VariantKind Kind = RISCVMCExpr::VK_RISCV_CALL; 1648 if (Identifier.consume_back("@plt")) 1649 Kind = RISCVMCExpr::VK_RISCV_CALL_PLT; 1650 1651 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); 1652 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1653 Res = RISCVMCExpr::create(Res, Kind, getContext()); 1654 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1655 return MatchOperand_Success; 1656 } 1657 1658 OperandMatchResultTy 1659 RISCVAsmParser::parsePseudoJumpSymbol(OperandVector &Operands) { 1660 SMLoc S = getLoc(); 1661 SMLoc E; 1662 const MCExpr *Res; 1663 1664 if (getParser().parseExpression(Res, E)) 1665 return MatchOperand_ParseFail; 1666 1667 if (Res->getKind() != MCExpr::ExprKind::SymbolRef || 1668 cast<MCSymbolRefExpr>(Res)->getKind() == 1669 MCSymbolRefExpr::VariantKind::VK_PLT) { 1670 Error(S, "operand must be a valid jump target"); 1671 return MatchOperand_ParseFail; 1672 } 1673 1674 Res = RISCVMCExpr::create(Res, RISCVMCExpr::VK_RISCV_CALL, getContext()); 1675 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1676 return MatchOperand_Success; 1677 } 1678 1679 OperandMatchResultTy RISCVAsmParser::parseJALOffset(OperandVector &Operands) { 1680 // Parsing jal operands is fiddly due to the `jal foo` and `jal ra, foo` 1681 // both being acceptable forms. When parsing `jal ra, foo` this function 1682 // will be called for the `ra` register operand in an attempt to match the 1683 // single-operand alias. parseJALOffset must fail for this case. It would 1684 // seem logical to try parse the operand using parseImmediate and return 1685 // NoMatch if the next token is a comma (meaning we must be parsing a jal in 1686 // the second form rather than the first). We can't do this as there's no 1687 // way of rewinding the lexer state. Instead, return NoMatch if this operand 1688 // is an identifier and is followed by a comma. 1689 if (getLexer().is(AsmToken::Identifier) && 1690 getLexer().peekTok().is(AsmToken::Comma)) 1691 return MatchOperand_NoMatch; 1692 1693 return parseImmediate(Operands); 1694 } 1695 1696 OperandMatchResultTy RISCVAsmParser::parseVTypeI(OperandVector &Operands) { 1697 SMLoc S = getLoc(); 1698 if (getLexer().isNot(AsmToken::Identifier)) 1699 return MatchOperand_NoMatch; 1700 1701 SmallVector<AsmToken, 7> VTypeIElements; 1702 // Put all the tokens for vtypei operand into VTypeIElements vector. 1703 while (getLexer().isNot(AsmToken::EndOfStatement)) { 1704 VTypeIElements.push_back(getLexer().getTok()); 1705 getLexer().Lex(); 1706 if (getLexer().is(AsmToken::EndOfStatement)) 1707 break; 1708 if (getLexer().isNot(AsmToken::Comma)) 1709 goto MatchFail; 1710 AsmToken Comma = getLexer().getTok(); 1711 VTypeIElements.push_back(Comma); 1712 getLexer().Lex(); 1713 } 1714 1715 if (VTypeIElements.size() == 7) { 1716 // The VTypeIElements layout is: 1717 // SEW comma LMUL comma TA comma MA 1718 // 0 1 2 3 4 5 6 1719 StringRef Name = VTypeIElements[0].getIdentifier(); 1720 if (!Name.consume_front("e")) 1721 goto MatchFail; 1722 unsigned Sew; 1723 if (Name.getAsInteger(10, Sew)) 1724 goto MatchFail; 1725 if (!RISCVVType::isValidSEW(Sew)) 1726 goto MatchFail; 1727 1728 Name = VTypeIElements[2].getIdentifier(); 1729 if (!Name.consume_front("m")) 1730 goto MatchFail; 1731 // "m" or "mf" 1732 bool Fractional = Name.consume_front("f"); 1733 unsigned Lmul; 1734 if (Name.getAsInteger(10, Lmul)) 1735 goto MatchFail; 1736 if (!RISCVVType::isValidLMUL(Lmul, Fractional)) 1737 goto MatchFail; 1738 1739 // ta or tu 1740 Name = VTypeIElements[4].getIdentifier(); 1741 bool TailAgnostic; 1742 if (Name == "ta") 1743 TailAgnostic = true; 1744 else if (Name == "tu") 1745 TailAgnostic = false; 1746 else 1747 goto MatchFail; 1748 1749 // ma or mu 1750 Name = VTypeIElements[6].getIdentifier(); 1751 bool MaskAgnostic; 1752 if (Name == "ma") 1753 MaskAgnostic = true; 1754 else if (Name == "mu") 1755 MaskAgnostic = false; 1756 else 1757 goto MatchFail; 1758 1759 unsigned LmulLog2 = Log2_32(Lmul); 1760 RISCVII::VLMUL VLMUL = 1761 static_cast<RISCVII::VLMUL>(Fractional ? 8 - LmulLog2 : LmulLog2); 1762 1763 unsigned VTypeI = 1764 RISCVVType::encodeVTYPE(VLMUL, Sew, TailAgnostic, MaskAgnostic); 1765 Operands.push_back(RISCVOperand::createVType(VTypeI, S, isRV64())); 1766 return MatchOperand_Success; 1767 } 1768 1769 // If NoMatch, unlex all the tokens that comprise a vtypei operand 1770 MatchFail: 1771 while (!VTypeIElements.empty()) 1772 getLexer().UnLex(VTypeIElements.pop_back_val()); 1773 return MatchOperand_NoMatch; 1774 } 1775 1776 OperandMatchResultTy RISCVAsmParser::parseMaskReg(OperandVector &Operands) { 1777 switch (getLexer().getKind()) { 1778 default: 1779 return MatchOperand_NoMatch; 1780 case AsmToken::Identifier: 1781 StringRef Name = getLexer().getTok().getIdentifier(); 1782 if (!Name.consume_back(".t")) { 1783 Error(getLoc(), "expected '.t' suffix"); 1784 return MatchOperand_ParseFail; 1785 } 1786 MCRegister RegNo; 1787 matchRegisterNameHelper(isRV32E(), RegNo, Name); 1788 1789 if (RegNo == RISCV::NoRegister) 1790 return MatchOperand_NoMatch; 1791 if (RegNo != RISCV::V0) 1792 return MatchOperand_NoMatch; 1793 SMLoc S = getLoc(); 1794 SMLoc E = SMLoc::getFromPointer(S.getPointer() + Name.size()); 1795 getLexer().Lex(); 1796 Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64())); 1797 } 1798 1799 return MatchOperand_Success; 1800 } 1801 1802 OperandMatchResultTy 1803 RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) { 1804 if (getLexer().isNot(AsmToken::LParen)) { 1805 Error(getLoc(), "expected '('"); 1806 return MatchOperand_ParseFail; 1807 } 1808 1809 getParser().Lex(); // Eat '(' 1810 Operands.push_back(RISCVOperand::createToken("(", getLoc(), isRV64())); 1811 1812 if (parseRegister(Operands) != MatchOperand_Success) { 1813 Error(getLoc(), "expected register"); 1814 return MatchOperand_ParseFail; 1815 } 1816 1817 if (getLexer().isNot(AsmToken::RParen)) { 1818 Error(getLoc(), "expected ')'"); 1819 return MatchOperand_ParseFail; 1820 } 1821 1822 getParser().Lex(); // Eat ')' 1823 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64())); 1824 1825 return MatchOperand_Success; 1826 } 1827 1828 OperandMatchResultTy RISCVAsmParser::parseAtomicMemOp(OperandVector &Operands) { 1829 // Atomic operations such as lr.w, sc.w, and amo*.w accept a "memory operand" 1830 // as one of their register operands, such as `(a0)`. This just denotes that 1831 // the register (in this case `a0`) contains a memory address. 1832 // 1833 // Normally, we would be able to parse these by putting the parens into the 1834 // instruction string. However, GNU as also accepts a zero-offset memory 1835 // operand (such as `0(a0)`), and ignores the 0. Normally this would be parsed 1836 // with parseImmediate followed by parseMemOpBaseReg, but these instructions 1837 // do not accept an immediate operand, and we do not want to add a "dummy" 1838 // operand that is silently dropped. 1839 // 1840 // Instead, we use this custom parser. This will: allow (and discard) an 1841 // offset if it is zero; require (and discard) parentheses; and add only the 1842 // parsed register operand to `Operands`. 1843 // 1844 // These operands are printed with RISCVInstPrinter::printAtomicMemOp, which 1845 // will only print the register surrounded by parentheses (which GNU as also 1846 // uses as its canonical representation for these operands). 1847 std::unique_ptr<RISCVOperand> OptionalImmOp; 1848 1849 if (getLexer().isNot(AsmToken::LParen)) { 1850 // Parse an Integer token. We do not accept arbritrary constant expressions 1851 // in the offset field (because they may include parens, which complicates 1852 // parsing a lot). 1853 int64_t ImmVal; 1854 SMLoc ImmStart = getLoc(); 1855 if (getParser().parseIntToken(ImmVal, 1856 "expected '(' or optional integer offset")) 1857 return MatchOperand_ParseFail; 1858 1859 // Create a RISCVOperand for checking later (so the error messages are 1860 // nicer), but we don't add it to Operands. 1861 SMLoc ImmEnd = getLoc(); 1862 OptionalImmOp = 1863 RISCVOperand::createImm(MCConstantExpr::create(ImmVal, getContext()), 1864 ImmStart, ImmEnd, isRV64()); 1865 } 1866 1867 if (getLexer().isNot(AsmToken::LParen)) { 1868 Error(getLoc(), OptionalImmOp ? "expected '(' after optional integer offset" 1869 : "expected '(' or optional integer offset"); 1870 return MatchOperand_ParseFail; 1871 } 1872 getParser().Lex(); // Eat '(' 1873 1874 if (parseRegister(Operands) != MatchOperand_Success) { 1875 Error(getLoc(), "expected register"); 1876 return MatchOperand_ParseFail; 1877 } 1878 1879 if (getLexer().isNot(AsmToken::RParen)) { 1880 Error(getLoc(), "expected ')'"); 1881 return MatchOperand_ParseFail; 1882 } 1883 getParser().Lex(); // Eat ')' 1884 1885 // Deferred Handling of non-zero offsets. This makes the error messages nicer. 1886 if (OptionalImmOp && !OptionalImmOp->isImmZero()) { 1887 Error(OptionalImmOp->getStartLoc(), "optional integer offset must be 0", 1888 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc())); 1889 return MatchOperand_ParseFail; 1890 } 1891 1892 return MatchOperand_Success; 1893 } 1894 1895 /// Looks at a token type and creates the relevant operand from this 1896 /// information, adding to Operands. If operand was parsed, returns false, else 1897 /// true. 1898 bool RISCVAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { 1899 // Check if the current operand has a custom associated parser, if so, try to 1900 // custom parse the operand, or fallback to the general approach. 1901 OperandMatchResultTy Result = 1902 MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true); 1903 if (Result == MatchOperand_Success) 1904 return false; 1905 if (Result == MatchOperand_ParseFail) 1906 return true; 1907 1908 // Attempt to parse token as a register. 1909 if (parseRegister(Operands, true) == MatchOperand_Success) 1910 return false; 1911 1912 // Attempt to parse token as an immediate 1913 if (parseImmediate(Operands) == MatchOperand_Success) { 1914 // Parse memory base register if present 1915 if (getLexer().is(AsmToken::LParen)) 1916 return parseMemOpBaseReg(Operands) != MatchOperand_Success; 1917 return false; 1918 } 1919 1920 // Finally we have exhausted all options and must declare defeat. 1921 Error(getLoc(), "unknown operand"); 1922 return true; 1923 } 1924 1925 bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info, 1926 StringRef Name, SMLoc NameLoc, 1927 OperandVector &Operands) { 1928 // Ensure that if the instruction occurs when relaxation is enabled, 1929 // relocations are forced for the file. Ideally this would be done when there 1930 // is enough information to reliably determine if the instruction itself may 1931 // cause relaxations. Unfortunately instruction processing stage occurs in the 1932 // same pass as relocation emission, so it's too late to set a 'sticky bit' 1933 // for the entire file. 1934 if (getSTI().getFeatureBits()[RISCV::FeatureRelax]) { 1935 auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr(); 1936 if (Assembler != nullptr) { 1937 RISCVAsmBackend &MAB = 1938 static_cast<RISCVAsmBackend &>(Assembler->getBackend()); 1939 MAB.setForceRelocs(); 1940 } 1941 } 1942 1943 // First operand is token for instruction 1944 Operands.push_back(RISCVOperand::createToken(Name, NameLoc, isRV64())); 1945 1946 // If there are no more operands, then finish 1947 if (getLexer().is(AsmToken::EndOfStatement)) { 1948 getParser().Lex(); // Consume the EndOfStatement. 1949 return false; 1950 } 1951 1952 // Parse first operand 1953 if (parseOperand(Operands, Name)) 1954 return true; 1955 1956 // Parse until end of statement, consuming commas between operands 1957 unsigned OperandIdx = 1; 1958 while (getLexer().is(AsmToken::Comma)) { 1959 // Consume comma token 1960 getLexer().Lex(); 1961 1962 // Parse next operand 1963 if (parseOperand(Operands, Name)) 1964 return true; 1965 1966 ++OperandIdx; 1967 } 1968 1969 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1970 SMLoc Loc = getLexer().getLoc(); 1971 getParser().eatToEndOfStatement(); 1972 return Error(Loc, "unexpected token"); 1973 } 1974 1975 getParser().Lex(); // Consume the EndOfStatement. 1976 return false; 1977 } 1978 1979 bool RISCVAsmParser::classifySymbolRef(const MCExpr *Expr, 1980 RISCVMCExpr::VariantKind &Kind) { 1981 Kind = RISCVMCExpr::VK_RISCV_None; 1982 1983 if (const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) { 1984 Kind = RE->getKind(); 1985 Expr = RE->getSubExpr(); 1986 } 1987 1988 MCValue Res; 1989 MCFixup Fixup; 1990 if (Expr->evaluateAsRelocatable(Res, nullptr, &Fixup)) 1991 return Res.getRefKind() == RISCVMCExpr::VK_RISCV_None; 1992 return false; 1993 } 1994 1995 bool RISCVAsmParser::ParseDirective(AsmToken DirectiveID) { 1996 // This returns false if this function recognizes the directive 1997 // regardless of whether it is successfully handles or reports an 1998 // error. Otherwise it returns true to give the generic parser a 1999 // chance at recognizing it. 2000 StringRef IDVal = DirectiveID.getString(); 2001 2002 if (IDVal == ".option") 2003 return parseDirectiveOption(); 2004 if (IDVal == ".attribute") 2005 return parseDirectiveAttribute(); 2006 if (IDVal == ".insn") 2007 return parseDirectiveInsn(DirectiveID.getLoc()); 2008 2009 return true; 2010 } 2011 2012 bool RISCVAsmParser::parseDirectiveOption() { 2013 MCAsmParser &Parser = getParser(); 2014 // Get the option token. 2015 AsmToken Tok = Parser.getTok(); 2016 // At the moment only identifiers are supported. 2017 if (Tok.isNot(AsmToken::Identifier)) 2018 return Error(Parser.getTok().getLoc(), 2019 "unexpected token, expected identifier"); 2020 2021 StringRef Option = Tok.getIdentifier(); 2022 2023 if (Option == "push") { 2024 getTargetStreamer().emitDirectiveOptionPush(); 2025 2026 Parser.Lex(); 2027 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 2028 return Error(Parser.getTok().getLoc(), 2029 "unexpected token, expected end of statement"); 2030 2031 pushFeatureBits(); 2032 return false; 2033 } 2034 2035 if (Option == "pop") { 2036 SMLoc StartLoc = Parser.getTok().getLoc(); 2037 getTargetStreamer().emitDirectiveOptionPop(); 2038 2039 Parser.Lex(); 2040 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 2041 return Error(Parser.getTok().getLoc(), 2042 "unexpected token, expected end of statement"); 2043 2044 if (popFeatureBits()) 2045 return Error(StartLoc, ".option pop with no .option push"); 2046 2047 return false; 2048 } 2049 2050 if (Option == "rvc") { 2051 getTargetStreamer().emitDirectiveOptionRVC(); 2052 2053 Parser.Lex(); 2054 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 2055 return Error(Parser.getTok().getLoc(), 2056 "unexpected token, expected end of statement"); 2057 2058 setFeatureBits(RISCV::FeatureStdExtC, "c"); 2059 return false; 2060 } 2061 2062 if (Option == "norvc") { 2063 getTargetStreamer().emitDirectiveOptionNoRVC(); 2064 2065 Parser.Lex(); 2066 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 2067 return Error(Parser.getTok().getLoc(), 2068 "unexpected token, expected end of statement"); 2069 2070 clearFeatureBits(RISCV::FeatureStdExtC, "c"); 2071 return false; 2072 } 2073 2074 if (Option == "pic") { 2075 getTargetStreamer().emitDirectiveOptionPIC(); 2076 2077 Parser.Lex(); 2078 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 2079 return Error(Parser.getTok().getLoc(), 2080 "unexpected token, expected end of statement"); 2081 2082 ParserOptions.IsPicEnabled = true; 2083 return false; 2084 } 2085 2086 if (Option == "nopic") { 2087 getTargetStreamer().emitDirectiveOptionNoPIC(); 2088 2089 Parser.Lex(); 2090 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 2091 return Error(Parser.getTok().getLoc(), 2092 "unexpected token, expected end of statement"); 2093 2094 ParserOptions.IsPicEnabled = false; 2095 return false; 2096 } 2097 2098 if (Option == "relax") { 2099 getTargetStreamer().emitDirectiveOptionRelax(); 2100 2101 Parser.Lex(); 2102 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 2103 return Error(Parser.getTok().getLoc(), 2104 "unexpected token, expected end of statement"); 2105 2106 setFeatureBits(RISCV::FeatureRelax, "relax"); 2107 return false; 2108 } 2109 2110 if (Option == "norelax") { 2111 getTargetStreamer().emitDirectiveOptionNoRelax(); 2112 2113 Parser.Lex(); 2114 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 2115 return Error(Parser.getTok().getLoc(), 2116 "unexpected token, expected end of statement"); 2117 2118 clearFeatureBits(RISCV::FeatureRelax, "relax"); 2119 return false; 2120 } 2121 2122 // Unknown option. 2123 Warning(Parser.getTok().getLoc(), 2124 "unknown option, expected 'push', 'pop', 'rvc', 'norvc', 'relax' or " 2125 "'norelax'"); 2126 Parser.eatToEndOfStatement(); 2127 return false; 2128 } 2129 2130 /// parseDirectiveAttribute 2131 /// ::= .attribute expression ',' ( expression | "string" ) 2132 /// ::= .attribute identifier ',' ( expression | "string" ) 2133 bool RISCVAsmParser::parseDirectiveAttribute() { 2134 MCAsmParser &Parser = getParser(); 2135 int64_t Tag; 2136 SMLoc TagLoc; 2137 TagLoc = Parser.getTok().getLoc(); 2138 if (Parser.getTok().is(AsmToken::Identifier)) { 2139 StringRef Name = Parser.getTok().getIdentifier(); 2140 Optional<unsigned> Ret = 2141 ELFAttrs::attrTypeFromString(Name, RISCVAttrs::getRISCVAttributeTags()); 2142 if (!Ret.hasValue()) { 2143 Error(TagLoc, "attribute name not recognised: " + Name); 2144 return false; 2145 } 2146 Tag = Ret.getValue(); 2147 Parser.Lex(); 2148 } else { 2149 const MCExpr *AttrExpr; 2150 2151 TagLoc = Parser.getTok().getLoc(); 2152 if (Parser.parseExpression(AttrExpr)) 2153 return true; 2154 2155 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr); 2156 if (check(!CE, TagLoc, "expected numeric constant")) 2157 return true; 2158 2159 Tag = CE->getValue(); 2160 } 2161 2162 if (Parser.parseToken(AsmToken::Comma, "comma expected")) 2163 return true; 2164 2165 StringRef StringValue; 2166 int64_t IntegerValue = 0; 2167 bool IsIntegerValue = true; 2168 2169 // RISC-V attributes have a string value if the tag number is odd 2170 // and an integer value if the tag number is even. 2171 if (Tag % 2) 2172 IsIntegerValue = false; 2173 2174 SMLoc ValueExprLoc = Parser.getTok().getLoc(); 2175 if (IsIntegerValue) { 2176 const MCExpr *ValueExpr; 2177 if (Parser.parseExpression(ValueExpr)) 2178 return true; 2179 2180 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr); 2181 if (!CE) 2182 return Error(ValueExprLoc, "expected numeric constant"); 2183 IntegerValue = CE->getValue(); 2184 } else { 2185 if (Parser.getTok().isNot(AsmToken::String)) 2186 return Error(Parser.getTok().getLoc(), "expected string constant"); 2187 2188 StringValue = Parser.getTok().getStringContents(); 2189 Parser.Lex(); 2190 } 2191 2192 if (Parser.parseToken(AsmToken::EndOfStatement, 2193 "unexpected token in '.attribute' directive")) 2194 return true; 2195 2196 if (IsIntegerValue) 2197 getTargetStreamer().emitAttribute(Tag, IntegerValue); 2198 else if (Tag != RISCVAttrs::ARCH) 2199 getTargetStreamer().emitTextAttribute(Tag, StringValue); 2200 else { 2201 StringRef Arch = StringValue; 2202 for (auto Feature : RISCVFeatureKV) 2203 if (llvm::RISCVISAInfo::isSupportedExtensionFeature(Feature.Key)) 2204 clearFeatureBits(Feature.Value, Feature.Key); 2205 2206 auto ParseResult = llvm::RISCVISAInfo::parseArchString( 2207 StringValue, /*EnableExperimentalExtension=*/true, 2208 /*ExperimentalExtensionVersionCheck=*/true); 2209 if (!ParseResult) { 2210 std::string Buffer; 2211 raw_string_ostream OutputErrMsg(Buffer); 2212 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) { 2213 OutputErrMsg << "invalid arch name '" << Arch << "', " 2214 << ErrMsg.getMessage(); 2215 }); 2216 2217 return Error(ValueExprLoc, OutputErrMsg.str()); 2218 } 2219 auto &ISAInfo = *ParseResult; 2220 2221 for (auto Feature : RISCVFeatureKV) 2222 if (ISAInfo->hasExtension(Feature.Key)) 2223 setFeatureBits(Feature.Value, Feature.Key); 2224 2225 if (ISAInfo->getXLen() == 32) 2226 clearFeatureBits(RISCV::Feature64Bit, "64bit"); 2227 else if (ISAInfo->getXLen() == 64) 2228 setFeatureBits(RISCV::Feature64Bit, "64bit"); 2229 else 2230 return Error(ValueExprLoc, "bad arch string " + Arch); 2231 2232 // Then emit the arch string. 2233 getTargetStreamer().emitTextAttribute(Tag, ISAInfo->toString()); 2234 } 2235 2236 return false; 2237 } 2238 2239 /// parseDirectiveInsn 2240 /// ::= .insn [ format encoding, (operands (, operands)*) ] 2241 bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) { 2242 MCAsmParser &Parser = getParser(); 2243 2244 // Expect instruction format as identifier. 2245 StringRef Format; 2246 SMLoc ErrorLoc = Parser.getTok().getLoc(); 2247 if (Parser.parseIdentifier(Format)) 2248 return Error(ErrorLoc, "expected instruction format"); 2249 2250 if (Format != "r" && Format != "r4" && Format != "i" && Format != "b" && 2251 Format != "sb" && Format != "u" && Format != "j" && Format != "uj" && 2252 Format != "s") 2253 return Error(ErrorLoc, "invalid instruction format"); 2254 2255 std::string FormatName = (".insn_" + Format).str(); 2256 2257 ParseInstructionInfo Info; 2258 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> Operands; 2259 2260 if (ParseInstruction(Info, FormatName, L, Operands)) 2261 return true; 2262 2263 unsigned Opcode; 2264 uint64_t ErrorInfo; 2265 return MatchAndEmitInstruction(L, Opcode, Operands, Parser.getStreamer(), 2266 ErrorInfo, 2267 /*MatchingInlineAsm=*/false); 2268 } 2269 2270 void RISCVAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) { 2271 MCInst CInst; 2272 bool Res = compressInst(CInst, Inst, getSTI(), S.getContext()); 2273 if (Res) 2274 ++RISCVNumInstrsCompressed; 2275 S.emitInstruction((Res ? CInst : Inst), getSTI()); 2276 } 2277 2278 void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t Value, 2279 MCStreamer &Out) { 2280 RISCVMatInt::InstSeq Seq = 2281 RISCVMatInt::generateInstSeq(Value, getSTI().getFeatureBits()); 2282 2283 MCRegister SrcReg = RISCV::X0; 2284 for (RISCVMatInt::Inst &Inst : Seq) { 2285 if (Inst.Opc == RISCV::LUI) { 2286 emitToStreamer( 2287 Out, MCInstBuilder(RISCV::LUI).addReg(DestReg).addImm(Inst.Imm)); 2288 } else if (Inst.Opc == RISCV::ADD_UW) { 2289 emitToStreamer(Out, MCInstBuilder(RISCV::ADD_UW) 2290 .addReg(DestReg) 2291 .addReg(SrcReg) 2292 .addReg(RISCV::X0)); 2293 } else if (Inst.Opc == RISCV::SH1ADD || Inst.Opc == RISCV::SH2ADD || 2294 Inst.Opc == RISCV::SH3ADD) { 2295 emitToStreamer( 2296 Out, MCInstBuilder(Inst.Opc).addReg(DestReg).addReg(SrcReg).addReg( 2297 SrcReg)); 2298 } else { 2299 emitToStreamer( 2300 Out, MCInstBuilder(Inst.Opc).addReg(DestReg).addReg(SrcReg).addImm( 2301 Inst.Imm)); 2302 } 2303 2304 // Only the first instruction has X0 as its source. 2305 SrcReg = DestReg; 2306 } 2307 } 2308 2309 void RISCVAsmParser::emitAuipcInstPair(MCOperand DestReg, MCOperand TmpReg, 2310 const MCExpr *Symbol, 2311 RISCVMCExpr::VariantKind VKHi, 2312 unsigned SecondOpcode, SMLoc IDLoc, 2313 MCStreamer &Out) { 2314 // A pair of instructions for PC-relative addressing; expands to 2315 // TmpLabel: AUIPC TmpReg, VKHi(symbol) 2316 // OP DestReg, TmpReg, %pcrel_lo(TmpLabel) 2317 MCContext &Ctx = getContext(); 2318 2319 MCSymbol *TmpLabel = Ctx.createNamedTempSymbol("pcrel_hi"); 2320 Out.emitLabel(TmpLabel); 2321 2322 const RISCVMCExpr *SymbolHi = RISCVMCExpr::create(Symbol, VKHi, Ctx); 2323 emitToStreamer( 2324 Out, MCInstBuilder(RISCV::AUIPC).addOperand(TmpReg).addExpr(SymbolHi)); 2325 2326 const MCExpr *RefToLinkTmpLabel = 2327 RISCVMCExpr::create(MCSymbolRefExpr::create(TmpLabel, Ctx), 2328 RISCVMCExpr::VK_RISCV_PCREL_LO, Ctx); 2329 2330 emitToStreamer(Out, MCInstBuilder(SecondOpcode) 2331 .addOperand(DestReg) 2332 .addOperand(TmpReg) 2333 .addExpr(RefToLinkTmpLabel)); 2334 } 2335 2336 void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, 2337 MCStreamer &Out) { 2338 // The load local address pseudo-instruction "lla" is used in PC-relative 2339 // addressing of local symbols: 2340 // lla rdest, symbol 2341 // expands to 2342 // TmpLabel: AUIPC rdest, %pcrel_hi(symbol) 2343 // ADDI rdest, rdest, %pcrel_lo(TmpLabel) 2344 MCOperand DestReg = Inst.getOperand(0); 2345 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 2346 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI, 2347 RISCV::ADDI, IDLoc, Out); 2348 } 2349 2350 void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc, 2351 MCStreamer &Out) { 2352 // The load address pseudo-instruction "la" is used in PC-relative and 2353 // GOT-indirect addressing of global symbols: 2354 // la rdest, symbol 2355 // expands to either (for non-PIC) 2356 // TmpLabel: AUIPC rdest, %pcrel_hi(symbol) 2357 // ADDI rdest, rdest, %pcrel_lo(TmpLabel) 2358 // or (for PIC) 2359 // TmpLabel: AUIPC rdest, %got_pcrel_hi(symbol) 2360 // Lx rdest, %pcrel_lo(TmpLabel)(rdest) 2361 MCOperand DestReg = Inst.getOperand(0); 2362 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 2363 unsigned SecondOpcode; 2364 RISCVMCExpr::VariantKind VKHi; 2365 if (ParserOptions.IsPicEnabled) { 2366 SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW; 2367 VKHi = RISCVMCExpr::VK_RISCV_GOT_HI; 2368 } else { 2369 SecondOpcode = RISCV::ADDI; 2370 VKHi = RISCVMCExpr::VK_RISCV_PCREL_HI; 2371 } 2372 emitAuipcInstPair(DestReg, DestReg, Symbol, VKHi, SecondOpcode, IDLoc, Out); 2373 } 2374 2375 void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc, 2376 MCStreamer &Out) { 2377 // The load TLS IE address pseudo-instruction "la.tls.ie" is used in 2378 // initial-exec TLS model addressing of global symbols: 2379 // la.tls.ie rdest, symbol 2380 // expands to 2381 // TmpLabel: AUIPC rdest, %tls_ie_pcrel_hi(symbol) 2382 // Lx rdest, %pcrel_lo(TmpLabel)(rdest) 2383 MCOperand DestReg = Inst.getOperand(0); 2384 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 2385 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW; 2386 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_TLS_GOT_HI, 2387 SecondOpcode, IDLoc, Out); 2388 } 2389 2390 void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, 2391 MCStreamer &Out) { 2392 // The load TLS GD address pseudo-instruction "la.tls.gd" is used in 2393 // global-dynamic TLS model addressing of global symbols: 2394 // la.tls.gd rdest, symbol 2395 // expands to 2396 // TmpLabel: AUIPC rdest, %tls_gd_pcrel_hi(symbol) 2397 // ADDI rdest, rdest, %pcrel_lo(TmpLabel) 2398 MCOperand DestReg = Inst.getOperand(0); 2399 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 2400 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_TLS_GD_HI, 2401 RISCV::ADDI, IDLoc, Out); 2402 } 2403 2404 void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode, 2405 SMLoc IDLoc, MCStreamer &Out, 2406 bool HasTmpReg) { 2407 // The load/store pseudo-instruction does a pc-relative load with 2408 // a symbol. 2409 // 2410 // The expansion looks like this 2411 // 2412 // TmpLabel: AUIPC tmp, %pcrel_hi(symbol) 2413 // [S|L]X rd, %pcrel_lo(TmpLabel)(tmp) 2414 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0; 2415 MCOperand DestReg = Inst.getOperand(DestRegOpIdx); 2416 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1; 2417 MCOperand TmpReg = Inst.getOperand(0); 2418 const MCExpr *Symbol = Inst.getOperand(SymbolOpIdx).getExpr(); 2419 emitAuipcInstPair(DestReg, TmpReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI, 2420 Opcode, IDLoc, Out); 2421 } 2422 2423 void RISCVAsmParser::emitPseudoExtend(MCInst &Inst, bool SignExtend, 2424 int64_t Width, SMLoc IDLoc, 2425 MCStreamer &Out) { 2426 // The sign/zero extend pseudo-instruction does two shifts, with the shift 2427 // amounts dependent on the XLEN. 2428 // 2429 // The expansion looks like this 2430 // 2431 // SLLI rd, rs, XLEN - Width 2432 // SR[A|R]I rd, rd, XLEN - Width 2433 MCOperand DestReg = Inst.getOperand(0); 2434 MCOperand SourceReg = Inst.getOperand(1); 2435 2436 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI; 2437 int64_t ShAmt = (isRV64() ? 64 : 32) - Width; 2438 2439 assert(ShAmt > 0 && "Shift amount must be non-zero."); 2440 2441 emitToStreamer(Out, MCInstBuilder(RISCV::SLLI) 2442 .addOperand(DestReg) 2443 .addOperand(SourceReg) 2444 .addImm(ShAmt)); 2445 2446 emitToStreamer(Out, MCInstBuilder(SecondOpcode) 2447 .addOperand(DestReg) 2448 .addOperand(DestReg) 2449 .addImm(ShAmt)); 2450 } 2451 2452 void RISCVAsmParser::emitVMSGE(MCInst &Inst, unsigned Opcode, SMLoc IDLoc, 2453 MCStreamer &Out) { 2454 if (Inst.getNumOperands() == 3) { 2455 // unmasked va >= x 2456 // 2457 // pseudoinstruction: vmsge{u}.vx vd, va, x 2458 // expansion: vmslt{u}.vx vd, va, x; vmnand.mm vd, vd, vd 2459 emitToStreamer(Out, MCInstBuilder(Opcode) 2460 .addOperand(Inst.getOperand(0)) 2461 .addOperand(Inst.getOperand(1)) 2462 .addOperand(Inst.getOperand(2)) 2463 .addReg(RISCV::NoRegister)); 2464 emitToStreamer(Out, MCInstBuilder(RISCV::VMNAND_MM) 2465 .addOperand(Inst.getOperand(0)) 2466 .addOperand(Inst.getOperand(0)) 2467 .addOperand(Inst.getOperand(0))); 2468 } else if (Inst.getNumOperands() == 4) { 2469 // masked va >= x, vd != v0 2470 // 2471 // pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t 2472 // expansion: vmslt{u}.vx vd, va, x, v0.t; vmxor.mm vd, vd, v0 2473 assert(Inst.getOperand(0).getReg() != RISCV::V0 && 2474 "The destination register should not be V0."); 2475 emitToStreamer(Out, MCInstBuilder(Opcode) 2476 .addOperand(Inst.getOperand(0)) 2477 .addOperand(Inst.getOperand(1)) 2478 .addOperand(Inst.getOperand(2)) 2479 .addOperand(Inst.getOperand(3))); 2480 emitToStreamer(Out, MCInstBuilder(RISCV::VMXOR_MM) 2481 .addOperand(Inst.getOperand(0)) 2482 .addOperand(Inst.getOperand(0)) 2483 .addReg(RISCV::V0)); 2484 } else if (Inst.getNumOperands() == 5 && 2485 Inst.getOperand(0).getReg() == RISCV::V0) { 2486 // masked va >= x, vd == v0 2487 // 2488 // pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t, vt 2489 // expansion: vmslt{u}.vx vt, va, x; vmandn.mm vd, vd, vt 2490 assert(Inst.getOperand(0).getReg() == RISCV::V0 && 2491 "The destination register should be V0."); 2492 assert(Inst.getOperand(1).getReg() != RISCV::V0 && 2493 "The temporary vector register should not be V0."); 2494 emitToStreamer(Out, MCInstBuilder(Opcode) 2495 .addOperand(Inst.getOperand(1)) 2496 .addOperand(Inst.getOperand(2)) 2497 .addOperand(Inst.getOperand(3)) 2498 .addOperand(Inst.getOperand(4))); 2499 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM) 2500 .addOperand(Inst.getOperand(0)) 2501 .addOperand(Inst.getOperand(0)) 2502 .addOperand(Inst.getOperand(1))); 2503 } else if (Inst.getNumOperands() == 5) { 2504 // masked va >= x, any vd 2505 // 2506 // pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t, vt 2507 // expansion: vmslt{u}.vx vt, va, x; vmandn.mm vt, v0, vt; vmandn.mm vd, 2508 // vd, v0; vmor.mm vd, vt, vd 2509 assert(Inst.getOperand(1).getReg() != RISCV::V0 && 2510 "The temporary vector register should not be V0."); 2511 emitToStreamer(Out, MCInstBuilder(Opcode) 2512 .addOperand(Inst.getOperand(1)) 2513 .addOperand(Inst.getOperand(2)) 2514 .addOperand(Inst.getOperand(3)) 2515 .addReg(RISCV::NoRegister)); 2516 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM) 2517 .addOperand(Inst.getOperand(1)) 2518 .addReg(RISCV::V0) 2519 .addOperand(Inst.getOperand(1))); 2520 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM) 2521 .addOperand(Inst.getOperand(0)) 2522 .addOperand(Inst.getOperand(0)) 2523 .addReg(RISCV::V0)); 2524 emitToStreamer(Out, MCInstBuilder(RISCV::VMOR_MM) 2525 .addOperand(Inst.getOperand(0)) 2526 .addOperand(Inst.getOperand(1)) 2527 .addOperand(Inst.getOperand(0))); 2528 } 2529 } 2530 2531 bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst, 2532 OperandVector &Operands) { 2533 assert(Inst.getOpcode() == RISCV::PseudoAddTPRel && "Invalid instruction"); 2534 assert(Inst.getOperand(2).isReg() && "Unexpected second operand kind"); 2535 if (Inst.getOperand(2).getReg() != RISCV::X4) { 2536 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc(); 2537 return Error(ErrorLoc, "the second input operand must be tp/x4 when using " 2538 "%tprel_add modifier"); 2539 } 2540 2541 return false; 2542 } 2543 2544 std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp() const { 2545 return RISCVOperand::createReg(RISCV::NoRegister, llvm::SMLoc(), 2546 llvm::SMLoc(), isRV64()); 2547 } 2548 2549 bool RISCVAsmParser::validateInstruction(MCInst &Inst, 2550 OperandVector &Operands) { 2551 if (Inst.getOpcode() == RISCV::PseudoVMSGEU_VX_M_T || 2552 Inst.getOpcode() == RISCV::PseudoVMSGE_VX_M_T) { 2553 unsigned DestReg = Inst.getOperand(0).getReg(); 2554 unsigned TempReg = Inst.getOperand(1).getReg(); 2555 if (DestReg == TempReg) { 2556 SMLoc Loc = Operands.back()->getStartLoc(); 2557 return Error(Loc, "The temporary vector register cannot be the same as " 2558 "the destination register."); 2559 } 2560 } 2561 2562 const MCInstrDesc &MCID = MII.get(Inst.getOpcode()); 2563 RISCVII::VConstraintType Constraints = 2564 RISCVII::getConstraint(MCID.TSFlags); 2565 if (Constraints == RISCVII::NoConstraint) 2566 return false; 2567 2568 unsigned DestReg = Inst.getOperand(0).getReg(); 2569 // Operands[1] will be the first operand, DestReg. 2570 SMLoc Loc = Operands[1]->getStartLoc(); 2571 if (Constraints & RISCVII::VS2Constraint) { 2572 unsigned CheckReg = Inst.getOperand(1).getReg(); 2573 if (DestReg == CheckReg) 2574 return Error(Loc, "The destination vector register group cannot overlap" 2575 " the source vector register group."); 2576 } 2577 if ((Constraints & RISCVII::VS1Constraint) && (Inst.getOperand(2).isReg())) { 2578 unsigned CheckReg = Inst.getOperand(2).getReg(); 2579 if (DestReg == CheckReg) 2580 return Error(Loc, "The destination vector register group cannot overlap" 2581 " the source vector register group."); 2582 } 2583 if ((Constraints & RISCVII::VMConstraint) && (DestReg == RISCV::V0)) { 2584 // vadc, vsbc are special cases. These instructions have no mask register. 2585 // The destination register could not be V0. 2586 unsigned Opcode = Inst.getOpcode(); 2587 if (Opcode == RISCV::VADC_VVM || Opcode == RISCV::VADC_VXM || 2588 Opcode == RISCV::VADC_VIM || Opcode == RISCV::VSBC_VVM || 2589 Opcode == RISCV::VSBC_VXM || Opcode == RISCV::VFMERGE_VFM || 2590 Opcode == RISCV::VMERGE_VIM || Opcode == RISCV::VMERGE_VVM || 2591 Opcode == RISCV::VMERGE_VXM) 2592 return Error(Loc, "The destination vector register group cannot be V0."); 2593 2594 // Regardless masked or unmasked version, the number of operands is the 2595 // same. For example, "viota.m v0, v2" is "viota.m v0, v2, NoRegister" 2596 // actually. We need to check the last operand to ensure whether it is 2597 // masked or not. 2598 unsigned CheckReg = Inst.getOperand(Inst.getNumOperands() - 1).getReg(); 2599 assert((CheckReg == RISCV::V0 || CheckReg == RISCV::NoRegister) && 2600 "Unexpected register for mask operand"); 2601 2602 if (DestReg == CheckReg) 2603 return Error(Loc, "The destination vector register group cannot overlap" 2604 " the mask register."); 2605 } 2606 return false; 2607 } 2608 2609 bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 2610 OperandVector &Operands, 2611 MCStreamer &Out) { 2612 Inst.setLoc(IDLoc); 2613 2614 switch (Inst.getOpcode()) { 2615 default: 2616 break; 2617 case RISCV::PseudoLI: { 2618 MCRegister Reg = Inst.getOperand(0).getReg(); 2619 const MCOperand &Op1 = Inst.getOperand(1); 2620 if (Op1.isExpr()) { 2621 // We must have li reg, %lo(sym) or li reg, %pcrel_lo(sym) or similar. 2622 // Just convert to an addi. This allows compatibility with gas. 2623 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI) 2624 .addReg(Reg) 2625 .addReg(RISCV::X0) 2626 .addExpr(Op1.getExpr())); 2627 return false; 2628 } 2629 int64_t Imm = Inst.getOperand(1).getImm(); 2630 // On RV32 the immediate here can either be a signed or an unsigned 2631 // 32-bit number. Sign extension has to be performed to ensure that Imm 2632 // represents the expected signed 64-bit number. 2633 if (!isRV64()) 2634 Imm = SignExtend64<32>(Imm); 2635 emitLoadImm(Reg, Imm, Out); 2636 return false; 2637 } 2638 case RISCV::PseudoLLA: 2639 emitLoadLocalAddress(Inst, IDLoc, Out); 2640 return false; 2641 case RISCV::PseudoLA: 2642 emitLoadAddress(Inst, IDLoc, Out); 2643 return false; 2644 case RISCV::PseudoLA_TLS_IE: 2645 emitLoadTLSIEAddress(Inst, IDLoc, Out); 2646 return false; 2647 case RISCV::PseudoLA_TLS_GD: 2648 emitLoadTLSGDAddress(Inst, IDLoc, Out); 2649 return false; 2650 case RISCV::PseudoLB: 2651 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out, /*HasTmpReg=*/false); 2652 return false; 2653 case RISCV::PseudoLBU: 2654 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out, /*HasTmpReg=*/false); 2655 return false; 2656 case RISCV::PseudoLH: 2657 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out, /*HasTmpReg=*/false); 2658 return false; 2659 case RISCV::PseudoLHU: 2660 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out, /*HasTmpReg=*/false); 2661 return false; 2662 case RISCV::PseudoLW: 2663 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out, /*HasTmpReg=*/false); 2664 return false; 2665 case RISCV::PseudoLWU: 2666 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out, /*HasTmpReg=*/false); 2667 return false; 2668 case RISCV::PseudoLD: 2669 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out, /*HasTmpReg=*/false); 2670 return false; 2671 case RISCV::PseudoFLH: 2672 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out, /*HasTmpReg=*/true); 2673 return false; 2674 case RISCV::PseudoFLW: 2675 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out, /*HasTmpReg=*/true); 2676 return false; 2677 case RISCV::PseudoFLD: 2678 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out, /*HasTmpReg=*/true); 2679 return false; 2680 case RISCV::PseudoSB: 2681 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out, /*HasTmpReg=*/true); 2682 return false; 2683 case RISCV::PseudoSH: 2684 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out, /*HasTmpReg=*/true); 2685 return false; 2686 case RISCV::PseudoSW: 2687 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out, /*HasTmpReg=*/true); 2688 return false; 2689 case RISCV::PseudoSD: 2690 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out, /*HasTmpReg=*/true); 2691 return false; 2692 case RISCV::PseudoFSH: 2693 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out, /*HasTmpReg=*/true); 2694 return false; 2695 case RISCV::PseudoFSW: 2696 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out, /*HasTmpReg=*/true); 2697 return false; 2698 case RISCV::PseudoFSD: 2699 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out, /*HasTmpReg=*/true); 2700 return false; 2701 case RISCV::PseudoAddTPRel: 2702 if (checkPseudoAddTPRel(Inst, Operands)) 2703 return true; 2704 break; 2705 case RISCV::PseudoSEXT_B: 2706 emitPseudoExtend(Inst, /*SignExtend=*/true, /*Width=*/8, IDLoc, Out); 2707 return false; 2708 case RISCV::PseudoSEXT_H: 2709 emitPseudoExtend(Inst, /*SignExtend=*/true, /*Width=*/16, IDLoc, Out); 2710 return false; 2711 case RISCV::PseudoZEXT_H: 2712 emitPseudoExtend(Inst, /*SignExtend=*/false, /*Width=*/16, IDLoc, Out); 2713 return false; 2714 case RISCV::PseudoZEXT_W: 2715 emitPseudoExtend(Inst, /*SignExtend=*/false, /*Width=*/32, IDLoc, Out); 2716 return false; 2717 case RISCV::PseudoVMSGEU_VX: 2718 case RISCV::PseudoVMSGEU_VX_M: 2719 case RISCV::PseudoVMSGEU_VX_M_T: 2720 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out); 2721 return false; 2722 case RISCV::PseudoVMSGE_VX: 2723 case RISCV::PseudoVMSGE_VX_M: 2724 case RISCV::PseudoVMSGE_VX_M_T: 2725 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out); 2726 return false; 2727 case RISCV::PseudoVMSGE_VI: 2728 case RISCV::PseudoVMSLT_VI: { 2729 // These instructions are signed and so is immediate so we can subtract one 2730 // and change the opcode. 2731 int64_t Imm = Inst.getOperand(2).getImm(); 2732 unsigned Opc = Inst.getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI 2733 : RISCV::VMSLE_VI; 2734 emitToStreamer(Out, MCInstBuilder(Opc) 2735 .addOperand(Inst.getOperand(0)) 2736 .addOperand(Inst.getOperand(1)) 2737 .addImm(Imm - 1) 2738 .addOperand(Inst.getOperand(3))); 2739 return false; 2740 } 2741 case RISCV::PseudoVMSGEU_VI: 2742 case RISCV::PseudoVMSLTU_VI: { 2743 int64_t Imm = Inst.getOperand(2).getImm(); 2744 // Unsigned comparisons are tricky because the immediate is signed. If the 2745 // immediate is 0 we can't just subtract one. vmsltu.vi v0, v1, 0 is always 2746 // false, but vmsle.vi v0, v1, -1 is always true. Instead we use 2747 // vmsne v0, v1, v1 which is always false. 2748 if (Imm == 0) { 2749 unsigned Opc = Inst.getOpcode() == RISCV::PseudoVMSGEU_VI 2750 ? RISCV::VMSEQ_VV 2751 : RISCV::VMSNE_VV; 2752 emitToStreamer(Out, MCInstBuilder(Opc) 2753 .addOperand(Inst.getOperand(0)) 2754 .addOperand(Inst.getOperand(1)) 2755 .addOperand(Inst.getOperand(1)) 2756 .addOperand(Inst.getOperand(3))); 2757 } else { 2758 // Other immediate values can subtract one like signed. 2759 unsigned Opc = Inst.getOpcode() == RISCV::PseudoVMSGEU_VI 2760 ? RISCV::VMSGTU_VI 2761 : RISCV::VMSLEU_VI; 2762 emitToStreamer(Out, MCInstBuilder(Opc) 2763 .addOperand(Inst.getOperand(0)) 2764 .addOperand(Inst.getOperand(1)) 2765 .addImm(Imm - 1) 2766 .addOperand(Inst.getOperand(3))); 2767 } 2768 2769 return false; 2770 } 2771 } 2772 2773 emitToStreamer(Out, Inst); 2774 return false; 2775 } 2776 2777 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVAsmParser() { 2778 RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target()); 2779 RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target()); 2780 } 2781