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