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