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