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