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