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 // Accept a named Sys Reg if the required features are present. 1316 if (SysReg) { 1317 if (!SysReg->haveRequiredFeatures(getSTI().getFeatureBits())) { 1318 Error(S, "system register use requires an option to be enabled"); 1319 return MatchOperand_ParseFail; 1320 } 1321 Operands.push_back(RISCVOperand::createSysReg( 1322 Identifier, S, SysReg->Encoding, isRV64())); 1323 return MatchOperand_Success; 1324 } 1325 1326 Twine Msg = "operand must be a valid system register name " 1327 "or an integer in the range"; 1328 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]"); 1329 return MatchOperand_ParseFail; 1330 } 1331 case AsmToken::Percent: { 1332 // Discard operand with modifier. 1333 Twine Msg = "immediate must be an integer in the range"; 1334 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]"); 1335 return MatchOperand_ParseFail; 1336 } 1337 } 1338 1339 return MatchOperand_NoMatch; 1340 } 1341 1342 OperandMatchResultTy RISCVAsmParser::parseImmediate(OperandVector &Operands) { 1343 SMLoc S = getLoc(); 1344 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1345 const MCExpr *Res; 1346 1347 switch (getLexer().getKind()) { 1348 default: 1349 return MatchOperand_NoMatch; 1350 case AsmToken::LParen: 1351 case AsmToken::Dot: 1352 case AsmToken::Minus: 1353 case AsmToken::Plus: 1354 case AsmToken::Exclaim: 1355 case AsmToken::Tilde: 1356 case AsmToken::Integer: 1357 case AsmToken::String: 1358 case AsmToken::Identifier: 1359 if (getParser().parseExpression(Res)) 1360 return MatchOperand_ParseFail; 1361 break; 1362 case AsmToken::Percent: 1363 return parseOperandWithModifier(Operands); 1364 } 1365 1366 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1367 return MatchOperand_Success; 1368 } 1369 1370 OperandMatchResultTy 1371 RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) { 1372 SMLoc S = getLoc(); 1373 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1374 1375 if (getLexer().getKind() != AsmToken::Percent) { 1376 Error(getLoc(), "expected '%' for operand modifier"); 1377 return MatchOperand_ParseFail; 1378 } 1379 1380 getParser().Lex(); // Eat '%' 1381 1382 if (getLexer().getKind() != AsmToken::Identifier) { 1383 Error(getLoc(), "expected valid identifier for operand modifier"); 1384 return MatchOperand_ParseFail; 1385 } 1386 StringRef Identifier = getParser().getTok().getIdentifier(); 1387 RISCVMCExpr::VariantKind VK = RISCVMCExpr::getVariantKindForName(Identifier); 1388 if (VK == RISCVMCExpr::VK_RISCV_Invalid) { 1389 Error(getLoc(), "unrecognized operand modifier"); 1390 return MatchOperand_ParseFail; 1391 } 1392 1393 getParser().Lex(); // Eat the identifier 1394 if (getLexer().getKind() != AsmToken::LParen) { 1395 Error(getLoc(), "expected '('"); 1396 return MatchOperand_ParseFail; 1397 } 1398 getParser().Lex(); // Eat '(' 1399 1400 const MCExpr *SubExpr; 1401 if (getParser().parseParenExpression(SubExpr, E)) { 1402 return MatchOperand_ParseFail; 1403 } 1404 1405 const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, VK, getContext()); 1406 Operands.push_back(RISCVOperand::createImm(ModExpr, S, E, isRV64())); 1407 return MatchOperand_Success; 1408 } 1409 1410 OperandMatchResultTy RISCVAsmParser::parseBareSymbol(OperandVector &Operands) { 1411 SMLoc S = getLoc(); 1412 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1413 const MCExpr *Res; 1414 1415 if (getLexer().getKind() != AsmToken::Identifier) 1416 return MatchOperand_NoMatch; 1417 1418 StringRef Identifier; 1419 AsmToken Tok = getLexer().getTok(); 1420 1421 if (getParser().parseIdentifier(Identifier)) 1422 return MatchOperand_ParseFail; 1423 1424 if (Identifier.consume_back("@plt")) { 1425 Error(getLoc(), "'@plt' operand not valid for instruction"); 1426 return MatchOperand_ParseFail; 1427 } 1428 1429 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); 1430 1431 if (Sym->isVariable()) { 1432 const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false); 1433 if (!isa<MCSymbolRefExpr>(V)) { 1434 getLexer().UnLex(Tok); // Put back if it's not a bare symbol. 1435 return MatchOperand_NoMatch; 1436 } 1437 Res = V; 1438 } else 1439 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1440 1441 MCBinaryExpr::Opcode Opcode; 1442 switch (getLexer().getKind()) { 1443 default: 1444 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1445 return MatchOperand_Success; 1446 case AsmToken::Plus: 1447 Opcode = MCBinaryExpr::Add; 1448 break; 1449 case AsmToken::Minus: 1450 Opcode = MCBinaryExpr::Sub; 1451 break; 1452 } 1453 1454 const MCExpr *Expr; 1455 if (getParser().parseExpression(Expr)) 1456 return MatchOperand_ParseFail; 1457 Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext()); 1458 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1459 return MatchOperand_Success; 1460 } 1461 1462 OperandMatchResultTy RISCVAsmParser::parseCallSymbol(OperandVector &Operands) { 1463 SMLoc S = getLoc(); 1464 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1465 const MCExpr *Res; 1466 1467 if (getLexer().getKind() != AsmToken::Identifier) 1468 return MatchOperand_NoMatch; 1469 1470 // Avoid parsing the register in `call rd, foo` as a call symbol. 1471 if (getLexer().peekTok().getKind() != AsmToken::EndOfStatement) 1472 return MatchOperand_NoMatch; 1473 1474 StringRef Identifier; 1475 if (getParser().parseIdentifier(Identifier)) 1476 return MatchOperand_ParseFail; 1477 1478 RISCVMCExpr::VariantKind Kind = RISCVMCExpr::VK_RISCV_CALL; 1479 if (Identifier.consume_back("@plt")) 1480 Kind = RISCVMCExpr::VK_RISCV_CALL_PLT; 1481 1482 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); 1483 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1484 Res = RISCVMCExpr::create(Res, Kind, getContext()); 1485 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1486 return MatchOperand_Success; 1487 } 1488 1489 OperandMatchResultTy 1490 RISCVAsmParser::parsePseudoJumpSymbol(OperandVector &Operands) { 1491 SMLoc S = getLoc(); 1492 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1493 const MCExpr *Res; 1494 1495 if (getParser().parseExpression(Res)) 1496 return MatchOperand_ParseFail; 1497 1498 if (Res->getKind() != MCExpr::ExprKind::SymbolRef || 1499 cast<MCSymbolRefExpr>(Res)->getKind() == 1500 MCSymbolRefExpr::VariantKind::VK_PLT) { 1501 Error(S, "operand must be a valid jump target"); 1502 return MatchOperand_ParseFail; 1503 } 1504 1505 Res = RISCVMCExpr::create(Res, RISCVMCExpr::VK_RISCV_CALL, getContext()); 1506 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1507 return MatchOperand_Success; 1508 } 1509 1510 OperandMatchResultTy RISCVAsmParser::parseJALOffset(OperandVector &Operands) { 1511 // Parsing jal operands is fiddly due to the `jal foo` and `jal ra, foo` 1512 // both being acceptable forms. When parsing `jal ra, foo` this function 1513 // will be called for the `ra` register operand in an attempt to match the 1514 // single-operand alias. parseJALOffset must fail for this case. It would 1515 // seem logical to try parse the operand using parseImmediate and return 1516 // NoMatch if the next token is a comma (meaning we must be parsing a jal in 1517 // the second form rather than the first). We can't do this as there's no 1518 // way of rewinding the lexer state. Instead, return NoMatch if this operand 1519 // is an identifier and is followed by a comma. 1520 if (getLexer().is(AsmToken::Identifier) && 1521 getLexer().peekTok().is(AsmToken::Comma)) 1522 return MatchOperand_NoMatch; 1523 1524 return parseImmediate(Operands); 1525 } 1526 1527 OperandMatchResultTy RISCVAsmParser::parseVTypeI(OperandVector &Operands) { 1528 SMLoc S = getLoc(); 1529 if (getLexer().isNot(AsmToken::Identifier)) 1530 return MatchOperand_NoMatch; 1531 1532 SmallVector<AsmToken, 7> VTypeIElements; 1533 // Put all the tokens for vtypei operand into VTypeIElements vector. 1534 while (getLexer().isNot(AsmToken::EndOfStatement)) { 1535 VTypeIElements.push_back(getLexer().getTok()); 1536 getLexer().Lex(); 1537 if (getLexer().is(AsmToken::EndOfStatement)) 1538 break; 1539 if (getLexer().isNot(AsmToken::Comma)) 1540 goto MatchFail; 1541 AsmToken Comma = getLexer().getTok(); 1542 VTypeIElements.push_back(Comma); 1543 getLexer().Lex(); 1544 } 1545 1546 if (VTypeIElements.size() == 7) { 1547 // The VTypeIElements layout is: 1548 // SEW comma LMUL comma TA comma MA 1549 // 0 1 2 3 4 5 6 1550 StringRef Name = VTypeIElements[0].getIdentifier(); 1551 if (!Name.consume_front("e")) 1552 goto MatchFail; 1553 unsigned Sew; 1554 if (Name.getAsInteger(10, Sew)) 1555 goto MatchFail; 1556 if (!RISCVVType::isValidSEW(Sew)) 1557 goto MatchFail; 1558 1559 Name = VTypeIElements[2].getIdentifier(); 1560 if (!Name.consume_front("m")) 1561 goto MatchFail; 1562 // "m" or "mf" 1563 bool Fractional = Name.consume_front("f"); 1564 unsigned Lmul; 1565 if (Name.getAsInteger(10, Lmul)) 1566 goto MatchFail; 1567 if (!RISCVVType::isValidLMUL(Lmul, Fractional)) 1568 goto MatchFail; 1569 1570 // ta or tu 1571 Name = VTypeIElements[4].getIdentifier(); 1572 bool TailAgnostic; 1573 if (Name == "ta") 1574 TailAgnostic = true; 1575 else if (Name == "tu") 1576 TailAgnostic = false; 1577 else 1578 goto MatchFail; 1579 1580 // ma or mu 1581 Name = VTypeIElements[6].getIdentifier(); 1582 bool MaskAgnostic; 1583 if (Name == "ma") 1584 MaskAgnostic = true; 1585 else if (Name == "mu") 1586 MaskAgnostic = false; 1587 else 1588 goto MatchFail; 1589 1590 unsigned LmulLog2 = Log2_32(Lmul); 1591 RISCVII::VLMUL VLMUL = 1592 static_cast<RISCVII::VLMUL>(Fractional ? 8 - LmulLog2 : LmulLog2); 1593 1594 unsigned VTypeI = 1595 RISCVVType::encodeVTYPE(VLMUL, Sew, TailAgnostic, MaskAgnostic); 1596 Operands.push_back(RISCVOperand::createVType(VTypeI, S, isRV64())); 1597 return MatchOperand_Success; 1598 } 1599 1600 // If NoMatch, unlex all the tokens that comprise a vtypei operand 1601 MatchFail: 1602 while (!VTypeIElements.empty()) 1603 getLexer().UnLex(VTypeIElements.pop_back_val()); 1604 return MatchOperand_NoMatch; 1605 } 1606 1607 OperandMatchResultTy RISCVAsmParser::parseMaskReg(OperandVector &Operands) { 1608 switch (getLexer().getKind()) { 1609 default: 1610 return MatchOperand_NoMatch; 1611 case AsmToken::Identifier: 1612 StringRef Name = getLexer().getTok().getIdentifier(); 1613 if (!Name.consume_back(".t")) { 1614 Error(getLoc(), "expected '.t' suffix"); 1615 return MatchOperand_ParseFail; 1616 } 1617 MCRegister RegNo; 1618 matchRegisterNameHelper(isRV32E(), RegNo, Name); 1619 1620 if (RegNo == RISCV::NoRegister) 1621 return MatchOperand_NoMatch; 1622 if (RegNo != RISCV::V0) 1623 return MatchOperand_NoMatch; 1624 SMLoc S = getLoc(); 1625 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1626 getLexer().Lex(); 1627 Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64())); 1628 } 1629 1630 return MatchOperand_Success; 1631 } 1632 1633 OperandMatchResultTy 1634 RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) { 1635 if (getLexer().isNot(AsmToken::LParen)) { 1636 Error(getLoc(), "expected '('"); 1637 return MatchOperand_ParseFail; 1638 } 1639 1640 getParser().Lex(); // Eat '(' 1641 Operands.push_back(RISCVOperand::createToken("(", getLoc(), isRV64())); 1642 1643 if (parseRegister(Operands) != MatchOperand_Success) { 1644 Error(getLoc(), "expected register"); 1645 return MatchOperand_ParseFail; 1646 } 1647 1648 if (getLexer().isNot(AsmToken::RParen)) { 1649 Error(getLoc(), "expected ')'"); 1650 return MatchOperand_ParseFail; 1651 } 1652 1653 getParser().Lex(); // Eat ')' 1654 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64())); 1655 1656 return MatchOperand_Success; 1657 } 1658 1659 OperandMatchResultTy RISCVAsmParser::parseAtomicMemOp(OperandVector &Operands) { 1660 // Atomic operations such as lr.w, sc.w, and amo*.w accept a "memory operand" 1661 // as one of their register operands, such as `(a0)`. This just denotes that 1662 // the register (in this case `a0`) contains a memory address. 1663 // 1664 // Normally, we would be able to parse these by putting the parens into the 1665 // instruction string. However, GNU as also accepts a zero-offset memory 1666 // operand (such as `0(a0)`), and ignores the 0. Normally this would be parsed 1667 // with parseImmediate followed by parseMemOpBaseReg, but these instructions 1668 // do not accept an immediate operand, and we do not want to add a "dummy" 1669 // operand that is silently dropped. 1670 // 1671 // Instead, we use this custom parser. This will: allow (and discard) an 1672 // offset if it is zero; require (and discard) parentheses; and add only the 1673 // parsed register operand to `Operands`. 1674 // 1675 // These operands are printed with RISCVInstPrinter::printAtomicMemOp, which 1676 // will only print the register surrounded by parentheses (which GNU as also 1677 // uses as its canonical representation for these operands). 1678 std::unique_ptr<RISCVOperand> OptionalImmOp; 1679 1680 if (getLexer().isNot(AsmToken::LParen)) { 1681 // Parse an Integer token. We do not accept arbritrary constant expressions 1682 // in the offset field (because they may include parens, which complicates 1683 // parsing a lot). 1684 int64_t ImmVal; 1685 SMLoc ImmStart = getLoc(); 1686 if (getParser().parseIntToken(ImmVal, 1687 "expected '(' or optional integer offset")) 1688 return MatchOperand_ParseFail; 1689 1690 // Create a RISCVOperand for checking later (so the error messages are 1691 // nicer), but we don't add it to Operands. 1692 SMLoc ImmEnd = getLoc(); 1693 OptionalImmOp = 1694 RISCVOperand::createImm(MCConstantExpr::create(ImmVal, getContext()), 1695 ImmStart, ImmEnd, isRV64()); 1696 } 1697 1698 if (getLexer().isNot(AsmToken::LParen)) { 1699 Error(getLoc(), OptionalImmOp ? "expected '(' after optional integer offset" 1700 : "expected '(' or optional integer offset"); 1701 return MatchOperand_ParseFail; 1702 } 1703 getParser().Lex(); // Eat '(' 1704 1705 if (parseRegister(Operands) != MatchOperand_Success) { 1706 Error(getLoc(), "expected register"); 1707 return MatchOperand_ParseFail; 1708 } 1709 1710 if (getLexer().isNot(AsmToken::RParen)) { 1711 Error(getLoc(), "expected ')'"); 1712 return MatchOperand_ParseFail; 1713 } 1714 getParser().Lex(); // Eat ')' 1715 1716 // Deferred Handling of non-zero offsets. This makes the error messages nicer. 1717 if (OptionalImmOp && !OptionalImmOp->isImmZero()) { 1718 Error(OptionalImmOp->getStartLoc(), "optional integer offset must be 0", 1719 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc())); 1720 return MatchOperand_ParseFail; 1721 } 1722 1723 return MatchOperand_Success; 1724 } 1725 1726 /// Looks at a token type and creates the relevant operand from this 1727 /// information, adding to Operands. If operand was parsed, returns false, else 1728 /// true. 1729 bool RISCVAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { 1730 // Check if the current operand has a custom associated parser, if so, try to 1731 // custom parse the operand, or fallback to the general approach. 1732 OperandMatchResultTy Result = 1733 MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true); 1734 if (Result == MatchOperand_Success) 1735 return false; 1736 if (Result == MatchOperand_ParseFail) 1737 return true; 1738 1739 // Attempt to parse token as a register. 1740 if (parseRegister(Operands, true) == MatchOperand_Success) 1741 return false; 1742 1743 // Attempt to parse token as an immediate 1744 if (parseImmediate(Operands) == MatchOperand_Success) { 1745 // Parse memory base register if present 1746 if (getLexer().is(AsmToken::LParen)) 1747 return parseMemOpBaseReg(Operands) != MatchOperand_Success; 1748 return false; 1749 } 1750 1751 // Finally we have exhausted all options and must declare defeat. 1752 Error(getLoc(), "unknown operand"); 1753 return true; 1754 } 1755 1756 bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info, 1757 StringRef Name, SMLoc NameLoc, 1758 OperandVector &Operands) { 1759 // Ensure that if the instruction occurs when relaxation is enabled, 1760 // relocations are forced for the file. Ideally this would be done when there 1761 // is enough information to reliably determine if the instruction itself may 1762 // cause relaxations. Unfortunately instruction processing stage occurs in the 1763 // same pass as relocation emission, so it's too late to set a 'sticky bit' 1764 // for the entire file. 1765 if (getSTI().getFeatureBits()[RISCV::FeatureRelax]) { 1766 auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr(); 1767 if (Assembler != nullptr) { 1768 RISCVAsmBackend &MAB = 1769 static_cast<RISCVAsmBackend &>(Assembler->getBackend()); 1770 MAB.setForceRelocs(); 1771 } 1772 } 1773 1774 // First operand is token for instruction 1775 Operands.push_back(RISCVOperand::createToken(Name, NameLoc, isRV64())); 1776 1777 // If there are no more operands, then finish 1778 if (getLexer().is(AsmToken::EndOfStatement)) 1779 return false; 1780 1781 // Parse first operand 1782 if (parseOperand(Operands, Name)) 1783 return true; 1784 1785 // Parse until end of statement, consuming commas between operands 1786 unsigned OperandIdx = 1; 1787 while (getLexer().is(AsmToken::Comma)) { 1788 // Consume comma token 1789 getLexer().Lex(); 1790 1791 // Parse next operand 1792 if (parseOperand(Operands, Name)) 1793 return true; 1794 1795 ++OperandIdx; 1796 } 1797 1798 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1799 SMLoc Loc = getLexer().getLoc(); 1800 getParser().eatToEndOfStatement(); 1801 return Error(Loc, "unexpected token"); 1802 } 1803 1804 getParser().Lex(); // Consume the EndOfStatement. 1805 return false; 1806 } 1807 1808 bool RISCVAsmParser::classifySymbolRef(const MCExpr *Expr, 1809 RISCVMCExpr::VariantKind &Kind) { 1810 Kind = RISCVMCExpr::VK_RISCV_None; 1811 1812 if (const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) { 1813 Kind = RE->getKind(); 1814 Expr = RE->getSubExpr(); 1815 } 1816 1817 MCValue Res; 1818 MCFixup Fixup; 1819 if (Expr->evaluateAsRelocatable(Res, nullptr, &Fixup)) 1820 return Res.getRefKind() == RISCVMCExpr::VK_RISCV_None; 1821 return false; 1822 } 1823 1824 bool RISCVAsmParser::ParseDirective(AsmToken DirectiveID) { 1825 // This returns false if this function recognizes the directive 1826 // regardless of whether it is successfully handles or reports an 1827 // error. Otherwise it returns true to give the generic parser a 1828 // chance at recognizing it. 1829 StringRef IDVal = DirectiveID.getString(); 1830 1831 if (IDVal == ".option") 1832 return parseDirectiveOption(); 1833 else if (IDVal == ".attribute") 1834 return parseDirectiveAttribute(); 1835 1836 return true; 1837 } 1838 1839 bool RISCVAsmParser::parseDirectiveOption() { 1840 MCAsmParser &Parser = getParser(); 1841 // Get the option token. 1842 AsmToken Tok = Parser.getTok(); 1843 // At the moment only identifiers are supported. 1844 if (Tok.isNot(AsmToken::Identifier)) 1845 return Error(Parser.getTok().getLoc(), 1846 "unexpected token, expected identifier"); 1847 1848 StringRef Option = Tok.getIdentifier(); 1849 1850 if (Option == "push") { 1851 getTargetStreamer().emitDirectiveOptionPush(); 1852 1853 Parser.Lex(); 1854 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1855 return Error(Parser.getTok().getLoc(), 1856 "unexpected token, expected end of statement"); 1857 1858 pushFeatureBits(); 1859 return false; 1860 } 1861 1862 if (Option == "pop") { 1863 SMLoc StartLoc = Parser.getTok().getLoc(); 1864 getTargetStreamer().emitDirectiveOptionPop(); 1865 1866 Parser.Lex(); 1867 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1868 return Error(Parser.getTok().getLoc(), 1869 "unexpected token, expected end of statement"); 1870 1871 if (popFeatureBits()) 1872 return Error(StartLoc, ".option pop with no .option push"); 1873 1874 return false; 1875 } 1876 1877 if (Option == "rvc") { 1878 getTargetStreamer().emitDirectiveOptionRVC(); 1879 1880 Parser.Lex(); 1881 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1882 return Error(Parser.getTok().getLoc(), 1883 "unexpected token, expected end of statement"); 1884 1885 setFeatureBits(RISCV::FeatureStdExtC, "c"); 1886 return false; 1887 } 1888 1889 if (Option == "norvc") { 1890 getTargetStreamer().emitDirectiveOptionNoRVC(); 1891 1892 Parser.Lex(); 1893 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1894 return Error(Parser.getTok().getLoc(), 1895 "unexpected token, expected end of statement"); 1896 1897 clearFeatureBits(RISCV::FeatureStdExtC, "c"); 1898 return false; 1899 } 1900 1901 if (Option == "pic") { 1902 getTargetStreamer().emitDirectiveOptionPIC(); 1903 1904 Parser.Lex(); 1905 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1906 return Error(Parser.getTok().getLoc(), 1907 "unexpected token, expected end of statement"); 1908 1909 ParserOptions.IsPicEnabled = true; 1910 return false; 1911 } 1912 1913 if (Option == "nopic") { 1914 getTargetStreamer().emitDirectiveOptionNoPIC(); 1915 1916 Parser.Lex(); 1917 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1918 return Error(Parser.getTok().getLoc(), 1919 "unexpected token, expected end of statement"); 1920 1921 ParserOptions.IsPicEnabled = false; 1922 return false; 1923 } 1924 1925 if (Option == "relax") { 1926 getTargetStreamer().emitDirectiveOptionRelax(); 1927 1928 Parser.Lex(); 1929 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1930 return Error(Parser.getTok().getLoc(), 1931 "unexpected token, expected end of statement"); 1932 1933 setFeatureBits(RISCV::FeatureRelax, "relax"); 1934 return false; 1935 } 1936 1937 if (Option == "norelax") { 1938 getTargetStreamer().emitDirectiveOptionNoRelax(); 1939 1940 Parser.Lex(); 1941 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1942 return Error(Parser.getTok().getLoc(), 1943 "unexpected token, expected end of statement"); 1944 1945 clearFeatureBits(RISCV::FeatureRelax, "relax"); 1946 return false; 1947 } 1948 1949 // Unknown option. 1950 Warning(Parser.getTok().getLoc(), 1951 "unknown option, expected 'push', 'pop', 'rvc', 'norvc', 'relax' or " 1952 "'norelax'"); 1953 Parser.eatToEndOfStatement(); 1954 return false; 1955 } 1956 1957 /// parseDirectiveAttribute 1958 /// ::= .attribute expression ',' ( expression | "string" ) 1959 /// ::= .attribute identifier ',' ( expression | "string" ) 1960 bool RISCVAsmParser::parseDirectiveAttribute() { 1961 MCAsmParser &Parser = getParser(); 1962 int64_t Tag; 1963 SMLoc TagLoc; 1964 TagLoc = Parser.getTok().getLoc(); 1965 if (Parser.getTok().is(AsmToken::Identifier)) { 1966 StringRef Name = Parser.getTok().getIdentifier(); 1967 Optional<unsigned> Ret = 1968 ELFAttrs::attrTypeFromString(Name, RISCVAttrs::RISCVAttributeTags); 1969 if (!Ret.hasValue()) { 1970 Error(TagLoc, "attribute name not recognised: " + Name); 1971 return false; 1972 } 1973 Tag = Ret.getValue(); 1974 Parser.Lex(); 1975 } else { 1976 const MCExpr *AttrExpr; 1977 1978 TagLoc = Parser.getTok().getLoc(); 1979 if (Parser.parseExpression(AttrExpr)) 1980 return true; 1981 1982 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr); 1983 if (check(!CE, TagLoc, "expected numeric constant")) 1984 return true; 1985 1986 Tag = CE->getValue(); 1987 } 1988 1989 if (Parser.parseToken(AsmToken::Comma, "comma expected")) 1990 return true; 1991 1992 StringRef StringValue; 1993 int64_t IntegerValue = 0; 1994 bool IsIntegerValue = true; 1995 1996 // RISC-V attributes have a string value if the tag number is odd 1997 // and an integer value if the tag number is even. 1998 if (Tag % 2) 1999 IsIntegerValue = false; 2000 2001 SMLoc ValueExprLoc = Parser.getTok().getLoc(); 2002 if (IsIntegerValue) { 2003 const MCExpr *ValueExpr; 2004 if (Parser.parseExpression(ValueExpr)) 2005 return true; 2006 2007 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr); 2008 if (!CE) 2009 return Error(ValueExprLoc, "expected numeric constant"); 2010 IntegerValue = CE->getValue(); 2011 } else { 2012 if (Parser.getTok().isNot(AsmToken::String)) 2013 return Error(Parser.getTok().getLoc(), "expected string constant"); 2014 2015 StringValue = Parser.getTok().getStringContents(); 2016 Parser.Lex(); 2017 } 2018 2019 if (Parser.parseToken(AsmToken::EndOfStatement, 2020 "unexpected token in '.attribute' directive")) 2021 return true; 2022 2023 if (Tag == RISCVAttrs::ARCH) { 2024 StringRef Arch = StringValue; 2025 if (Arch.consume_front("rv32")) 2026 clearFeatureBits(RISCV::Feature64Bit, "64bit"); 2027 else if (Arch.consume_front("rv64")) 2028 setFeatureBits(RISCV::Feature64Bit, "64bit"); 2029 else 2030 return Error(ValueExprLoc, "bad arch string " + Arch); 2031 2032 // .attribute arch overrides the current architecture, so unset all 2033 // currently enabled extensions 2034 clearFeatureBits(RISCV::FeatureRV32E, "e"); 2035 clearFeatureBits(RISCV::FeatureStdExtM, "m"); 2036 clearFeatureBits(RISCV::FeatureStdExtA, "a"); 2037 clearFeatureBits(RISCV::FeatureStdExtF, "f"); 2038 clearFeatureBits(RISCV::FeatureStdExtD, "d"); 2039 clearFeatureBits(RISCV::FeatureStdExtC, "c"); 2040 clearFeatureBits(RISCV::FeatureStdExtB, "experimental-b"); 2041 clearFeatureBits(RISCV::FeatureStdExtV, "experimental-v"); 2042 clearFeatureBits(RISCV::FeatureExtZfh, "experimental-zfh"); 2043 clearFeatureBits(RISCV::FeatureExtZba, "experimental-zba"); 2044 clearFeatureBits(RISCV::FeatureExtZbb, "experimental-zbb"); 2045 clearFeatureBits(RISCV::FeatureExtZbc, "experimental-zbc"); 2046 clearFeatureBits(RISCV::FeatureExtZbe, "experimental-zbe"); 2047 clearFeatureBits(RISCV::FeatureExtZbf, "experimental-zbf"); 2048 clearFeatureBits(RISCV::FeatureExtZbm, "experimental-zbm"); 2049 clearFeatureBits(RISCV::FeatureExtZbp, "experimental-zbp"); 2050 clearFeatureBits(RISCV::FeatureExtZbproposedc, "experimental-zbproposedc"); 2051 clearFeatureBits(RISCV::FeatureExtZbr, "experimental-zbr"); 2052 clearFeatureBits(RISCV::FeatureExtZbs, "experimental-zbs"); 2053 clearFeatureBits(RISCV::FeatureExtZbt, "experimental-zbt"); 2054 clearFeatureBits(RISCV::FeatureExtZvamo, "experimental-zvamo"); 2055 clearFeatureBits(RISCV::FeatureStdExtZvlsseg, "experimental-zvlsseg"); 2056 2057 while (!Arch.empty()) { 2058 bool DropFirst = true; 2059 if (Arch[0] == 'i') 2060 clearFeatureBits(RISCV::FeatureRV32E, "e"); 2061 else if (Arch[0] == 'e') 2062 setFeatureBits(RISCV::FeatureRV32E, "e"); 2063 else if (Arch[0] == 'g') { 2064 clearFeatureBits(RISCV::FeatureRV32E, "e"); 2065 setFeatureBits(RISCV::FeatureStdExtM, "m"); 2066 setFeatureBits(RISCV::FeatureStdExtA, "a"); 2067 setFeatureBits(RISCV::FeatureStdExtF, "f"); 2068 setFeatureBits(RISCV::FeatureStdExtD, "d"); 2069 } else if (Arch[0] == 'm') 2070 setFeatureBits(RISCV::FeatureStdExtM, "m"); 2071 else if (Arch[0] == 'a') 2072 setFeatureBits(RISCV::FeatureStdExtA, "a"); 2073 else if (Arch[0] == 'f') 2074 setFeatureBits(RISCV::FeatureStdExtF, "f"); 2075 else if (Arch[0] == 'd') { 2076 setFeatureBits(RISCV::FeatureStdExtF, "f"); 2077 setFeatureBits(RISCV::FeatureStdExtD, "d"); 2078 } else if (Arch[0] == 'c') { 2079 setFeatureBits(RISCV::FeatureStdExtC, "c"); 2080 } else if (Arch[0] == 'b') { 2081 setFeatureBits(RISCV::FeatureStdExtB, "experimental-b"); 2082 } else if (Arch[0] == 'v') { 2083 setFeatureBits(RISCV::FeatureStdExtV, "experimental-v"); 2084 } else if (Arch[0] == 's' || Arch[0] == 'x' || Arch[0] == 'z') { 2085 StringRef Ext = 2086 Arch.take_until([](char c) { return ::isdigit(c) || c == '_'; }); 2087 if (Ext == "zba") 2088 setFeatureBits(RISCV::FeatureExtZba, "experimental-zba"); 2089 else if (Ext == "zbb") 2090 setFeatureBits(RISCV::FeatureExtZbb, "experimental-zbb"); 2091 else if (Ext == "zbc") 2092 setFeatureBits(RISCV::FeatureExtZbc, "experimental-zbc"); 2093 else if (Ext == "zbe") 2094 setFeatureBits(RISCV::FeatureExtZbe, "experimental-zbe"); 2095 else if (Ext == "zbf") 2096 setFeatureBits(RISCV::FeatureExtZbf, "experimental-zbf"); 2097 else if (Ext == "zbm") 2098 setFeatureBits(RISCV::FeatureExtZbm, "experimental-zbm"); 2099 else if (Ext == "zbp") 2100 setFeatureBits(RISCV::FeatureExtZbp, "experimental-zbp"); 2101 else if (Ext == "zbproposedc") 2102 setFeatureBits(RISCV::FeatureExtZbproposedc, 2103 "experimental-zbproposedc"); 2104 else if (Ext == "zbr") 2105 setFeatureBits(RISCV::FeatureExtZbr, "experimental-zbr"); 2106 else if (Ext == "zbs") 2107 setFeatureBits(RISCV::FeatureExtZbs, "experimental-zbs"); 2108 else if (Ext == "zbt") 2109 setFeatureBits(RISCV::FeatureExtZbt, "experimental-zbt"); 2110 else if (Ext == "zfh") 2111 setFeatureBits(RISCV::FeatureExtZfh, "experimental-zfh"); 2112 else if (Ext == "zvamo") 2113 setFeatureBits(RISCV::FeatureExtZvamo, "experimental-zvamo"); 2114 else if (Ext == "zvlsseg") 2115 setFeatureBits(RISCV::FeatureStdExtZvlsseg, "experimental-zvlsseg"); 2116 else 2117 return Error(ValueExprLoc, "bad arch string " + Ext); 2118 Arch = Arch.drop_until([](char c) { return ::isdigit(c) || c == '_'; }); 2119 DropFirst = false; 2120 } else 2121 return Error(ValueExprLoc, "bad arch string " + Arch); 2122 2123 if (DropFirst) 2124 Arch = Arch.drop_front(1); 2125 int major = 0; 2126 int minor = 0; 2127 Arch.consumeInteger(10, major); 2128 Arch.consume_front("p"); 2129 Arch.consumeInteger(10, minor); 2130 Arch = Arch.drop_while([](char c) { return c == '_'; }); 2131 } 2132 } 2133 2134 if (IsIntegerValue) 2135 getTargetStreamer().emitAttribute(Tag, IntegerValue); 2136 else { 2137 if (Tag != RISCVAttrs::ARCH) { 2138 getTargetStreamer().emitTextAttribute(Tag, StringValue); 2139 } else { 2140 std::string formalArchStr = "rv32"; 2141 if (getFeatureBits(RISCV::Feature64Bit)) 2142 formalArchStr = "rv64"; 2143 if (getFeatureBits(RISCV::FeatureRV32E)) 2144 formalArchStr = (Twine(formalArchStr) + "e1p9").str(); 2145 else 2146 formalArchStr = (Twine(formalArchStr) + "i2p0").str(); 2147 2148 if (getFeatureBits(RISCV::FeatureStdExtM)) 2149 formalArchStr = (Twine(formalArchStr) + "_m2p0").str(); 2150 if (getFeatureBits(RISCV::FeatureStdExtA)) 2151 formalArchStr = (Twine(formalArchStr) + "_a2p0").str(); 2152 if (getFeatureBits(RISCV::FeatureStdExtF)) 2153 formalArchStr = (Twine(formalArchStr) + "_f2p0").str(); 2154 if (getFeatureBits(RISCV::FeatureStdExtD)) 2155 formalArchStr = (Twine(formalArchStr) + "_d2p0").str(); 2156 if (getFeatureBits(RISCV::FeatureStdExtC)) 2157 formalArchStr = (Twine(formalArchStr) + "_c2p0").str(); 2158 if (getFeatureBits(RISCV::FeatureStdExtB)) 2159 formalArchStr = (Twine(formalArchStr) + "_b0p93").str(); 2160 if (getFeatureBits(RISCV::FeatureStdExtV)) 2161 formalArchStr = (Twine(formalArchStr) + "_v0p10").str(); 2162 if (getFeatureBits(RISCV::FeatureExtZfh)) 2163 formalArchStr = (Twine(formalArchStr) + "_zfh0p1").str(); 2164 if (getFeatureBits(RISCV::FeatureExtZba)) 2165 formalArchStr = (Twine(formalArchStr) + "_zba0p93").str(); 2166 if (getFeatureBits(RISCV::FeatureExtZbb)) 2167 formalArchStr = (Twine(formalArchStr) + "_zbb0p93").str(); 2168 if (getFeatureBits(RISCV::FeatureExtZbc)) 2169 formalArchStr = (Twine(formalArchStr) + "_zbc0p93").str(); 2170 if (getFeatureBits(RISCV::FeatureExtZbe)) 2171 formalArchStr = (Twine(formalArchStr) + "_zbe0p93").str(); 2172 if (getFeatureBits(RISCV::FeatureExtZbf)) 2173 formalArchStr = (Twine(formalArchStr) + "_zbf0p93").str(); 2174 if (getFeatureBits(RISCV::FeatureExtZbm)) 2175 formalArchStr = (Twine(formalArchStr) + "_zbm0p93").str(); 2176 if (getFeatureBits(RISCV::FeatureExtZbp)) 2177 formalArchStr = (Twine(formalArchStr) + "_zbp0p93").str(); 2178 if (getFeatureBits(RISCV::FeatureExtZbproposedc)) 2179 formalArchStr = (Twine(formalArchStr) + "_zbproposedc0p93").str(); 2180 if (getFeatureBits(RISCV::FeatureExtZbr)) 2181 formalArchStr = (Twine(formalArchStr) + "_zbr0p93").str(); 2182 if (getFeatureBits(RISCV::FeatureExtZbs)) 2183 formalArchStr = (Twine(formalArchStr) + "_zbs0p93").str(); 2184 if (getFeatureBits(RISCV::FeatureExtZbt)) 2185 formalArchStr = (Twine(formalArchStr) + "_zbt0p93").str(); 2186 if (getFeatureBits(RISCV::FeatureExtZvamo)) 2187 formalArchStr = (Twine(formalArchStr) + "_zvamo0p10").str(); 2188 if (getFeatureBits(RISCV::FeatureStdExtZvlsseg)) 2189 formalArchStr = (Twine(formalArchStr) + "_zvlsseg0p10").str(); 2190 2191 getTargetStreamer().emitTextAttribute(Tag, formalArchStr); 2192 } 2193 } 2194 2195 return false; 2196 } 2197 2198 void RISCVAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) { 2199 MCInst CInst; 2200 bool Res = compressInst(CInst, Inst, getSTI(), S.getContext()); 2201 if (Res) 2202 ++RISCVNumInstrsCompressed; 2203 S.emitInstruction((Res ? CInst : Inst), getSTI()); 2204 } 2205 2206 void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t Value, 2207 MCStreamer &Out) { 2208 RISCVMatInt::InstSeq Seq = RISCVMatInt::generateInstSeq(Value, isRV64()); 2209 2210 MCRegister SrcReg = RISCV::X0; 2211 for (RISCVMatInt::Inst &Inst : Seq) { 2212 if (Inst.Opc == RISCV::LUI) { 2213 emitToStreamer( 2214 Out, MCInstBuilder(RISCV::LUI).addReg(DestReg).addImm(Inst.Imm)); 2215 } else { 2216 emitToStreamer( 2217 Out, MCInstBuilder(Inst.Opc).addReg(DestReg).addReg(SrcReg).addImm( 2218 Inst.Imm)); 2219 } 2220 2221 // Only the first instruction has X0 as its source. 2222 SrcReg = DestReg; 2223 } 2224 } 2225 2226 void RISCVAsmParser::emitAuipcInstPair(MCOperand DestReg, MCOperand TmpReg, 2227 const MCExpr *Symbol, 2228 RISCVMCExpr::VariantKind VKHi, 2229 unsigned SecondOpcode, SMLoc IDLoc, 2230 MCStreamer &Out) { 2231 // A pair of instructions for PC-relative addressing; expands to 2232 // TmpLabel: AUIPC TmpReg, VKHi(symbol) 2233 // OP DestReg, TmpReg, %pcrel_lo(TmpLabel) 2234 MCContext &Ctx = getContext(); 2235 2236 MCSymbol *TmpLabel = Ctx.createNamedTempSymbol("pcrel_hi"); 2237 Out.emitLabel(TmpLabel); 2238 2239 const RISCVMCExpr *SymbolHi = RISCVMCExpr::create(Symbol, VKHi, Ctx); 2240 emitToStreamer( 2241 Out, MCInstBuilder(RISCV::AUIPC).addOperand(TmpReg).addExpr(SymbolHi)); 2242 2243 const MCExpr *RefToLinkTmpLabel = 2244 RISCVMCExpr::create(MCSymbolRefExpr::create(TmpLabel, Ctx), 2245 RISCVMCExpr::VK_RISCV_PCREL_LO, Ctx); 2246 2247 emitToStreamer(Out, MCInstBuilder(SecondOpcode) 2248 .addOperand(DestReg) 2249 .addOperand(TmpReg) 2250 .addExpr(RefToLinkTmpLabel)); 2251 } 2252 2253 void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, 2254 MCStreamer &Out) { 2255 // The load local address pseudo-instruction "lla" is used in PC-relative 2256 // addressing of local symbols: 2257 // lla rdest, symbol 2258 // expands to 2259 // TmpLabel: AUIPC rdest, %pcrel_hi(symbol) 2260 // ADDI rdest, rdest, %pcrel_lo(TmpLabel) 2261 MCOperand DestReg = Inst.getOperand(0); 2262 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 2263 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI, 2264 RISCV::ADDI, IDLoc, Out); 2265 } 2266 2267 void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc, 2268 MCStreamer &Out) { 2269 // The load address pseudo-instruction "la" is used in PC-relative and 2270 // GOT-indirect addressing of global symbols: 2271 // la rdest, symbol 2272 // expands to either (for non-PIC) 2273 // TmpLabel: AUIPC rdest, %pcrel_hi(symbol) 2274 // ADDI rdest, rdest, %pcrel_lo(TmpLabel) 2275 // or (for PIC) 2276 // TmpLabel: AUIPC rdest, %got_pcrel_hi(symbol) 2277 // Lx rdest, %pcrel_lo(TmpLabel)(rdest) 2278 MCOperand DestReg = Inst.getOperand(0); 2279 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 2280 unsigned SecondOpcode; 2281 RISCVMCExpr::VariantKind VKHi; 2282 if (ParserOptions.IsPicEnabled) { 2283 SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW; 2284 VKHi = RISCVMCExpr::VK_RISCV_GOT_HI; 2285 } else { 2286 SecondOpcode = RISCV::ADDI; 2287 VKHi = RISCVMCExpr::VK_RISCV_PCREL_HI; 2288 } 2289 emitAuipcInstPair(DestReg, DestReg, Symbol, VKHi, SecondOpcode, IDLoc, Out); 2290 } 2291 2292 void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc, 2293 MCStreamer &Out) { 2294 // The load TLS IE address pseudo-instruction "la.tls.ie" is used in 2295 // initial-exec TLS model addressing of global symbols: 2296 // la.tls.ie rdest, symbol 2297 // expands to 2298 // TmpLabel: AUIPC rdest, %tls_ie_pcrel_hi(symbol) 2299 // Lx rdest, %pcrel_lo(TmpLabel)(rdest) 2300 MCOperand DestReg = Inst.getOperand(0); 2301 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 2302 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW; 2303 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_TLS_GOT_HI, 2304 SecondOpcode, IDLoc, Out); 2305 } 2306 2307 void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, 2308 MCStreamer &Out) { 2309 // The load TLS GD address pseudo-instruction "la.tls.gd" is used in 2310 // global-dynamic TLS model addressing of global symbols: 2311 // la.tls.gd rdest, symbol 2312 // expands to 2313 // TmpLabel: AUIPC rdest, %tls_gd_pcrel_hi(symbol) 2314 // ADDI rdest, rdest, %pcrel_lo(TmpLabel) 2315 MCOperand DestReg = Inst.getOperand(0); 2316 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 2317 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_TLS_GD_HI, 2318 RISCV::ADDI, IDLoc, Out); 2319 } 2320 2321 void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode, 2322 SMLoc IDLoc, MCStreamer &Out, 2323 bool HasTmpReg) { 2324 // The load/store pseudo-instruction does a pc-relative load with 2325 // a symbol. 2326 // 2327 // The expansion looks like this 2328 // 2329 // TmpLabel: AUIPC tmp, %pcrel_hi(symbol) 2330 // [S|L]X rd, %pcrel_lo(TmpLabel)(tmp) 2331 MCOperand DestReg = Inst.getOperand(0); 2332 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1; 2333 unsigned TmpRegOpIdx = HasTmpReg ? 1 : 0; 2334 MCOperand TmpReg = Inst.getOperand(TmpRegOpIdx); 2335 const MCExpr *Symbol = Inst.getOperand(SymbolOpIdx).getExpr(); 2336 emitAuipcInstPair(DestReg, TmpReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI, 2337 Opcode, IDLoc, Out); 2338 } 2339 2340 void RISCVAsmParser::emitPseudoExtend(MCInst &Inst, bool SignExtend, 2341 int64_t Width, SMLoc IDLoc, 2342 MCStreamer &Out) { 2343 // The sign/zero extend pseudo-instruction does two shifts, with the shift 2344 // amounts dependent on the XLEN. 2345 // 2346 // The expansion looks like this 2347 // 2348 // SLLI rd, rs, XLEN - Width 2349 // SR[A|R]I rd, rd, XLEN - Width 2350 MCOperand DestReg = Inst.getOperand(0); 2351 MCOperand SourceReg = Inst.getOperand(1); 2352 2353 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI; 2354 int64_t ShAmt = (isRV64() ? 64 : 32) - Width; 2355 2356 assert(ShAmt > 0 && "Shift amount must be non-zero."); 2357 2358 emitToStreamer(Out, MCInstBuilder(RISCV::SLLI) 2359 .addOperand(DestReg) 2360 .addOperand(SourceReg) 2361 .addImm(ShAmt)); 2362 2363 emitToStreamer(Out, MCInstBuilder(SecondOpcode) 2364 .addOperand(DestReg) 2365 .addOperand(DestReg) 2366 .addImm(ShAmt)); 2367 } 2368 2369 void RISCVAsmParser::emitVMSGE(MCInst &Inst, unsigned Opcode, SMLoc IDLoc, 2370 MCStreamer &Out) { 2371 if (Inst.getNumOperands() == 3) { 2372 // unmasked va >= x 2373 // 2374 // pseudoinstruction: vmsge{u}.vx vd, va, x 2375 // expansion: vmslt{u}.vx vd, va, x; vmnand.mm vd, vd, vd 2376 emitToStreamer(Out, MCInstBuilder(Opcode) 2377 .addOperand(Inst.getOperand(0)) 2378 .addOperand(Inst.getOperand(1)) 2379 .addOperand(Inst.getOperand(2)) 2380 .addReg(RISCV::NoRegister)); 2381 emitToStreamer(Out, MCInstBuilder(RISCV::VMNAND_MM) 2382 .addOperand(Inst.getOperand(0)) 2383 .addOperand(Inst.getOperand(0)) 2384 .addOperand(Inst.getOperand(0))); 2385 } else if (Inst.getNumOperands() == 4) { 2386 // masked va >= x, vd != v0 2387 // 2388 // pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t 2389 // expansion: vmslt{u}.vx vd, va, x, v0.t; vmxor.mm vd, vd, v0 2390 assert(Inst.getOperand(0).getReg() != RISCV::V0 && 2391 "The destination register should not be V0."); 2392 emitToStreamer(Out, MCInstBuilder(Opcode) 2393 .addOperand(Inst.getOperand(0)) 2394 .addOperand(Inst.getOperand(1)) 2395 .addOperand(Inst.getOperand(2)) 2396 .addOperand(Inst.getOperand(3))); 2397 emitToStreamer(Out, MCInstBuilder(RISCV::VMXOR_MM) 2398 .addOperand(Inst.getOperand(0)) 2399 .addOperand(Inst.getOperand(0)) 2400 .addReg(RISCV::V0)); 2401 } else if (Inst.getNumOperands() == 5 && 2402 Inst.getOperand(0).getReg() == RISCV::V0) { 2403 // masked va >= x, vd == v0 2404 // 2405 // pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t, vt 2406 // expansion: vmslt{u}.vx vt, va, x; vmandnot.mm vd, vd, vt 2407 assert(Inst.getOperand(0).getReg() == RISCV::V0 && 2408 "The destination register should be V0."); 2409 assert(Inst.getOperand(1).getReg() != RISCV::V0 && 2410 "The temporary vector register should not be V0."); 2411 emitToStreamer(Out, MCInstBuilder(Opcode) 2412 .addOperand(Inst.getOperand(1)) 2413 .addOperand(Inst.getOperand(2)) 2414 .addOperand(Inst.getOperand(3)) 2415 .addOperand(Inst.getOperand(4))); 2416 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDNOT_MM) 2417 .addOperand(Inst.getOperand(0)) 2418 .addOperand(Inst.getOperand(0)) 2419 .addOperand(Inst.getOperand(1))); 2420 } else if (Inst.getNumOperands() == 5) { 2421 // masked va >= x, any vd 2422 // 2423 // pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t, vt 2424 // expansion: vmslt{u}.vx vt, va, x; vmandnot.mm vt, v0, vt; vmandnot.mm vd, 2425 // vd, v0; vmor.mm vd, vt, vd 2426 assert(Inst.getOperand(1).getReg() != RISCV::V0 && 2427 "The temporary vector register should not be V0."); 2428 emitToStreamer(Out, MCInstBuilder(Opcode) 2429 .addOperand(Inst.getOperand(1)) 2430 .addOperand(Inst.getOperand(2)) 2431 .addOperand(Inst.getOperand(3)) 2432 .addReg(RISCV::NoRegister)); 2433 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDNOT_MM) 2434 .addOperand(Inst.getOperand(1)) 2435 .addReg(RISCV::V0) 2436 .addOperand(Inst.getOperand(1))); 2437 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDNOT_MM) 2438 .addOperand(Inst.getOperand(0)) 2439 .addOperand(Inst.getOperand(0)) 2440 .addReg(RISCV::V0)); 2441 emitToStreamer(Out, MCInstBuilder(RISCV::VMOR_MM) 2442 .addOperand(Inst.getOperand(0)) 2443 .addOperand(Inst.getOperand(1)) 2444 .addOperand(Inst.getOperand(0))); 2445 } 2446 } 2447 2448 bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst, 2449 OperandVector &Operands) { 2450 assert(Inst.getOpcode() == RISCV::PseudoAddTPRel && "Invalid instruction"); 2451 assert(Inst.getOperand(2).isReg() && "Unexpected second operand kind"); 2452 if (Inst.getOperand(2).getReg() != RISCV::X4) { 2453 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc(); 2454 return Error(ErrorLoc, "the second input operand must be tp/x4 when using " 2455 "%tprel_add modifier"); 2456 } 2457 2458 return false; 2459 } 2460 2461 std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp() const { 2462 return RISCVOperand::createReg(RISCV::NoRegister, llvm::SMLoc(), 2463 llvm::SMLoc(), isRV64()); 2464 } 2465 2466 bool RISCVAsmParser::validateInstruction(MCInst &Inst, 2467 OperandVector &Operands) { 2468 if (Inst.getOpcode() == RISCV::PseudoVMSGEU_VX_M_T || 2469 Inst.getOpcode() == RISCV::PseudoVMSGE_VX_M_T) { 2470 unsigned DestReg = Inst.getOperand(0).getReg(); 2471 unsigned TempReg = Inst.getOperand(1).getReg(); 2472 if (DestReg == TempReg) { 2473 SMLoc Loc = Operands.back()->getStartLoc(); 2474 return Error(Loc, "The temporary vector register cannot be the same as " 2475 "the destination register."); 2476 } 2477 } 2478 2479 const MCInstrDesc &MCID = MII.get(Inst.getOpcode()); 2480 RISCVII::VConstraintType Constraints = 2481 RISCVII::getConstraint(MCID.TSFlags); 2482 if (Constraints == RISCVII::NoConstraint) 2483 return false; 2484 2485 unsigned DestReg = Inst.getOperand(0).getReg(); 2486 // Operands[1] will be the first operand, DestReg. 2487 SMLoc Loc = Operands[1]->getStartLoc(); 2488 if (Constraints & RISCVII::VS2Constraint) { 2489 unsigned CheckReg = Inst.getOperand(1).getReg(); 2490 if (DestReg == CheckReg) 2491 return Error(Loc, "The destination vector register group cannot overlap" 2492 " the source vector register group."); 2493 } 2494 if ((Constraints & RISCVII::VS1Constraint) && (Inst.getOperand(2).isReg())) { 2495 unsigned CheckReg = Inst.getOperand(2).getReg(); 2496 if (DestReg == CheckReg) 2497 return Error(Loc, "The destination vector register group cannot overlap" 2498 " the source vector register group."); 2499 } 2500 if ((Constraints & RISCVII::VMConstraint) && (DestReg == RISCV::V0)) { 2501 // vadc, vsbc are special cases. These instructions have no mask register. 2502 // The destination register could not be V0. 2503 unsigned Opcode = Inst.getOpcode(); 2504 if (Opcode == RISCV::VADC_VVM || Opcode == RISCV::VADC_VXM || 2505 Opcode == RISCV::VADC_VIM || Opcode == RISCV::VSBC_VVM || 2506 Opcode == RISCV::VSBC_VXM || Opcode == RISCV::VFMERGE_VFM || 2507 Opcode == RISCV::VMERGE_VIM || Opcode == RISCV::VMERGE_VVM || 2508 Opcode == RISCV::VMERGE_VXM) 2509 return Error(Loc, "The destination vector register group cannot be V0."); 2510 2511 // Regardless masked or unmasked version, the number of operands is the 2512 // same. For example, "viota.m v0, v2" is "viota.m v0, v2, NoRegister" 2513 // actually. We need to check the last operand to ensure whether it is 2514 // masked or not. 2515 unsigned CheckReg = Inst.getOperand(Inst.getNumOperands() - 1).getReg(); 2516 assert((CheckReg == RISCV::V0 || CheckReg == RISCV::NoRegister) && 2517 "Unexpected register for mask operand"); 2518 2519 if (DestReg == CheckReg) 2520 return Error(Loc, "The destination vector register group cannot overlap" 2521 " the mask register."); 2522 } 2523 return false; 2524 } 2525 2526 bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 2527 OperandVector &Operands, 2528 MCStreamer &Out) { 2529 Inst.setLoc(IDLoc); 2530 2531 switch (Inst.getOpcode()) { 2532 default: 2533 break; 2534 case RISCV::PseudoLI: { 2535 MCRegister Reg = Inst.getOperand(0).getReg(); 2536 const MCOperand &Op1 = Inst.getOperand(1); 2537 if (Op1.isExpr()) { 2538 // We must have li reg, %lo(sym) or li reg, %pcrel_lo(sym) or similar. 2539 // Just convert to an addi. This allows compatibility with gas. 2540 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI) 2541 .addReg(Reg) 2542 .addReg(RISCV::X0) 2543 .addExpr(Op1.getExpr())); 2544 return false; 2545 } 2546 int64_t Imm = Inst.getOperand(1).getImm(); 2547 // On RV32 the immediate here can either be a signed or an unsigned 2548 // 32-bit number. Sign extension has to be performed to ensure that Imm 2549 // represents the expected signed 64-bit number. 2550 if (!isRV64()) 2551 Imm = SignExtend64<32>(Imm); 2552 emitLoadImm(Reg, Imm, Out); 2553 return false; 2554 } 2555 case RISCV::PseudoLLA: 2556 emitLoadLocalAddress(Inst, IDLoc, Out); 2557 return false; 2558 case RISCV::PseudoLA: 2559 emitLoadAddress(Inst, IDLoc, Out); 2560 return false; 2561 case RISCV::PseudoLA_TLS_IE: 2562 emitLoadTLSIEAddress(Inst, IDLoc, Out); 2563 return false; 2564 case RISCV::PseudoLA_TLS_GD: 2565 emitLoadTLSGDAddress(Inst, IDLoc, Out); 2566 return false; 2567 case RISCV::PseudoLB: 2568 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out, /*HasTmpReg=*/false); 2569 return false; 2570 case RISCV::PseudoLBU: 2571 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out, /*HasTmpReg=*/false); 2572 return false; 2573 case RISCV::PseudoLH: 2574 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out, /*HasTmpReg=*/false); 2575 return false; 2576 case RISCV::PseudoLHU: 2577 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out, /*HasTmpReg=*/false); 2578 return false; 2579 case RISCV::PseudoLW: 2580 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out, /*HasTmpReg=*/false); 2581 return false; 2582 case RISCV::PseudoLWU: 2583 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out, /*HasTmpReg=*/false); 2584 return false; 2585 case RISCV::PseudoLD: 2586 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out, /*HasTmpReg=*/false); 2587 return false; 2588 case RISCV::PseudoFLH: 2589 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out, /*HasTmpReg=*/true); 2590 return false; 2591 case RISCV::PseudoFLW: 2592 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out, /*HasTmpReg=*/true); 2593 return false; 2594 case RISCV::PseudoFLD: 2595 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out, /*HasTmpReg=*/true); 2596 return false; 2597 case RISCV::PseudoSB: 2598 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out, /*HasTmpReg=*/true); 2599 return false; 2600 case RISCV::PseudoSH: 2601 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out, /*HasTmpReg=*/true); 2602 return false; 2603 case RISCV::PseudoSW: 2604 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out, /*HasTmpReg=*/true); 2605 return false; 2606 case RISCV::PseudoSD: 2607 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out, /*HasTmpReg=*/true); 2608 return false; 2609 case RISCV::PseudoFSH: 2610 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out, /*HasTmpReg=*/true); 2611 return false; 2612 case RISCV::PseudoFSW: 2613 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out, /*HasTmpReg=*/true); 2614 return false; 2615 case RISCV::PseudoFSD: 2616 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out, /*HasTmpReg=*/true); 2617 return false; 2618 case RISCV::PseudoAddTPRel: 2619 if (checkPseudoAddTPRel(Inst, Operands)) 2620 return true; 2621 break; 2622 case RISCV::PseudoSEXT_B: 2623 emitPseudoExtend(Inst, /*SignExtend=*/true, /*Width=*/8, IDLoc, Out); 2624 return false; 2625 case RISCV::PseudoSEXT_H: 2626 emitPseudoExtend(Inst, /*SignExtend=*/true, /*Width=*/16, IDLoc, Out); 2627 return false; 2628 case RISCV::PseudoZEXT_H: 2629 emitPseudoExtend(Inst, /*SignExtend=*/false, /*Width=*/16, IDLoc, Out); 2630 return false; 2631 case RISCV::PseudoZEXT_W: 2632 emitPseudoExtend(Inst, /*SignExtend=*/false, /*Width=*/32, IDLoc, Out); 2633 return false; 2634 case RISCV::PseudoVMSGEU_VX: 2635 case RISCV::PseudoVMSGEU_VX_M: 2636 case RISCV::PseudoVMSGEU_VX_M_T: 2637 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out); 2638 return false; 2639 case RISCV::PseudoVMSGE_VX: 2640 case RISCV::PseudoVMSGE_VX_M: 2641 case RISCV::PseudoVMSGE_VX_M_T: 2642 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out); 2643 return false; 2644 case RISCV::PseudoVMSGE_VI: 2645 case RISCV::PseudoVMSLT_VI: { 2646 // These instructions are signed and so is immediate so we can subtract one 2647 // and change the opcode. 2648 int64_t Imm = Inst.getOperand(2).getImm(); 2649 unsigned Opc = Inst.getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI 2650 : RISCV::VMSLE_VI; 2651 emitToStreamer(Out, MCInstBuilder(Opc) 2652 .addOperand(Inst.getOperand(0)) 2653 .addOperand(Inst.getOperand(1)) 2654 .addImm(Imm - 1) 2655 .addOperand(Inst.getOperand(3))); 2656 return false; 2657 } 2658 case RISCV::PseudoVMSGEU_VI: 2659 case RISCV::PseudoVMSLTU_VI: { 2660 int64_t Imm = Inst.getOperand(2).getImm(); 2661 // Unsigned comparisons are tricky because the immediate is signed. If the 2662 // immediate is 0 we can't just subtract one. vmsltu.vi v0, v1, 0 is always 2663 // false, but vmsle.vi v0, v1, -1 is always true. Instead we use 2664 // vmsne v0, v1, v1 which is always false. 2665 if (Imm == 0) { 2666 unsigned Opc = Inst.getOpcode() == RISCV::PseudoVMSGEU_VI 2667 ? RISCV::VMSEQ_VV 2668 : RISCV::VMSNE_VV; 2669 emitToStreamer(Out, MCInstBuilder(Opc) 2670 .addOperand(Inst.getOperand(0)) 2671 .addOperand(Inst.getOperand(1)) 2672 .addOperand(Inst.getOperand(1)) 2673 .addOperand(Inst.getOperand(3))); 2674 } else { 2675 // Other immediate values can subtract one like signed. 2676 unsigned Opc = Inst.getOpcode() == RISCV::PseudoVMSGEU_VI 2677 ? RISCV::VMSGTU_VI 2678 : RISCV::VMSLEU_VI; 2679 emitToStreamer(Out, MCInstBuilder(Opc) 2680 .addOperand(Inst.getOperand(0)) 2681 .addOperand(Inst.getOperand(1)) 2682 .addImm(Imm - 1) 2683 .addOperand(Inst.getOperand(3))); 2684 } 2685 2686 return false; 2687 } 2688 } 2689 2690 emitToStreamer(Out, Inst); 2691 return false; 2692 } 2693 2694 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVAsmParser() { 2695 RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target()); 2696 RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target()); 2697 } 2698