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