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