xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp (revision cb14a3fe5122c879eae1fb480ed7ce82a699ddb6)
1 //===-- RISCVAsmParser.cpp - Parse RISC-V 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/SmallVector.h"
20 #include "llvm/ADT/Statistic.h"
21 #include "llvm/ADT/StringExtras.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/MCInstrInfo.h"
28 #include "llvm/MC/MCObjectFileInfo.h"
29 #include "llvm/MC/MCParser/MCAsmLexer.h"
30 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
31 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
32 #include "llvm/MC/MCRegisterInfo.h"
33 #include "llvm/MC/MCStreamer.h"
34 #include "llvm/MC/MCSubtargetInfo.h"
35 #include "llvm/MC/MCValue.h"
36 #include "llvm/MC/TargetRegistry.h"
37 #include "llvm/Support/Casting.h"
38 #include "llvm/Support/CommandLine.h"
39 #include "llvm/Support/MathExtras.h"
40 #include "llvm/Support/RISCVAttributes.h"
41 #include "llvm/Support/RISCVISAInfo.h"
42 
43 #include <limits>
44 
45 using namespace llvm;
46 
47 #define DEBUG_TYPE "riscv-asm-parser"
48 
49 STATISTIC(RISCVNumInstrsCompressed,
50           "Number of RISC-V Compressed instructions emitted");
51 
52 static cl::opt<bool> AddBuildAttributes("riscv-add-build-attributes",
53                                         cl::init(false));
54 
55 namespace llvm {
56 extern const SubtargetFeatureKV RISCVFeatureKV[RISCV::NumSubtargetFeatures];
57 } // namespace llvm
58 
59 namespace {
60 struct RISCVOperand;
61 
62 struct ParserOptionsSet {
63   bool IsPicEnabled;
64 };
65 
66 class RISCVAsmParser : public MCTargetAsmParser {
67   // This tracks the parsing of the 4 operands that make up the vtype portion
68   // of vset(i)vli instructions which are separated by commas. The state names
69   // represent the next expected operand with Done meaning no other operands are
70   // expected.
71   enum VTypeState {
72     VTypeState_SEW,
73     VTypeState_LMUL,
74     VTypeState_TailPolicy,
75     VTypeState_MaskPolicy,
76     VTypeState_Done,
77   };
78 
79   SmallVector<FeatureBitset, 4> FeatureBitStack;
80 
81   SmallVector<ParserOptionsSet, 4> ParserOptionsStack;
82   ParserOptionsSet ParserOptions;
83 
84   SMLoc getLoc() const { return getParser().getTok().getLoc(); }
85   bool isRV64() const { return getSTI().hasFeature(RISCV::Feature64Bit); }
86   bool isRVE() const { return getSTI().hasFeature(RISCV::FeatureRVE); }
87 
88   RISCVTargetStreamer &getTargetStreamer() {
89     assert(getParser().getStreamer().getTargetStreamer() &&
90            "do not have a target streamer");
91     MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
92     return static_cast<RISCVTargetStreamer &>(TS);
93   }
94 
95   unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
96                                       unsigned Kind) override;
97   unsigned checkTargetMatchPredicate(MCInst &Inst) override;
98 
99   bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo,
100                                   int64_t Lower, int64_t Upper,
101                                   const Twine &Msg);
102   bool generateImmOutOfRangeError(SMLoc ErrorLoc, int64_t Lower, int64_t Upper,
103                                   const Twine &Msg);
104 
105   bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
106                                OperandVector &Operands, MCStreamer &Out,
107                                uint64_t &ErrorInfo,
108                                bool MatchingInlineAsm) override;
109 
110   bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;
111   ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
112                                SMLoc &EndLoc) override;
113 
114   bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
115                         SMLoc NameLoc, OperandVector &Operands) override;
116 
117   ParseStatus parseDirective(AsmToken DirectiveID) override;
118 
119   bool parseVTypeToken(StringRef Identifier, VTypeState &State, unsigned &Sew,
120                        unsigned &Lmul, bool &Fractional, bool &TailAgnostic,
121                        bool &MaskAgnostic);
122   bool generateVTypeError(SMLoc ErrorLoc);
123 
124   // Helper to actually emit an instruction to the MCStreamer. Also, when
125   // possible, compression of the instruction is performed.
126   void emitToStreamer(MCStreamer &S, const MCInst &Inst);
127 
128   // Helper to emit a combination of LUI, ADDI(W), and SLLI instructions that
129   // synthesize the desired immedate value into the destination register.
130   void emitLoadImm(MCRegister DestReg, int64_t Value, MCStreamer &Out);
131 
132   // Helper to emit a combination of AUIPC and SecondOpcode. Used to implement
133   // helpers such as emitLoadLocalAddress and emitLoadAddress.
134   void emitAuipcInstPair(MCOperand DestReg, MCOperand TmpReg,
135                          const MCExpr *Symbol, RISCVMCExpr::VariantKind VKHi,
136                          unsigned SecondOpcode, SMLoc IDLoc, MCStreamer &Out);
137 
138   // Helper to emit pseudo instruction "lla" used in PC-rel addressing.
139   void emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
140 
141   // Helper to emit pseudo instruction "lga" used in GOT-rel addressing.
142   void emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
143 
144   // Helper to emit pseudo instruction "la" used in GOT/PC-rel addressing.
145   void emitLoadAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
146 
147   // Helper to emit pseudo instruction "la.tls.ie" used in initial-exec TLS
148   // addressing.
149   void emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
150 
151   // Helper to emit pseudo instruction "la.tls.gd" used in global-dynamic TLS
152   // addressing.
153   void emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
154 
155   // Helper to emit pseudo load/store instruction with a symbol.
156   void emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode, SMLoc IDLoc,
157                            MCStreamer &Out, bool HasTmpReg);
158 
159   // Helper to emit pseudo sign/zero extend instruction.
160   void emitPseudoExtend(MCInst &Inst, bool SignExtend, int64_t Width,
161                         SMLoc IDLoc, MCStreamer &Out);
162 
163   // Helper to emit pseudo vmsge{u}.vx instruction.
164   void emitVMSGE(MCInst &Inst, unsigned Opcode, SMLoc IDLoc, MCStreamer &Out);
165 
166   // Checks that a PseudoAddTPRel is using x4/tp in its second input operand.
167   // Enforcing this using a restricted register class for the second input
168   // operand of PseudoAddTPRel results in a poor diagnostic due to the fact
169   // 'add' is an overloaded mnemonic.
170   bool checkPseudoAddTPRel(MCInst &Inst, OperandVector &Operands);
171 
172   // Check instruction constraints.
173   bool validateInstruction(MCInst &Inst, OperandVector &Operands);
174 
175   /// Helper for processing MC instructions that have been successfully matched
176   /// by MatchAndEmitInstruction. Modifications to the emitted instructions,
177   /// like the expansion of pseudo instructions (e.g., "li"), can be performed
178   /// in this method.
179   bool processInstruction(MCInst &Inst, SMLoc IDLoc, OperandVector &Operands,
180                           MCStreamer &Out);
181 
182 // Auto-generated instruction matching functions
183 #define GET_ASSEMBLER_HEADER
184 #include "RISCVGenAsmMatcher.inc"
185 
186   ParseStatus parseCSRSystemRegister(OperandVector &Operands);
187   ParseStatus parseFPImm(OperandVector &Operands);
188   ParseStatus parseImmediate(OperandVector &Operands);
189   ParseStatus parseRegister(OperandVector &Operands, bool AllowParens = false);
190   ParseStatus parseMemOpBaseReg(OperandVector &Operands);
191   ParseStatus parseZeroOffsetMemOp(OperandVector &Operands);
192   ParseStatus parseOperandWithModifier(OperandVector &Operands);
193   ParseStatus parseBareSymbol(OperandVector &Operands);
194   ParseStatus parseCallSymbol(OperandVector &Operands);
195   ParseStatus parsePseudoJumpSymbol(OperandVector &Operands);
196   ParseStatus parseJALOffset(OperandVector &Operands);
197   ParseStatus parseVTypeI(OperandVector &Operands);
198   ParseStatus parseMaskReg(OperandVector &Operands);
199   ParseStatus parseInsnDirectiveOpcode(OperandVector &Operands);
200   ParseStatus parseInsnCDirectiveOpcode(OperandVector &Operands);
201   ParseStatus parseGPRAsFPR(OperandVector &Operands);
202   ParseStatus parseFRMArg(OperandVector &Operands);
203   ParseStatus parseFenceArg(OperandVector &Operands);
204   ParseStatus parseReglist(OperandVector &Operands);
205   ParseStatus parseRegReg(OperandVector &Operands);
206   ParseStatus parseRetval(OperandVector &Operands);
207   ParseStatus parseZcmpSpimm(OperandVector &Operands);
208 
209   bool parseOperand(OperandVector &Operands, StringRef Mnemonic);
210 
211   bool parseDirectiveOption();
212   bool parseDirectiveAttribute();
213   bool parseDirectiveInsn(SMLoc L);
214   bool parseDirectiveVariantCC();
215 
216   /// Helper to reset target features for a new arch string. It
217   /// also records the new arch string that is expanded by RISCVISAInfo
218   /// and reports error for invalid arch string.
219   bool resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
220                    bool FromOptionDirective);
221 
222   void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
223     if (!(getSTI().hasFeature(Feature))) {
224       MCSubtargetInfo &STI = copySTI();
225       setAvailableFeatures(
226           ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
227     }
228   }
229 
230   void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
231     if (getSTI().hasFeature(Feature)) {
232       MCSubtargetInfo &STI = copySTI();
233       setAvailableFeatures(
234           ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
235     }
236   }
237 
238   void pushFeatureBits() {
239     assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
240            "These two stacks must be kept synchronized");
241     FeatureBitStack.push_back(getSTI().getFeatureBits());
242     ParserOptionsStack.push_back(ParserOptions);
243   }
244 
245   bool popFeatureBits() {
246     assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
247            "These two stacks must be kept synchronized");
248     if (FeatureBitStack.empty())
249       return true;
250 
251     FeatureBitset FeatureBits = FeatureBitStack.pop_back_val();
252     copySTI().setFeatureBits(FeatureBits);
253     setAvailableFeatures(ComputeAvailableFeatures(FeatureBits));
254 
255     ParserOptions = ParserOptionsStack.pop_back_val();
256 
257     return false;
258   }
259 
260   std::unique_ptr<RISCVOperand> defaultMaskRegOp() const;
261   std::unique_ptr<RISCVOperand> defaultFRMArgOp() const;
262   std::unique_ptr<RISCVOperand> defaultFRMArgLegacyOp() const;
263 
264 public:
265   enum RISCVMatchResultTy {
266     Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
267     Match_RequiresEvenGPRs,
268 #define GET_OPERAND_DIAGNOSTIC_TYPES
269 #include "RISCVGenAsmMatcher.inc"
270 #undef GET_OPERAND_DIAGNOSTIC_TYPES
271   };
272 
273   static bool classifySymbolRef(const MCExpr *Expr,
274                                 RISCVMCExpr::VariantKind &Kind);
275   static bool isSymbolDiff(const MCExpr *Expr);
276 
277   RISCVAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
278                  const MCInstrInfo &MII, const MCTargetOptions &Options)
279       : MCTargetAsmParser(Options, STI, MII) {
280     MCAsmParserExtension::Initialize(Parser);
281 
282     Parser.addAliasForDirective(".half", ".2byte");
283     Parser.addAliasForDirective(".hword", ".2byte");
284     Parser.addAliasForDirective(".word", ".4byte");
285     Parser.addAliasForDirective(".dword", ".8byte");
286     setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
287 
288     auto ABIName = StringRef(Options.ABIName);
289     if (ABIName.ends_with("f") && !getSTI().hasFeature(RISCV::FeatureStdExtF)) {
290       errs() << "Hard-float 'f' ABI can't be used for a target that "
291                 "doesn't support the F instruction set extension (ignoring "
292                 "target-abi)\n";
293     } else if (ABIName.ends_with("d") &&
294                !getSTI().hasFeature(RISCV::FeatureStdExtD)) {
295       errs() << "Hard-float 'd' ABI can't be used for a target that "
296                 "doesn't support the D instruction set extension (ignoring "
297                 "target-abi)\n";
298     }
299 
300     // Use computeTargetABI to check if ABIName is valid. If invalid, output
301     // error message.
302     RISCVABI::computeTargetABI(STI.getTargetTriple(), STI.getFeatureBits(),
303                                ABIName);
304 
305     const MCObjectFileInfo *MOFI = Parser.getContext().getObjectFileInfo();
306     ParserOptions.IsPicEnabled = MOFI->isPositionIndependent();
307 
308     if (AddBuildAttributes)
309       getTargetStreamer().emitTargetAttributes(STI, /*EmitStackAlign*/ false);
310   }
311 };
312 
313 /// RISCVOperand - Instances of this class represent a parsed machine
314 /// instruction
315 struct RISCVOperand final : public MCParsedAsmOperand {
316 
317   enum class KindTy {
318     Token,
319     Register,
320     Immediate,
321     FPImmediate,
322     SystemRegister,
323     VType,
324     FRM,
325     Fence,
326     Rlist,
327     Spimm,
328     RegReg,
329   } Kind;
330 
331   struct RegOp {
332     MCRegister RegNum;
333     bool IsGPRAsFPR;
334   };
335 
336   struct ImmOp {
337     const MCExpr *Val;
338     bool IsRV64;
339   };
340 
341   struct FPImmOp {
342     uint64_t Val;
343   };
344 
345   struct SysRegOp {
346     const char *Data;
347     unsigned Length;
348     unsigned Encoding;
349     // FIXME: Add the Encoding parsed fields as needed for checks,
350     // e.g.: read/write or user/supervisor/machine privileges.
351   };
352 
353   struct VTypeOp {
354     unsigned Val;
355   };
356 
357   struct FRMOp {
358     RISCVFPRndMode::RoundingMode FRM;
359   };
360 
361   struct FenceOp {
362     unsigned Val;
363   };
364 
365   struct RlistOp {
366     unsigned Val;
367   };
368 
369   struct SpimmOp {
370     unsigned Val;
371   };
372 
373   struct RegRegOp {
374     MCRegister Reg1;
375     MCRegister Reg2;
376   };
377 
378   SMLoc StartLoc, EndLoc;
379   union {
380     StringRef Tok;
381     RegOp Reg;
382     ImmOp Imm;
383     FPImmOp FPImm;
384     struct SysRegOp SysReg;
385     struct VTypeOp VType;
386     struct FRMOp FRM;
387     struct FenceOp Fence;
388     struct RlistOp Rlist;
389     struct SpimmOp Spimm;
390     struct RegRegOp RegReg;
391   };
392 
393   RISCVOperand(KindTy K) : Kind(K) {}
394 
395 public:
396   RISCVOperand(const RISCVOperand &o) : MCParsedAsmOperand() {
397     Kind = o.Kind;
398     StartLoc = o.StartLoc;
399     EndLoc = o.EndLoc;
400     switch (Kind) {
401     case KindTy::Register:
402       Reg = o.Reg;
403       break;
404     case KindTy::Immediate:
405       Imm = o.Imm;
406       break;
407     case KindTy::FPImmediate:
408       FPImm = o.FPImm;
409       break;
410     case KindTy::Token:
411       Tok = o.Tok;
412       break;
413     case KindTy::SystemRegister:
414       SysReg = o.SysReg;
415       break;
416     case KindTy::VType:
417       VType = o.VType;
418       break;
419     case KindTy::FRM:
420       FRM = o.FRM;
421       break;
422     case KindTy::Fence:
423       Fence = o.Fence;
424       break;
425     case KindTy::Rlist:
426       Rlist = o.Rlist;
427       break;
428     case KindTy::Spimm:
429       Spimm = o.Spimm;
430       break;
431     case KindTy::RegReg:
432       RegReg = o.RegReg;
433       break;
434     }
435   }
436 
437   bool isToken() const override { return Kind == KindTy::Token; }
438   bool isReg() const override { return Kind == KindTy::Register; }
439   bool isV0Reg() const {
440     return Kind == KindTy::Register && Reg.RegNum == RISCV::V0;
441   }
442   bool isAnyReg() const {
443     return Kind == KindTy::Register &&
444            (RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(Reg.RegNum) ||
445             RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(Reg.RegNum) ||
446             RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(Reg.RegNum));
447   }
448   bool isAnyRegC() const {
449     return Kind == KindTy::Register &&
450            (RISCVMCRegisterClasses[RISCV::GPRCRegClassID].contains(
451                 Reg.RegNum) ||
452             RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
453                 Reg.RegNum));
454   }
455   bool isImm() const override { return Kind == KindTy::Immediate; }
456   bool isMem() const override { return false; }
457   bool isSystemRegister() const { return Kind == KindTy::SystemRegister; }
458   bool isRegReg() const { return Kind == KindTy::RegReg; }
459   bool isRlist() const { return Kind == KindTy::Rlist; }
460   bool isSpimm() const { return Kind == KindTy::Spimm; }
461 
462   bool isGPR() const {
463     return Kind == KindTy::Register &&
464            RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(Reg.RegNum);
465   }
466 
467   bool isGPRAsFPR() const { return isGPR() && Reg.IsGPRAsFPR; }
468 
469   bool isGPRF64AsFPR() const { return isGPR() && Reg.IsGPRAsFPR; }
470 
471   bool isGPRPF64AsFPR() const { return isGPR() && Reg.IsGPRAsFPR; }
472 
473   static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm,
474                                   RISCVMCExpr::VariantKind &VK) {
475     if (auto *RE = dyn_cast<RISCVMCExpr>(Expr)) {
476       VK = RE->getKind();
477       return RE->evaluateAsConstant(Imm);
478     }
479 
480     if (auto CE = dyn_cast<MCConstantExpr>(Expr)) {
481       VK = RISCVMCExpr::VK_RISCV_None;
482       Imm = CE->getValue();
483       return true;
484     }
485 
486     return false;
487   }
488 
489   // True if operand is a symbol with no modifiers, or a constant with no
490   // modifiers and isShiftedInt<N-1, 1>(Op).
491   template <int N> bool isBareSimmNLsb0() const {
492     int64_t Imm;
493     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
494     if (!isImm())
495       return false;
496     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
497     bool IsValid;
498     if (!IsConstantImm)
499       IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
500     else
501       IsValid = isShiftedInt<N - 1, 1>(Imm);
502     return IsValid && VK == RISCVMCExpr::VK_RISCV_None;
503   }
504 
505   // Predicate methods for AsmOperands defined in RISCVInstrInfo.td
506 
507   bool isBareSymbol() const {
508     int64_t Imm;
509     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
510     // Must be of 'immediate' type but not a constant.
511     if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
512       return false;
513     return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
514            VK == RISCVMCExpr::VK_RISCV_None;
515   }
516 
517   bool isCallSymbol() const {
518     int64_t Imm;
519     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
520     // Must be of 'immediate' type but not a constant.
521     if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
522       return false;
523     return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
524            (VK == RISCVMCExpr::VK_RISCV_CALL ||
525             VK == RISCVMCExpr::VK_RISCV_CALL_PLT);
526   }
527 
528   bool isPseudoJumpSymbol() const {
529     int64_t Imm;
530     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
531     // Must be of 'immediate' type but not a constant.
532     if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
533       return false;
534     return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
535            VK == RISCVMCExpr::VK_RISCV_CALL;
536   }
537 
538   bool isTPRelAddSymbol() const {
539     int64_t Imm;
540     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
541     // Must be of 'immediate' type but not a constant.
542     if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
543       return false;
544     return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
545            VK == RISCVMCExpr::VK_RISCV_TPREL_ADD;
546   }
547 
548   bool isCSRSystemRegister() const { return isSystemRegister(); }
549 
550   bool isVTypeImm(unsigned N) const {
551     int64_t Imm;
552     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
553     if (!isImm())
554       return false;
555     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
556     return IsConstantImm && isUIntN(N, Imm) && VK == RISCVMCExpr::VK_RISCV_None;
557   }
558 
559   // If the last operand of the vsetvli/vsetvli instruction is a constant
560   // expression, KindTy is Immediate.
561   bool isVTypeI10() const {
562     if (Kind == KindTy::Immediate)
563       return isVTypeImm(10);
564     return Kind == KindTy::VType;
565   }
566   bool isVTypeI11() const {
567     if (Kind == KindTy::Immediate)
568       return isVTypeImm(11);
569     return Kind == KindTy::VType;
570   }
571 
572   /// Return true if the operand is a valid for the fence instruction e.g.
573   /// ('iorw').
574   bool isFenceArg() const { return Kind == KindTy::Fence; }
575 
576   /// Return true if the operand is a valid floating point rounding mode.
577   bool isFRMArg() const { return Kind == KindTy::FRM; }
578   bool isFRMArgLegacy() const { return Kind == KindTy::FRM; }
579   bool isRTZArg() const { return isFRMArg() && FRM.FRM == RISCVFPRndMode::RTZ; }
580 
581   /// Return true if the operand is a valid fli.s floating-point immediate.
582   bool isLoadFPImm() const {
583     if (isImm())
584       return isUImm5();
585     if (Kind != KindTy::FPImmediate)
586       return false;
587     int Idx = RISCVLoadFPImm::getLoadFPImm(
588         APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
589     // Don't allow decimal version of the minimum value. It is a different value
590     // for each supported data type.
591     return Idx >= 0 && Idx != 1;
592   }
593 
594   bool isImmXLenLI() const {
595     int64_t Imm;
596     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
597     if (!isImm())
598       return false;
599     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
600     if (VK == RISCVMCExpr::VK_RISCV_LO || VK == RISCVMCExpr::VK_RISCV_PCREL_LO)
601       return true;
602     // Given only Imm, ensuring that the actually specified constant is either
603     // a signed or unsigned 64-bit number is unfortunately impossible.
604     if (IsConstantImm) {
605       return VK == RISCVMCExpr::VK_RISCV_None &&
606              (isRV64Imm() || (isInt<32>(Imm) || isUInt<32>(Imm)));
607     }
608 
609     return RISCVAsmParser::isSymbolDiff(getImm());
610   }
611 
612   bool isImmXLenLI_Restricted() const {
613     int64_t Imm;
614     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
615     if (!isImm())
616       return false;
617     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
618     // 'la imm' supports constant immediates only.
619     return IsConstantImm && (VK == RISCVMCExpr::VK_RISCV_None) &&
620            (isRV64Imm() || (isInt<32>(Imm) || isUInt<32>(Imm)));
621   }
622 
623   bool isUImmLog2XLen() const {
624     int64_t Imm;
625     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
626     if (!isImm())
627       return false;
628     if (!evaluateConstantImm(getImm(), Imm, VK) ||
629         VK != RISCVMCExpr::VK_RISCV_None)
630       return false;
631     return (isRV64Imm() && isUInt<6>(Imm)) || isUInt<5>(Imm);
632   }
633 
634   bool isUImmLog2XLenNonZero() const {
635     int64_t Imm;
636     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
637     if (!isImm())
638       return false;
639     if (!evaluateConstantImm(getImm(), Imm, VK) ||
640         VK != RISCVMCExpr::VK_RISCV_None)
641       return false;
642     if (Imm == 0)
643       return false;
644     return (isRV64Imm() && isUInt<6>(Imm)) || isUInt<5>(Imm);
645   }
646 
647   bool isUImmLog2XLenHalf() const {
648     int64_t Imm;
649     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
650     if (!isImm())
651       return false;
652     if (!evaluateConstantImm(getImm(), Imm, VK) ||
653         VK != RISCVMCExpr::VK_RISCV_None)
654       return false;
655     return (isRV64Imm() && isUInt<5>(Imm)) || isUInt<4>(Imm);
656   }
657 
658   template <unsigned N> bool IsUImm() const {
659     int64_t Imm;
660     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
661     if (!isImm())
662       return false;
663     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
664     return IsConstantImm && isUInt<N>(Imm) && VK == RISCVMCExpr::VK_RISCV_None;
665   }
666 
667   bool isUImm1() const { return IsUImm<1>(); }
668   bool isUImm2() const { return IsUImm<2>(); }
669   bool isUImm3() const { return IsUImm<3>(); }
670   bool isUImm4() const { return IsUImm<4>(); }
671   bool isUImm5() const { return IsUImm<5>(); }
672   bool isUImm6() const { return IsUImm<6>(); }
673   bool isUImm7() const { return IsUImm<7>(); }
674   bool isUImm8() const { return IsUImm<8>(); }
675   bool isUImm20() const { return IsUImm<20>(); }
676 
677   bool isUImm8GE32() const {
678     int64_t Imm;
679     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
680     if (!isImm())
681       return false;
682     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
683     return IsConstantImm && isUInt<8>(Imm) && Imm >= 32 &&
684            VK == RISCVMCExpr::VK_RISCV_None;
685   }
686 
687   bool isRnumArg() const {
688     int64_t Imm;
689     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
690     if (!isImm())
691       return false;
692     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
693     return IsConstantImm && Imm >= INT64_C(0) && Imm <= INT64_C(10) &&
694            VK == RISCVMCExpr::VK_RISCV_None;
695   }
696 
697   bool isRnumArg_0_7() const {
698     int64_t Imm;
699     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
700     if (!isImm())
701       return false;
702     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
703     return IsConstantImm && Imm >= INT64_C(0) && Imm <= INT64_C(7) &&
704            VK == RISCVMCExpr::VK_RISCV_None;
705   }
706 
707   bool isRnumArg_1_10() const {
708     int64_t Imm;
709     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
710     if (!isImm())
711       return false;
712     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
713     return IsConstantImm && Imm >= INT64_C(1) && Imm <= INT64_C(10) &&
714            VK == RISCVMCExpr::VK_RISCV_None;
715   }
716 
717   bool isRnumArg_2_14() const {
718     int64_t Imm;
719     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
720     if (!isImm())
721       return false;
722     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
723     return IsConstantImm && Imm >= INT64_C(2) && Imm <= INT64_C(14) &&
724            VK == RISCVMCExpr::VK_RISCV_None;
725   }
726 
727   bool isSImm5() const {
728     if (!isImm())
729       return false;
730     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
731     int64_t Imm;
732     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
733     return IsConstantImm && isInt<5>(fixImmediateForRV32(Imm, isRV64Imm())) &&
734            VK == RISCVMCExpr::VK_RISCV_None;
735   }
736 
737   bool isSImm6() const {
738     if (!isImm())
739       return false;
740     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
741     int64_t Imm;
742     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
743     return IsConstantImm && isInt<6>(fixImmediateForRV32(Imm, isRV64Imm())) &&
744            VK == RISCVMCExpr::VK_RISCV_None;
745   }
746 
747   bool isSImm6NonZero() const {
748     if (!isImm())
749       return false;
750     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
751     int64_t Imm;
752     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
753     return IsConstantImm && Imm != 0 &&
754            isInt<6>(fixImmediateForRV32(Imm, isRV64Imm())) &&
755            VK == RISCVMCExpr::VK_RISCV_None;
756   }
757 
758   bool isCLUIImm() const {
759     if (!isImm())
760       return false;
761     int64_t Imm;
762     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
763     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
764     return IsConstantImm && (Imm != 0) &&
765            (isUInt<5>(Imm) || (Imm >= 0xfffe0 && Imm <= 0xfffff)) &&
766            VK == RISCVMCExpr::VK_RISCV_None;
767   }
768 
769   bool isUImm2Lsb0() const {
770     if (!isImm())
771       return false;
772     int64_t Imm;
773     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
774     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
775     return IsConstantImm && isShiftedUInt<1, 1>(Imm) &&
776            VK == RISCVMCExpr::VK_RISCV_None;
777   }
778 
779   bool isUImm7Lsb00() const {
780     if (!isImm())
781       return false;
782     int64_t Imm;
783     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
784     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
785     return IsConstantImm && isShiftedUInt<5, 2>(Imm) &&
786            VK == RISCVMCExpr::VK_RISCV_None;
787   }
788 
789   bool isUImm8Lsb00() const {
790     if (!isImm())
791       return false;
792     int64_t Imm;
793     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
794     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
795     return IsConstantImm && isShiftedUInt<6, 2>(Imm) &&
796            VK == RISCVMCExpr::VK_RISCV_None;
797   }
798 
799   bool isUImm8Lsb000() const {
800     if (!isImm())
801       return false;
802     int64_t Imm;
803     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
804     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
805     return IsConstantImm && isShiftedUInt<5, 3>(Imm) &&
806            VK == RISCVMCExpr::VK_RISCV_None;
807   }
808 
809   bool isSImm9Lsb0() const { return isBareSimmNLsb0<9>(); }
810 
811   bool isUImm9Lsb000() const {
812     if (!isImm())
813       return false;
814     int64_t Imm;
815     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
816     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
817     return IsConstantImm && isShiftedUInt<6, 3>(Imm) &&
818            VK == RISCVMCExpr::VK_RISCV_None;
819   }
820 
821   bool isUImm10Lsb00NonZero() const {
822     if (!isImm())
823       return false;
824     int64_t Imm;
825     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
826     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
827     return IsConstantImm && isShiftedUInt<8, 2>(Imm) && (Imm != 0) &&
828            VK == RISCVMCExpr::VK_RISCV_None;
829   }
830 
831   // If this a RV32 and the immediate is a uimm32, sign extend it to 32 bits.
832   // This allows writing 'addi a0, a0, 0xffffffff'.
833   static int64_t fixImmediateForRV32(int64_t Imm, bool IsRV64Imm) {
834     if (IsRV64Imm || !isUInt<32>(Imm))
835       return Imm;
836     return SignExtend64<32>(Imm);
837   }
838 
839   bool isSImm12() const {
840     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
841     int64_t Imm;
842     bool IsValid;
843     if (!isImm())
844       return false;
845     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
846     if (!IsConstantImm)
847       IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
848     else
849       IsValid = isInt<12>(fixImmediateForRV32(Imm, isRV64Imm()));
850     return IsValid && ((IsConstantImm && VK == RISCVMCExpr::VK_RISCV_None) ||
851                        VK == RISCVMCExpr::VK_RISCV_LO ||
852                        VK == RISCVMCExpr::VK_RISCV_PCREL_LO ||
853                        VK == RISCVMCExpr::VK_RISCV_TPREL_LO);
854   }
855 
856   bool isSImm12Lsb0() const { return isBareSimmNLsb0<12>(); }
857 
858   bool isSImm12Lsb00000() const {
859     if (!isImm())
860       return false;
861     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
862     int64_t Imm;
863     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
864     return IsConstantImm && isShiftedInt<7, 5>(Imm) &&
865            VK == RISCVMCExpr::VK_RISCV_None;
866   }
867 
868   bool isSImm13Lsb0() const { return isBareSimmNLsb0<13>(); }
869 
870   bool isSImm10Lsb0000NonZero() const {
871     if (!isImm())
872       return false;
873     int64_t Imm;
874     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
875     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
876     return IsConstantImm && (Imm != 0) && isShiftedInt<6, 4>(Imm) &&
877            VK == RISCVMCExpr::VK_RISCV_None;
878   }
879 
880   bool isUImm20LUI() const {
881     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
882     int64_t Imm;
883     bool IsValid;
884     if (!isImm())
885       return false;
886     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
887     if (!IsConstantImm) {
888       IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
889       return IsValid && (VK == RISCVMCExpr::VK_RISCV_HI ||
890                          VK == RISCVMCExpr::VK_RISCV_TPREL_HI);
891     } else {
892       return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None ||
893                                  VK == RISCVMCExpr::VK_RISCV_HI ||
894                                  VK == RISCVMCExpr::VK_RISCV_TPREL_HI);
895     }
896   }
897 
898   bool isUImm20AUIPC() const {
899     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
900     int64_t Imm;
901     bool IsValid;
902     if (!isImm())
903       return false;
904     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
905     if (!IsConstantImm) {
906       IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
907       return IsValid && (VK == RISCVMCExpr::VK_RISCV_PCREL_HI ||
908                          VK == RISCVMCExpr::VK_RISCV_GOT_HI ||
909                          VK == RISCVMCExpr::VK_RISCV_TLS_GOT_HI ||
910                          VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI);
911     } else {
912       return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None ||
913                                  VK == RISCVMCExpr::VK_RISCV_PCREL_HI ||
914                                  VK == RISCVMCExpr::VK_RISCV_GOT_HI ||
915                                  VK == RISCVMCExpr::VK_RISCV_TLS_GOT_HI ||
916                                  VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI);
917     }
918   }
919 
920   bool isSImm21Lsb0JAL() const { return isBareSimmNLsb0<21>(); }
921 
922   bool isImmZero() const {
923     if (!isImm())
924       return false;
925     int64_t Imm;
926     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
927     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
928     return IsConstantImm && (Imm == 0) && VK == RISCVMCExpr::VK_RISCV_None;
929   }
930 
931   bool isSImm5Plus1() const {
932     if (!isImm())
933       return false;
934     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
935     int64_t Imm;
936     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
937     return IsConstantImm &&
938            isInt<5>(fixImmediateForRV32(Imm, isRV64Imm()) - 1) &&
939            VK == RISCVMCExpr::VK_RISCV_None;
940   }
941 
942   /// getStartLoc - Gets location of the first token of this operand
943   SMLoc getStartLoc() const override { return StartLoc; }
944   /// getEndLoc - Gets location of the last token of this operand
945   SMLoc getEndLoc() const override { return EndLoc; }
946   /// True if this operand is for an RV64 instruction
947   bool isRV64Imm() const {
948     assert(Kind == KindTy::Immediate && "Invalid type access!");
949     return Imm.IsRV64;
950   }
951 
952   unsigned getReg() const override {
953     assert(Kind == KindTy::Register && "Invalid type access!");
954     return Reg.RegNum.id();
955   }
956 
957   StringRef getSysReg() const {
958     assert(Kind == KindTy::SystemRegister && "Invalid type access!");
959     return StringRef(SysReg.Data, SysReg.Length);
960   }
961 
962   const MCExpr *getImm() const {
963     assert(Kind == KindTy::Immediate && "Invalid type access!");
964     return Imm.Val;
965   }
966 
967   uint64_t getFPConst() const {
968     assert(Kind == KindTy::FPImmediate && "Invalid type access!");
969     return FPImm.Val;
970   }
971 
972   StringRef getToken() const {
973     assert(Kind == KindTy::Token && "Invalid type access!");
974     return Tok;
975   }
976 
977   unsigned getVType() const {
978     assert(Kind == KindTy::VType && "Invalid type access!");
979     return VType.Val;
980   }
981 
982   RISCVFPRndMode::RoundingMode getFRM() const {
983     assert(Kind == KindTy::FRM && "Invalid type access!");
984     return FRM.FRM;
985   }
986 
987   unsigned getFence() const {
988     assert(Kind == KindTy::Fence && "Invalid type access!");
989     return Fence.Val;
990   }
991 
992   void print(raw_ostream &OS) const override {
993     auto RegName = [](MCRegister Reg) {
994       if (Reg)
995         return RISCVInstPrinter::getRegisterName(Reg);
996       else
997         return "noreg";
998     };
999 
1000     switch (Kind) {
1001     case KindTy::Immediate:
1002       OS << *getImm();
1003       break;
1004     case KindTy::FPImmediate:
1005       break;
1006     case KindTy::Register:
1007       OS << "<register " << RegName(getReg()) << ">";
1008       break;
1009     case KindTy::Token:
1010       OS << "'" << getToken() << "'";
1011       break;
1012     case KindTy::SystemRegister:
1013       OS << "<sysreg: " << getSysReg() << '>';
1014       break;
1015     case KindTy::VType:
1016       OS << "<vtype: ";
1017       RISCVVType::printVType(getVType(), OS);
1018       OS << '>';
1019       break;
1020     case KindTy::FRM:
1021       OS << "<frm: ";
1022       roundingModeToString(getFRM());
1023       OS << '>';
1024       break;
1025     case KindTy::Fence:
1026       OS << "<fence: ";
1027       OS << getFence();
1028       OS << '>';
1029       break;
1030     case KindTy::Rlist:
1031       OS << "<rlist: ";
1032       RISCVZC::printRlist(Rlist.Val, OS);
1033       OS << '>';
1034       break;
1035     case KindTy::Spimm:
1036       OS << "<Spimm: ";
1037       RISCVZC::printSpimm(Spimm.Val, OS);
1038       OS << '>';
1039       break;
1040     case KindTy::RegReg:
1041       OS << "<RegReg:  Reg1 " << RegName(RegReg.Reg1);
1042       OS << " Reg2 " << RegName(RegReg.Reg2);
1043       break;
1044     }
1045   }
1046 
1047   static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S) {
1048     auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
1049     Op->Tok = Str;
1050     Op->StartLoc = S;
1051     Op->EndLoc = S;
1052     return Op;
1053   }
1054 
1055   static std::unique_ptr<RISCVOperand>
1056   createReg(unsigned RegNo, SMLoc S, SMLoc E, bool IsGPRAsFPR = false) {
1057     auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
1058     Op->Reg.RegNum = RegNo;
1059     Op->Reg.IsGPRAsFPR = IsGPRAsFPR;
1060     Op->StartLoc = S;
1061     Op->EndLoc = E;
1062     return Op;
1063   }
1064 
1065   static std::unique_ptr<RISCVOperand> createImm(const MCExpr *Val, SMLoc S,
1066                                                  SMLoc E, bool IsRV64) {
1067     auto Op = std::make_unique<RISCVOperand>(KindTy::Immediate);
1068     Op->Imm.Val = Val;
1069     Op->Imm.IsRV64 = IsRV64;
1070     Op->StartLoc = S;
1071     Op->EndLoc = E;
1072     return Op;
1073   }
1074 
1075   static std::unique_ptr<RISCVOperand> createFPImm(uint64_t Val, SMLoc S) {
1076     auto Op = std::make_unique<RISCVOperand>(KindTy::FPImmediate);
1077     Op->FPImm.Val = Val;
1078     Op->StartLoc = S;
1079     Op->EndLoc = S;
1080     return Op;
1081   }
1082 
1083   static std::unique_ptr<RISCVOperand> createSysReg(StringRef Str, SMLoc S,
1084                                                     unsigned Encoding) {
1085     auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
1086     Op->SysReg.Data = Str.data();
1087     Op->SysReg.Length = Str.size();
1088     Op->SysReg.Encoding = Encoding;
1089     Op->StartLoc = S;
1090     Op->EndLoc = S;
1091     return Op;
1092   }
1093 
1094   static std::unique_ptr<RISCVOperand>
1095   createFRMArg(RISCVFPRndMode::RoundingMode FRM, SMLoc S) {
1096     auto Op = std::make_unique<RISCVOperand>(KindTy::FRM);
1097     Op->FRM.FRM = FRM;
1098     Op->StartLoc = S;
1099     Op->EndLoc = S;
1100     return Op;
1101   }
1102 
1103   static std::unique_ptr<RISCVOperand> createFenceArg(unsigned Val, SMLoc S) {
1104     auto Op = std::make_unique<RISCVOperand>(KindTy::Fence);
1105     Op->Fence.Val = Val;
1106     Op->StartLoc = S;
1107     Op->EndLoc = S;
1108     return Op;
1109   }
1110 
1111   static std::unique_ptr<RISCVOperand> createVType(unsigned VTypeI, SMLoc S) {
1112     auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
1113     Op->VType.Val = VTypeI;
1114     Op->StartLoc = S;
1115     Op->EndLoc = S;
1116     return Op;
1117   }
1118 
1119   static std::unique_ptr<RISCVOperand> createRlist(unsigned RlistEncode,
1120                                                    SMLoc S) {
1121     auto Op = std::make_unique<RISCVOperand>(KindTy::Rlist);
1122     Op->Rlist.Val = RlistEncode;
1123     Op->StartLoc = S;
1124     return Op;
1125   }
1126 
1127   static std::unique_ptr<RISCVOperand> createRegReg(unsigned Reg1No,
1128                                                     unsigned Reg2No, SMLoc S) {
1129     auto Op = std::make_unique<RISCVOperand>(KindTy::RegReg);
1130     Op->RegReg.Reg1 = Reg1No;
1131     Op->RegReg.Reg2 = Reg2No;
1132     Op->StartLoc = S;
1133     Op->EndLoc = S;
1134     return Op;
1135   }
1136 
1137   static std::unique_ptr<RISCVOperand> createSpimm(unsigned Spimm, SMLoc S) {
1138     auto Op = std::make_unique<RISCVOperand>(KindTy::Spimm);
1139     Op->Spimm.Val = Spimm;
1140     Op->StartLoc = S;
1141     return Op;
1142   }
1143 
1144   static void addExpr(MCInst &Inst, const MCExpr *Expr, bool IsRV64Imm) {
1145     assert(Expr && "Expr shouldn't be null!");
1146     int64_t Imm = 0;
1147     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
1148     bool IsConstant = evaluateConstantImm(Expr, Imm, VK);
1149 
1150     if (IsConstant)
1151       Inst.addOperand(
1152           MCOperand::createImm(fixImmediateForRV32(Imm, IsRV64Imm)));
1153     else
1154       Inst.addOperand(MCOperand::createExpr(Expr));
1155   }
1156 
1157   // Used by the TableGen Code
1158   void addRegOperands(MCInst &Inst, unsigned N) const {
1159     assert(N == 1 && "Invalid number of operands!");
1160     Inst.addOperand(MCOperand::createReg(getReg()));
1161   }
1162 
1163   void addImmOperands(MCInst &Inst, unsigned N) const {
1164     assert(N == 1 && "Invalid number of operands!");
1165     addExpr(Inst, getImm(), isRV64Imm());
1166   }
1167 
1168   void addFPImmOperands(MCInst &Inst, unsigned N) const {
1169     assert(N == 1 && "Invalid number of operands!");
1170     if (isImm()) {
1171       addExpr(Inst, getImm(), isRV64Imm());
1172       return;
1173     }
1174 
1175     int Imm = RISCVLoadFPImm::getLoadFPImm(
1176         APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
1177     Inst.addOperand(MCOperand::createImm(Imm));
1178   }
1179 
1180   void addFenceArgOperands(MCInst &Inst, unsigned N) const {
1181     assert(N == 1 && "Invalid number of operands!");
1182     Inst.addOperand(MCOperand::createImm(Fence.Val));
1183   }
1184 
1185   void addCSRSystemRegisterOperands(MCInst &Inst, unsigned N) const {
1186     assert(N == 1 && "Invalid number of operands!");
1187     Inst.addOperand(MCOperand::createImm(SysReg.Encoding));
1188   }
1189 
1190   // Support non-canonical syntax:
1191   // "vsetivli rd, uimm, 0xabc" or "vsetvli rd, rs1, 0xabc"
1192   // "vsetivli rd, uimm, (0xc << N)" or "vsetvli rd, rs1, (0xc << N)"
1193   void addVTypeIOperands(MCInst &Inst, unsigned N) const {
1194     assert(N == 1 && "Invalid number of operands!");
1195     int64_t Imm = 0;
1196     if (Kind == KindTy::Immediate) {
1197       RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
1198       bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
1199       (void)IsConstantImm;
1200       assert(IsConstantImm && "Invalid VTypeI Operand!");
1201     } else {
1202       Imm = getVType();
1203     }
1204     Inst.addOperand(MCOperand::createImm(Imm));
1205   }
1206 
1207   void addRlistOperands(MCInst &Inst, unsigned N) const {
1208     assert(N == 1 && "Invalid number of operands!");
1209     Inst.addOperand(MCOperand::createImm(Rlist.Val));
1210   }
1211 
1212   void addRegRegOperands(MCInst &Inst, unsigned N) const {
1213     assert(N == 1 && "Invalid number of operands!");
1214     Inst.addOperand(MCOperand::createReg(RegReg.Reg1));
1215     Inst.addOperand(MCOperand::createReg(RegReg.Reg2));
1216   }
1217 
1218   void addSpimmOperands(MCInst &Inst, unsigned N) const {
1219     assert(N == 1 && "Invalid number of operands!");
1220     Inst.addOperand(MCOperand::createImm(Spimm.Val));
1221   }
1222 
1223   void addFRMArgOperands(MCInst &Inst, unsigned N) const {
1224     assert(N == 1 && "Invalid number of operands!");
1225     Inst.addOperand(MCOperand::createImm(getFRM()));
1226   }
1227 };
1228 } // end anonymous namespace.
1229 
1230 #define GET_REGISTER_MATCHER
1231 #define GET_SUBTARGET_FEATURE_NAME
1232 #define GET_MATCHER_IMPLEMENTATION
1233 #define GET_MNEMONIC_SPELL_CHECKER
1234 #include "RISCVGenAsmMatcher.inc"
1235 
1236 static MCRegister convertFPR64ToFPR16(MCRegister Reg) {
1237   assert(Reg >= RISCV::F0_D && Reg <= RISCV::F31_D && "Invalid register");
1238   return Reg - RISCV::F0_D + RISCV::F0_H;
1239 }
1240 
1241 static MCRegister convertFPR64ToFPR32(MCRegister Reg) {
1242   assert(Reg >= RISCV::F0_D && Reg <= RISCV::F31_D && "Invalid register");
1243   return Reg - RISCV::F0_D + RISCV::F0_F;
1244 }
1245 
1246 static MCRegister convertVRToVRMx(const MCRegisterInfo &RI, MCRegister Reg,
1247                                   unsigned Kind) {
1248   unsigned RegClassID;
1249   if (Kind == MCK_VRM2)
1250     RegClassID = RISCV::VRM2RegClassID;
1251   else if (Kind == MCK_VRM4)
1252     RegClassID = RISCV::VRM4RegClassID;
1253   else if (Kind == MCK_VRM8)
1254     RegClassID = RISCV::VRM8RegClassID;
1255   else
1256     return 0;
1257   return RI.getMatchingSuperReg(Reg, RISCV::sub_vrm1_0,
1258                                 &RISCVMCRegisterClasses[RegClassID]);
1259 }
1260 
1261 unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
1262                                                     unsigned Kind) {
1263   RISCVOperand &Op = static_cast<RISCVOperand &>(AsmOp);
1264   if (!Op.isReg())
1265     return Match_InvalidOperand;
1266 
1267   MCRegister Reg = Op.getReg();
1268   bool IsRegFPR64 =
1269       RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(Reg);
1270   bool IsRegFPR64C =
1271       RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(Reg);
1272   bool IsRegVR = RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(Reg);
1273 
1274   // As the parser couldn't differentiate an FPR32 from an FPR64, coerce the
1275   // register from FPR64 to FPR32 or FPR64C to FPR32C if necessary.
1276   if ((IsRegFPR64 && Kind == MCK_FPR32) ||
1277       (IsRegFPR64C && Kind == MCK_FPR32C)) {
1278     Op.Reg.RegNum = convertFPR64ToFPR32(Reg);
1279     return Match_Success;
1280   }
1281   // As the parser couldn't differentiate an FPR16 from an FPR64, coerce the
1282   // register from FPR64 to FPR16 if necessary.
1283   if (IsRegFPR64 && Kind == MCK_FPR16) {
1284     Op.Reg.RegNum = convertFPR64ToFPR16(Reg);
1285     return Match_Success;
1286   }
1287   // As the parser couldn't differentiate an VRM2/VRM4/VRM8 from an VR, coerce
1288   // the register from VR to VRM2/VRM4/VRM8 if necessary.
1289   if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
1290     Op.Reg.RegNum = convertVRToVRMx(*getContext().getRegisterInfo(), Reg, Kind);
1291     if (Op.Reg.RegNum == 0)
1292       return Match_InvalidOperand;
1293     return Match_Success;
1294   }
1295   return Match_InvalidOperand;
1296 }
1297 
1298 unsigned RISCVAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1299   const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
1300 
1301   for (unsigned I = 0; I < MCID.NumOperands; ++I) {
1302     if (MCID.operands()[I].RegClass == RISCV::GPRPF64RegClassID) {
1303       const auto &Op = Inst.getOperand(I);
1304       assert(Op.isReg());
1305 
1306       MCRegister Reg = Op.getReg();
1307       if (((Reg.id() - RISCV::X0) & 1) != 0)
1308         return Match_RequiresEvenGPRs;
1309     }
1310   }
1311 
1312   return Match_Success;
1313 }
1314 
1315 bool RISCVAsmParser::generateImmOutOfRangeError(
1316     SMLoc ErrorLoc, int64_t Lower, int64_t Upper,
1317     const Twine &Msg = "immediate must be an integer in the range") {
1318   return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]");
1319 }
1320 
1321 bool RISCVAsmParser::generateImmOutOfRangeError(
1322     OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper,
1323     const Twine &Msg = "immediate must be an integer in the range") {
1324   SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1325   return generateImmOutOfRangeError(ErrorLoc, Lower, Upper, Msg);
1326 }
1327 
1328 bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1329                                              OperandVector &Operands,
1330                                              MCStreamer &Out,
1331                                              uint64_t &ErrorInfo,
1332                                              bool MatchingInlineAsm) {
1333   MCInst Inst;
1334   FeatureBitset MissingFeatures;
1335 
1336   auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
1337                                      MatchingInlineAsm);
1338   switch (Result) {
1339   default:
1340     break;
1341   case Match_Success:
1342     if (validateInstruction(Inst, Operands))
1343       return true;
1344     return processInstruction(Inst, IDLoc, Operands, Out);
1345   case Match_MissingFeature: {
1346     assert(MissingFeatures.any() && "Unknown missing features!");
1347     bool FirstFeature = true;
1348     std::string Msg = "instruction requires the following:";
1349     for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) {
1350       if (MissingFeatures[i]) {
1351         Msg += FirstFeature ? " " : ", ";
1352         Msg += getSubtargetFeatureName(i);
1353         FirstFeature = false;
1354       }
1355     }
1356     return Error(IDLoc, Msg);
1357   }
1358   case Match_MnemonicFail: {
1359     FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1360     std::string Suggestion = RISCVMnemonicSpellCheck(
1361         ((RISCVOperand &)*Operands[0]).getToken(), FBS, 0);
1362     return Error(IDLoc, "unrecognized instruction mnemonic" + Suggestion);
1363   }
1364   case Match_InvalidOperand: {
1365     SMLoc ErrorLoc = IDLoc;
1366     if (ErrorInfo != ~0ULL) {
1367       if (ErrorInfo >= Operands.size())
1368         return Error(ErrorLoc, "too few operands for instruction");
1369 
1370       ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1371       if (ErrorLoc == SMLoc())
1372         ErrorLoc = IDLoc;
1373     }
1374     return Error(ErrorLoc, "invalid operand for instruction");
1375   }
1376   }
1377 
1378   // Handle the case when the error message is of specific type
1379   // other than the generic Match_InvalidOperand, and the
1380   // corresponding operand is missing.
1381   if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1382     SMLoc ErrorLoc = IDLoc;
1383     if (ErrorInfo != ~0ULL && ErrorInfo >= Operands.size())
1384       return Error(ErrorLoc, "too few operands for instruction");
1385   }
1386 
1387   switch (Result) {
1388   default:
1389     break;
1390   case Match_RequiresEvenGPRs:
1391     return Error(IDLoc,
1392                  "double precision floating point operands must use even "
1393                  "numbered X register");
1394   case Match_InvalidImmXLenLI:
1395     if (isRV64()) {
1396       SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1397       return Error(ErrorLoc, "operand must be a constant 64-bit integer");
1398     }
1399     return generateImmOutOfRangeError(Operands, ErrorInfo,
1400                                       std::numeric_limits<int32_t>::min(),
1401                                       std::numeric_limits<uint32_t>::max());
1402   case Match_InvalidImmXLenLI_Restricted:
1403     if (isRV64()) {
1404       SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1405       return Error(ErrorLoc, "operand either must be a constant 64-bit integer "
1406                              "or a bare symbol name");
1407     }
1408     return generateImmOutOfRangeError(
1409         Operands, ErrorInfo, std::numeric_limits<int32_t>::min(),
1410         std::numeric_limits<uint32_t>::max(),
1411         "operand either must be a bare symbol name or an immediate integer in "
1412         "the range");
1413   case Match_InvalidImmZero: {
1414     SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1415     return Error(ErrorLoc, "immediate must be zero");
1416   }
1417   case Match_InvalidUImmLog2XLen:
1418     if (isRV64())
1419       return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
1420     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1421   case Match_InvalidUImmLog2XLenNonZero:
1422     if (isRV64())
1423       return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1);
1424     return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
1425   case Match_InvalidUImmLog2XLenHalf:
1426     if (isRV64())
1427       return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1428     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);
1429   case Match_InvalidUImm1:
1430     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 1) - 1);
1431   case Match_InvalidUImm2:
1432     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1);
1433   case Match_InvalidUImm2Lsb0:
1434     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 2,
1435                                       "immediate must be one of");
1436   case Match_InvalidUImm3:
1437     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1);
1438   case Match_InvalidUImm4:
1439     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);
1440   case Match_InvalidUImm5:
1441     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1442   case Match_InvalidUImm6:
1443     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
1444   case Match_InvalidUImm7:
1445     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1);
1446   case Match_InvalidUImm8:
1447     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 8) - 1);
1448   case Match_InvalidUImm8GE32:
1449     return generateImmOutOfRangeError(Operands, ErrorInfo, 32, (1 << 8) - 1);
1450   case Match_InvalidSImm5:
1451     return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4),
1452                                       (1 << 4) - 1);
1453   case Match_InvalidSImm6:
1454     return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5),
1455                                       (1 << 5) - 1);
1456   case Match_InvalidSImm6NonZero:
1457     return generateImmOutOfRangeError(
1458         Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1,
1459         "immediate must be non-zero in the range");
1460   case Match_InvalidCLUIImm:
1461     return generateImmOutOfRangeError(
1462         Operands, ErrorInfo, 1, (1 << 5) - 1,
1463         "immediate must be in [0xfffe0, 0xfffff] or");
1464   case Match_InvalidUImm7Lsb00:
1465     return generateImmOutOfRangeError(
1466         Operands, ErrorInfo, 0, (1 << 7) - 4,
1467         "immediate must be a multiple of 4 bytes in the range");
1468   case Match_InvalidUImm8Lsb00:
1469     return generateImmOutOfRangeError(
1470         Operands, ErrorInfo, 0, (1 << 8) - 4,
1471         "immediate must be a multiple of 4 bytes in the range");
1472   case Match_InvalidUImm8Lsb000:
1473     return generateImmOutOfRangeError(
1474         Operands, ErrorInfo, 0, (1 << 8) - 8,
1475         "immediate must be a multiple of 8 bytes in the range");
1476   case Match_InvalidSImm9Lsb0:
1477     return generateImmOutOfRangeError(
1478         Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2,
1479         "immediate must be a multiple of 2 bytes in the range");
1480   case Match_InvalidUImm9Lsb000:
1481     return generateImmOutOfRangeError(
1482         Operands, ErrorInfo, 0, (1 << 9) - 8,
1483         "immediate must be a multiple of 8 bytes in the range");
1484   case Match_InvalidUImm10Lsb00NonZero:
1485     return generateImmOutOfRangeError(
1486         Operands, ErrorInfo, 4, (1 << 10) - 4,
1487         "immediate must be a multiple of 4 bytes in the range");
1488   case Match_InvalidSImm10Lsb0000NonZero:
1489     return generateImmOutOfRangeError(
1490         Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
1491         "immediate must be a multiple of 16 bytes and non-zero in the range");
1492   case Match_InvalidSImm12:
1493     return generateImmOutOfRangeError(
1494         Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1,
1495         "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an "
1496         "integer in the range");
1497   case Match_InvalidSImm12Lsb0:
1498     return generateImmOutOfRangeError(
1499         Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2,
1500         "immediate must be a multiple of 2 bytes in the range");
1501   case Match_InvalidSImm12Lsb00000:
1502     return generateImmOutOfRangeError(
1503         Operands, ErrorInfo, -(1 << 11), (1 << 11) - 32,
1504         "immediate must be a multiple of 32 bytes in the range");
1505   case Match_InvalidSImm13Lsb0:
1506     return generateImmOutOfRangeError(
1507         Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2,
1508         "immediate must be a multiple of 2 bytes in the range");
1509   case Match_InvalidUImm20LUI:
1510     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1,
1511                                       "operand must be a symbol with "
1512                                       "%hi/%tprel_hi modifier or an integer in "
1513                                       "the range");
1514   case Match_InvalidUImm20:
1515     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1);
1516   case Match_InvalidUImm20AUIPC:
1517     return generateImmOutOfRangeError(
1518         Operands, ErrorInfo, 0, (1 << 20) - 1,
1519         "operand must be a symbol with a "
1520         "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or "
1521         "an integer in the range");
1522   case Match_InvalidSImm21Lsb0JAL:
1523     return generateImmOutOfRangeError(
1524         Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2,
1525         "immediate must be a multiple of 2 bytes in the range");
1526   case Match_InvalidCSRSystemRegister: {
1527     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1,
1528                                       "operand must be a valid system register "
1529                                       "name or an integer in the range");
1530   }
1531   case Match_InvalidLoadFPImm: {
1532     SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1533     return Error(ErrorLoc, "operand must be a valid floating-point constant");
1534   }
1535   case Match_InvalidBareSymbol: {
1536     SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1537     return Error(ErrorLoc, "operand must be a bare symbol name");
1538   }
1539   case Match_InvalidPseudoJumpSymbol: {
1540     SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1541     return Error(ErrorLoc, "operand must be a valid jump target");
1542   }
1543   case Match_InvalidCallSymbol: {
1544     SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1545     return Error(ErrorLoc, "operand must be a bare symbol name");
1546   }
1547   case Match_InvalidTPRelAddSymbol: {
1548     SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1549     return Error(ErrorLoc, "operand must be a symbol with %tprel_add modifier");
1550   }
1551   case Match_InvalidRTZArg: {
1552     SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1553     return Error(ErrorLoc, "operand must be 'rtz' floating-point rounding mode");
1554   }
1555   case Match_InvalidVTypeI: {
1556     SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1557     return generateVTypeError(ErrorLoc);
1558   }
1559   case Match_InvalidVMaskRegister: {
1560     SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1561     return Error(ErrorLoc, "operand must be v0.t");
1562   }
1563   case Match_InvalidSImm5Plus1: {
1564     return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4) + 1,
1565                                       (1 << 4),
1566                                       "immediate must be in the range");
1567   }
1568   case Match_InvalidRlist: {
1569     SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1570     return Error(
1571         ErrorLoc,
1572         "operand must be {ra [, s0[-sN]]} or {x1 [, x8[-x9][, x18[-xN]]]}");
1573   }
1574   case Match_InvalidSpimm: {
1575     SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1576     return Error(
1577         ErrorLoc,
1578         "stack adjustment is invalid for this instruction and register list; "
1579         "refer to Zc spec for a detailed range of stack adjustment");
1580   }
1581   case Match_InvalidRnumArg: {
1582     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 10);
1583   }
1584   case Match_InvalidRegReg: {
1585     SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1586     return Error(ErrorLoc, "operands must be register and register");
1587   }
1588   }
1589 
1590   llvm_unreachable("Unknown match type detected!");
1591 }
1592 
1593 // Attempts to match Name as a register (either using the default name or
1594 // alternative ABI names), setting RegNo to the matching register. Upon
1595 // failure, returns a non-valid MCRegister. If IsRVE, then registers x16-x31
1596 // will be rejected.
1597 static MCRegister matchRegisterNameHelper(bool IsRVE, StringRef Name) {
1598   MCRegister Reg = MatchRegisterName(Name);
1599   // The 16-/32- and 64-bit FPRs have the same asm name. Check that the initial
1600   // match always matches the 64-bit variant, and not the 16/32-bit one.
1601   assert(!(Reg >= RISCV::F0_H && Reg <= RISCV::F31_H));
1602   assert(!(Reg >= RISCV::F0_F && Reg <= RISCV::F31_F));
1603   // The default FPR register class is based on the tablegen enum ordering.
1604   static_assert(RISCV::F0_D < RISCV::F0_H, "FPR matching must be updated");
1605   static_assert(RISCV::F0_D < RISCV::F0_F, "FPR matching must be updated");
1606   if (!Reg)
1607     Reg = MatchRegisterAltName(Name);
1608   if (IsRVE && Reg >= RISCV::X16 && Reg <= RISCV::X31)
1609     Reg = RISCV::NoRegister;
1610   return Reg;
1611 }
1612 
1613 bool RISCVAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
1614                                    SMLoc &EndLoc) {
1615   if (!tryParseRegister(Reg, StartLoc, EndLoc).isSuccess())
1616     return Error(StartLoc, "invalid register name");
1617   return false;
1618 }
1619 
1620 ParseStatus RISCVAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
1621                                              SMLoc &EndLoc) {
1622   const AsmToken &Tok = getParser().getTok();
1623   StartLoc = Tok.getLoc();
1624   EndLoc = Tok.getEndLoc();
1625   StringRef Name = getLexer().getTok().getIdentifier();
1626 
1627   Reg = matchRegisterNameHelper(isRVE(), Name);
1628   if (!Reg)
1629     return ParseStatus::NoMatch;
1630 
1631   getParser().Lex(); // Eat identifier token.
1632   return ParseStatus::Success;
1633 }
1634 
1635 ParseStatus RISCVAsmParser::parseRegister(OperandVector &Operands,
1636                                           bool AllowParens) {
1637   SMLoc FirstS = getLoc();
1638   bool HadParens = false;
1639   AsmToken LParen;
1640 
1641   // If this is an LParen and a parenthesised register name is allowed, parse it
1642   // atomically.
1643   if (AllowParens && getLexer().is(AsmToken::LParen)) {
1644     AsmToken Buf[2];
1645     size_t ReadCount = getLexer().peekTokens(Buf);
1646     if (ReadCount == 2 && Buf[1].getKind() == AsmToken::RParen) {
1647       HadParens = true;
1648       LParen = getParser().getTok();
1649       getParser().Lex(); // Eat '('
1650     }
1651   }
1652 
1653   switch (getLexer().getKind()) {
1654   default:
1655     if (HadParens)
1656       getLexer().UnLex(LParen);
1657     return ParseStatus::NoMatch;
1658   case AsmToken::Identifier:
1659     StringRef Name = getLexer().getTok().getIdentifier();
1660     MCRegister RegNo = matchRegisterNameHelper(isRVE(), Name);
1661 
1662     if (!RegNo) {
1663       if (HadParens)
1664         getLexer().UnLex(LParen);
1665       return ParseStatus::NoMatch;
1666     }
1667     if (HadParens)
1668       Operands.push_back(RISCVOperand::createToken("(", FirstS));
1669     SMLoc S = getLoc();
1670     SMLoc E = SMLoc::getFromPointer(S.getPointer() + Name.size());
1671     getLexer().Lex();
1672     Operands.push_back(RISCVOperand::createReg(RegNo, S, E));
1673   }
1674 
1675   if (HadParens) {
1676     getParser().Lex(); // Eat ')'
1677     Operands.push_back(RISCVOperand::createToken(")", getLoc()));
1678   }
1679 
1680   return ParseStatus::Success;
1681 }
1682 
1683 ParseStatus RISCVAsmParser::parseInsnDirectiveOpcode(OperandVector &Operands) {
1684   SMLoc S = getLoc();
1685   SMLoc E;
1686   const MCExpr *Res;
1687 
1688   switch (getLexer().getKind()) {
1689   default:
1690     return ParseStatus::NoMatch;
1691   case AsmToken::LParen:
1692   case AsmToken::Minus:
1693   case AsmToken::Plus:
1694   case AsmToken::Exclaim:
1695   case AsmToken::Tilde:
1696   case AsmToken::Integer:
1697   case AsmToken::String: {
1698     if (getParser().parseExpression(Res, E))
1699       return ParseStatus::Failure;
1700 
1701     auto *CE = dyn_cast<MCConstantExpr>(Res);
1702     if (CE) {
1703       int64_t Imm = CE->getValue();
1704       if (isUInt<7>(Imm)) {
1705         Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1706         return ParseStatus::Success;
1707       }
1708     }
1709 
1710     break;
1711   }
1712   case AsmToken::Identifier: {
1713     StringRef Identifier;
1714     if (getParser().parseIdentifier(Identifier))
1715       return ParseStatus::Failure;
1716 
1717     auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);
1718     if (Opcode) {
1719       assert(isUInt<7>(Opcode->Value) && (Opcode->Value & 0x3) == 3 &&
1720              "Unexpected opcode");
1721       Res = MCConstantExpr::create(Opcode->Value, getContext());
1722       E = SMLoc::getFromPointer(S.getPointer() + Identifier.size());
1723       Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1724       return ParseStatus::Success;
1725     }
1726 
1727     break;
1728   }
1729   case AsmToken::Percent:
1730     break;
1731   }
1732 
1733   return generateImmOutOfRangeError(
1734       S, 0, 127,
1735       "opcode must be a valid opcode name or an immediate in the range");
1736 }
1737 
1738 ParseStatus RISCVAsmParser::parseInsnCDirectiveOpcode(OperandVector &Operands) {
1739   SMLoc S = getLoc();
1740   SMLoc E;
1741   const MCExpr *Res;
1742 
1743   switch (getLexer().getKind()) {
1744   default:
1745     return ParseStatus::NoMatch;
1746   case AsmToken::LParen:
1747   case AsmToken::Minus:
1748   case AsmToken::Plus:
1749   case AsmToken::Exclaim:
1750   case AsmToken::Tilde:
1751   case AsmToken::Integer:
1752   case AsmToken::String: {
1753     if (getParser().parseExpression(Res, E))
1754       return ParseStatus::Failure;
1755 
1756     auto *CE = dyn_cast<MCConstantExpr>(Res);
1757     if (CE) {
1758       int64_t Imm = CE->getValue();
1759       if (Imm >= 0 && Imm <= 2) {
1760         Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1761         return ParseStatus::Success;
1762       }
1763     }
1764 
1765     break;
1766   }
1767   case AsmToken::Identifier: {
1768     StringRef Identifier;
1769     if (getParser().parseIdentifier(Identifier))
1770       return ParseStatus::Failure;
1771 
1772     unsigned Opcode;
1773     if (Identifier == "C0")
1774       Opcode = 0;
1775     else if (Identifier == "C1")
1776       Opcode = 1;
1777     else if (Identifier == "C2")
1778       Opcode = 2;
1779     else
1780       break;
1781 
1782     Res = MCConstantExpr::create(Opcode, getContext());
1783     E = SMLoc::getFromPointer(S.getPointer() + Identifier.size());
1784     Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1785     return ParseStatus::Success;
1786   }
1787   case AsmToken::Percent: {
1788     // Discard operand with modifier.
1789     break;
1790   }
1791   }
1792 
1793   return generateImmOutOfRangeError(
1794       S, 0, 2,
1795       "opcode must be a valid opcode name or an immediate in the range");
1796 }
1797 
1798 ParseStatus RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) {
1799   SMLoc S = getLoc();
1800   const MCExpr *Res;
1801 
1802   switch (getLexer().getKind()) {
1803   default:
1804     return ParseStatus::NoMatch;
1805   case AsmToken::LParen:
1806   case AsmToken::Minus:
1807   case AsmToken::Plus:
1808   case AsmToken::Exclaim:
1809   case AsmToken::Tilde:
1810   case AsmToken::Integer:
1811   case AsmToken::String: {
1812     if (getParser().parseExpression(Res))
1813       return ParseStatus::Failure;
1814 
1815     auto *CE = dyn_cast<MCConstantExpr>(Res);
1816     if (CE) {
1817       int64_t Imm = CE->getValue();
1818       if (isUInt<12>(Imm)) {
1819         auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm);
1820         // Accept an immediate representing a named or un-named Sys Reg
1821         // if the range is valid, regardless of the required features.
1822         Operands.push_back(
1823             RISCVOperand::createSysReg(SysReg ? SysReg->Name : "", S, Imm));
1824         return ParseStatus::Success;
1825       }
1826     }
1827 
1828     return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
1829   }
1830   case AsmToken::Identifier: {
1831     StringRef Identifier;
1832     if (getParser().parseIdentifier(Identifier))
1833       return ParseStatus::Failure;
1834 
1835     // Check for CSR names conflicts.
1836     // Custom CSR names might conflict with CSR names in privileged spec.
1837     // E.g. - SiFive mnscratch(0x350) and privileged spec mnscratch(0x740).
1838     auto CheckCSRNameConflict = [&]() {
1839       if (!(RISCVSysReg::lookupSysRegByName(Identifier))) {
1840         Error(S, "system register use requires an option to be enabled");
1841         return true;
1842       }
1843       return false;
1844     };
1845 
1846     // First check for vendor specific CSRs.
1847     auto SiFiveReg = RISCVSysReg::lookupSiFiveRegByName(Identifier);
1848     if (SiFiveReg) {
1849       if (SiFiveReg->haveVendorRequiredFeatures(getSTI().getFeatureBits())) {
1850         Operands.push_back(
1851             RISCVOperand::createSysReg(Identifier, S, SiFiveReg->Encoding));
1852         return ParseStatus::Success;
1853       }
1854       if (CheckCSRNameConflict())
1855         return ParseStatus::Failure;
1856     }
1857 
1858     auto SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
1859     if (!SysReg)
1860       if ((SysReg = RISCVSysReg::lookupSysRegByDeprecatedName(Identifier)))
1861         Warning(S, "'" + Identifier + "' is a deprecated alias for '" +
1862                        SysReg->Name + "'");
1863 
1864     // Check for CSR encoding conflicts.
1865     // Custom CSR encoding might conflict with CSR encoding in privileged spec.
1866     // E.g. - SiFive mnscratch(0x350) and privileged spec miselect(0x350).
1867     auto CheckCSREncodingConflict = [&]() {
1868       auto Reg = RISCVSysReg::lookupSiFiveRegByEncoding(SysReg->Encoding);
1869       if (Reg && Reg->haveVendorRequiredFeatures(getSTI().getFeatureBits())) {
1870         Warning(S, "'" + Identifier + "' CSR is not available on the current " +
1871                        "subtarget. Instead '" + Reg->Name +
1872                        "' CSR will be used.");
1873         Operands.push_back(
1874             RISCVOperand::createSysReg(Reg->Name, S, Reg->Encoding));
1875         return true;
1876       }
1877       return false;
1878     };
1879 
1880     // Accept a named SysReg if the required features are present.
1881     if (SysReg) {
1882       if (!SysReg->haveRequiredFeatures(getSTI().getFeatureBits()))
1883         return Error(S, "system register use requires an option to be enabled");
1884       if (CheckCSREncodingConflict())
1885         return ParseStatus::Success;
1886       Operands.push_back(
1887           RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
1888       return ParseStatus::Success;
1889     }
1890 
1891     return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
1892                                       "operand must be a valid system register "
1893                                       "name or an integer in the range");
1894   }
1895   case AsmToken::Percent: {
1896     // Discard operand with modifier.
1897     return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
1898   }
1899   }
1900 
1901   return ParseStatus::NoMatch;
1902 }
1903 
1904 ParseStatus RISCVAsmParser::parseFPImm(OperandVector &Operands) {
1905   SMLoc S = getLoc();
1906 
1907   // Parse special floats (inf/nan/min) representation.
1908   if (getTok().is(AsmToken::Identifier)) {
1909     StringRef Identifier = getTok().getIdentifier();
1910     if (Identifier.compare_insensitive("inf") == 0) {
1911       Operands.push_back(
1912           RISCVOperand::createImm(MCConstantExpr::create(30, getContext()), S,
1913                                   getTok().getEndLoc(), isRV64()));
1914     } else if (Identifier.compare_insensitive("nan") == 0) {
1915       Operands.push_back(
1916           RISCVOperand::createImm(MCConstantExpr::create(31, getContext()), S,
1917                                   getTok().getEndLoc(), isRV64()));
1918     } else if (Identifier.compare_insensitive("min") == 0) {
1919       Operands.push_back(
1920           RISCVOperand::createImm(MCConstantExpr::create(1, getContext()), S,
1921                                   getTok().getEndLoc(), isRV64()));
1922     } else {
1923       return TokError("invalid floating point literal");
1924     }
1925 
1926     Lex(); // Eat the token.
1927 
1928     return ParseStatus::Success;
1929   }
1930 
1931   // Handle negation, as that still comes through as a separate token.
1932   bool IsNegative = parseOptionalToken(AsmToken::Minus);
1933 
1934   const AsmToken &Tok = getTok();
1935   if (!Tok.is(AsmToken::Real))
1936     return TokError("invalid floating point immediate");
1937 
1938   // Parse FP representation.
1939   APFloat RealVal(APFloat::IEEEdouble());
1940   auto StatusOrErr =
1941       RealVal.convertFromString(Tok.getString(), APFloat::rmTowardZero);
1942   if (errorToBool(StatusOrErr.takeError()))
1943     return TokError("invalid floating point representation");
1944 
1945   if (IsNegative)
1946     RealVal.changeSign();
1947 
1948   Operands.push_back(RISCVOperand::createFPImm(
1949       RealVal.bitcastToAPInt().getZExtValue(), S));
1950 
1951   Lex(); // Eat the token.
1952 
1953   return ParseStatus::Success;
1954 }
1955 
1956 ParseStatus RISCVAsmParser::parseImmediate(OperandVector &Operands) {
1957   SMLoc S = getLoc();
1958   SMLoc E;
1959   const MCExpr *Res;
1960 
1961   switch (getLexer().getKind()) {
1962   default:
1963     return ParseStatus::NoMatch;
1964   case AsmToken::LParen:
1965   case AsmToken::Dot:
1966   case AsmToken::Minus:
1967   case AsmToken::Plus:
1968   case AsmToken::Exclaim:
1969   case AsmToken::Tilde:
1970   case AsmToken::Integer:
1971   case AsmToken::String:
1972   case AsmToken::Identifier:
1973     if (getParser().parseExpression(Res, E))
1974       return ParseStatus::Failure;
1975     break;
1976   case AsmToken::Percent:
1977     return parseOperandWithModifier(Operands);
1978   }
1979 
1980   Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1981   return ParseStatus::Success;
1982 }
1983 
1984 ParseStatus RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) {
1985   SMLoc S = getLoc();
1986   SMLoc E;
1987 
1988   if (parseToken(AsmToken::Percent, "expected '%' for operand modifier"))
1989     return ParseStatus::Failure;
1990 
1991   if (getLexer().getKind() != AsmToken::Identifier)
1992     return Error(getLoc(), "expected valid identifier for operand modifier");
1993   StringRef Identifier = getParser().getTok().getIdentifier();
1994   RISCVMCExpr::VariantKind VK = RISCVMCExpr::getVariantKindForName(Identifier);
1995   if (VK == RISCVMCExpr::VK_RISCV_Invalid)
1996     return Error(getLoc(), "unrecognized operand modifier");
1997 
1998   getParser().Lex(); // Eat the identifier
1999   if (parseToken(AsmToken::LParen, "expected '('"))
2000     return ParseStatus::Failure;
2001 
2002   const MCExpr *SubExpr;
2003   if (getParser().parseParenExpression(SubExpr, E))
2004     return ParseStatus::Failure;
2005 
2006   const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, VK, getContext());
2007   Operands.push_back(RISCVOperand::createImm(ModExpr, S, E, isRV64()));
2008   return ParseStatus::Success;
2009 }
2010 
2011 ParseStatus RISCVAsmParser::parseBareSymbol(OperandVector &Operands) {
2012   SMLoc S = getLoc();
2013   const MCExpr *Res;
2014 
2015   if (getLexer().getKind() != AsmToken::Identifier)
2016     return ParseStatus::NoMatch;
2017 
2018   StringRef Identifier;
2019   AsmToken Tok = getLexer().getTok();
2020 
2021   if (getParser().parseIdentifier(Identifier))
2022     return ParseStatus::Failure;
2023 
2024   SMLoc E = SMLoc::getFromPointer(S.getPointer() + Identifier.size());
2025 
2026   if (Identifier.consume_back("@plt"))
2027     return Error(getLoc(), "'@plt' operand not valid for instruction");
2028 
2029   MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
2030 
2031   if (Sym->isVariable()) {
2032     const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false);
2033     if (!isa<MCSymbolRefExpr>(V)) {
2034       getLexer().UnLex(Tok); // Put back if it's not a bare symbol.
2035       return ParseStatus::NoMatch;
2036     }
2037     Res = V;
2038   } else
2039     Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
2040 
2041   MCBinaryExpr::Opcode Opcode;
2042   switch (getLexer().getKind()) {
2043   default:
2044     Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
2045     return ParseStatus::Success;
2046   case AsmToken::Plus:
2047     Opcode = MCBinaryExpr::Add;
2048     getLexer().Lex();
2049     break;
2050   case AsmToken::Minus:
2051     Opcode = MCBinaryExpr::Sub;
2052     getLexer().Lex();
2053     break;
2054   }
2055 
2056   const MCExpr *Expr;
2057   if (getParser().parseExpression(Expr, E))
2058     return ParseStatus::Failure;
2059   Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext());
2060   Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
2061   return ParseStatus::Success;
2062 }
2063 
2064 ParseStatus RISCVAsmParser::parseCallSymbol(OperandVector &Operands) {
2065   SMLoc S = getLoc();
2066   const MCExpr *Res;
2067 
2068   if (getLexer().getKind() != AsmToken::Identifier)
2069     return ParseStatus::NoMatch;
2070 
2071   // Avoid parsing the register in `call rd, foo` as a call symbol.
2072   if (getLexer().peekTok().getKind() != AsmToken::EndOfStatement)
2073     return ParseStatus::NoMatch;
2074 
2075   StringRef Identifier;
2076   if (getParser().parseIdentifier(Identifier))
2077     return ParseStatus::Failure;
2078 
2079   SMLoc E = SMLoc::getFromPointer(S.getPointer() + Identifier.size());
2080 
2081   RISCVMCExpr::VariantKind Kind = RISCVMCExpr::VK_RISCV_CALL;
2082   if (Identifier.consume_back("@plt"))
2083     Kind = RISCVMCExpr::VK_RISCV_CALL_PLT;
2084 
2085   MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
2086   Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
2087   Res = RISCVMCExpr::create(Res, Kind, getContext());
2088   Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
2089   return ParseStatus::Success;
2090 }
2091 
2092 ParseStatus RISCVAsmParser::parsePseudoJumpSymbol(OperandVector &Operands) {
2093   SMLoc S = getLoc();
2094   SMLoc E;
2095   const MCExpr *Res;
2096 
2097   if (getParser().parseExpression(Res, E))
2098     return ParseStatus::Failure;
2099 
2100   if (Res->getKind() != MCExpr::ExprKind::SymbolRef ||
2101       cast<MCSymbolRefExpr>(Res)->getKind() ==
2102           MCSymbolRefExpr::VariantKind::VK_PLT)
2103     return Error(S, "operand must be a valid jump target");
2104 
2105   Res = RISCVMCExpr::create(Res, RISCVMCExpr::VK_RISCV_CALL, getContext());
2106   Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
2107   return ParseStatus::Success;
2108 }
2109 
2110 ParseStatus RISCVAsmParser::parseJALOffset(OperandVector &Operands) {
2111   // Parsing jal operands is fiddly due to the `jal foo` and `jal ra, foo`
2112   // both being acceptable forms. When parsing `jal ra, foo` this function
2113   // will be called for the `ra` register operand in an attempt to match the
2114   // single-operand alias. parseJALOffset must fail for this case. It would
2115   // seem logical to try parse the operand using parseImmediate and return
2116   // NoMatch if the next token is a comma (meaning we must be parsing a jal in
2117   // the second form rather than the first). We can't do this as there's no
2118   // way of rewinding the lexer state. Instead, return NoMatch if this operand
2119   // is an identifier and is followed by a comma.
2120   if (getLexer().is(AsmToken::Identifier) &&
2121       getLexer().peekTok().is(AsmToken::Comma))
2122     return ParseStatus::NoMatch;
2123 
2124   return parseImmediate(Operands);
2125 }
2126 
2127 bool RISCVAsmParser::parseVTypeToken(StringRef Identifier, VTypeState &State,
2128                                      unsigned &Sew, unsigned &Lmul,
2129                                      bool &Fractional, bool &TailAgnostic,
2130                                      bool &MaskAgnostic) {
2131   switch (State) {
2132   case VTypeState_SEW:
2133     if (!Identifier.consume_front("e"))
2134       break;
2135     if (Identifier.getAsInteger(10, Sew))
2136       break;
2137     if (!RISCVVType::isValidSEW(Sew))
2138       break;
2139     State = VTypeState_LMUL;
2140     return false;
2141   case VTypeState_LMUL: {
2142     if (!Identifier.consume_front("m"))
2143       break;
2144     Fractional = Identifier.consume_front("f");
2145     if (Identifier.getAsInteger(10, Lmul))
2146       break;
2147     if (!RISCVVType::isValidLMUL(Lmul, Fractional))
2148       break;
2149     State = VTypeState_TailPolicy;
2150     return false;
2151   }
2152   case VTypeState_TailPolicy:
2153     if (Identifier == "ta")
2154       TailAgnostic = true;
2155     else if (Identifier == "tu")
2156       TailAgnostic = false;
2157     else
2158       break;
2159     State = VTypeState_MaskPolicy;
2160     return false;
2161   case VTypeState_MaskPolicy:
2162     if (Identifier == "ma")
2163       MaskAgnostic = true;
2164     else if (Identifier == "mu")
2165       MaskAgnostic = false;
2166     else
2167       break;
2168     State = VTypeState_Done;
2169     return false;
2170   case VTypeState_Done:
2171     // Extra token?
2172     break;
2173   }
2174 
2175   return true;
2176 }
2177 
2178 ParseStatus RISCVAsmParser::parseVTypeI(OperandVector &Operands) {
2179   SMLoc S = getLoc();
2180 
2181   unsigned Sew = 0;
2182   unsigned Lmul = 0;
2183   bool Fractional = false;
2184   bool TailAgnostic = false;
2185   bool MaskAgnostic = false;
2186 
2187   VTypeState State = VTypeState_SEW;
2188 
2189   if (getLexer().isNot(AsmToken::Identifier))
2190     return ParseStatus::NoMatch;
2191 
2192   StringRef Identifier = getTok().getIdentifier();
2193 
2194   if (parseVTypeToken(Identifier, State, Sew, Lmul, Fractional, TailAgnostic,
2195                       MaskAgnostic))
2196     return ParseStatus::NoMatch;
2197 
2198   getLexer().Lex();
2199 
2200   while (parseOptionalToken(AsmToken::Comma)) {
2201     if (getLexer().isNot(AsmToken::Identifier))
2202       break;
2203 
2204     Identifier = getTok().getIdentifier();
2205 
2206     if (parseVTypeToken(Identifier, State, Sew, Lmul, Fractional, TailAgnostic,
2207                         MaskAgnostic))
2208       break;
2209 
2210     getLexer().Lex();
2211   }
2212 
2213   if (getLexer().is(AsmToken::EndOfStatement) && State == VTypeState_Done) {
2214     RISCVII::VLMUL VLMUL = RISCVVType::encodeLMUL(Lmul, Fractional);
2215 
2216     unsigned VTypeI =
2217         RISCVVType::encodeVTYPE(VLMUL, Sew, TailAgnostic, MaskAgnostic);
2218     Operands.push_back(RISCVOperand::createVType(VTypeI, S));
2219     return ParseStatus::Success;
2220   }
2221 
2222   return generateVTypeError(S);
2223 }
2224 
2225 bool RISCVAsmParser::generateVTypeError(SMLoc ErrorLoc) {
2226   return Error(
2227       ErrorLoc,
2228       "operand must be "
2229       "e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2230 }
2231 
2232 ParseStatus RISCVAsmParser::parseMaskReg(OperandVector &Operands) {
2233   if (getLexer().isNot(AsmToken::Identifier))
2234     return ParseStatus::NoMatch;
2235 
2236   StringRef Name = getLexer().getTok().getIdentifier();
2237   if (!Name.consume_back(".t"))
2238     return Error(getLoc(), "expected '.t' suffix");
2239   MCRegister RegNo = matchRegisterNameHelper(isRVE(), Name);
2240 
2241   if (!RegNo)
2242     return ParseStatus::NoMatch;
2243   if (RegNo != RISCV::V0)
2244     return ParseStatus::NoMatch;
2245   SMLoc S = getLoc();
2246   SMLoc E = SMLoc::getFromPointer(S.getPointer() + Name.size());
2247   getLexer().Lex();
2248   Operands.push_back(RISCVOperand::createReg(RegNo, S, E));
2249   return ParseStatus::Success;
2250 }
2251 
2252 ParseStatus RISCVAsmParser::parseGPRAsFPR(OperandVector &Operands) {
2253   if (getLexer().isNot(AsmToken::Identifier))
2254     return ParseStatus::NoMatch;
2255 
2256   StringRef Name = getLexer().getTok().getIdentifier();
2257   MCRegister RegNo = matchRegisterNameHelper(isRVE(), Name);
2258 
2259   if (!RegNo)
2260     return ParseStatus::NoMatch;
2261   SMLoc S = getLoc();
2262   SMLoc E = SMLoc::getFromPointer(S.getPointer() + Name.size());
2263   getLexer().Lex();
2264   Operands.push_back(RISCVOperand::createReg(
2265       RegNo, S, E, !getSTI().hasFeature(RISCV::FeatureStdExtF)));
2266   return ParseStatus::Success;
2267 }
2268 
2269 ParseStatus RISCVAsmParser::parseFRMArg(OperandVector &Operands) {
2270   if (getLexer().isNot(AsmToken::Identifier))
2271     return TokError(
2272         "operand must be a valid floating point rounding mode mnemonic");
2273 
2274   StringRef Str = getLexer().getTok().getIdentifier();
2275   RISCVFPRndMode::RoundingMode FRM = RISCVFPRndMode::stringToRoundingMode(Str);
2276 
2277   if (FRM == RISCVFPRndMode::Invalid)
2278     return TokError(
2279         "operand must be a valid floating point rounding mode mnemonic");
2280 
2281   Operands.push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
2282   Lex(); // Eat identifier token.
2283   return ParseStatus::Success;
2284 }
2285 
2286 ParseStatus RISCVAsmParser::parseFenceArg(OperandVector &Operands) {
2287   const AsmToken &Tok = getLexer().getTok();
2288 
2289   if (Tok.is(AsmToken::Integer)) {
2290     if (Tok.getIntVal() != 0)
2291       goto ParseFail;
2292 
2293     Operands.push_back(RISCVOperand::createFenceArg(0, getLoc()));
2294     Lex();
2295     return ParseStatus::Success;
2296   }
2297 
2298   if (Tok.is(AsmToken::Identifier)) {
2299     StringRef Str = Tok.getIdentifier();
2300 
2301     // Letters must be unique, taken from 'iorw', and in ascending order. This
2302     // holds as long as each individual character is one of 'iorw' and is
2303     // greater than the previous character.
2304     unsigned Imm = 0;
2305     bool Valid = true;
2306     char Prev = '\0';
2307     for (char c : Str) {
2308       switch (c) {
2309       default:
2310         Valid = false;
2311         break;
2312       case 'i':
2313         Imm |= RISCVFenceField::I;
2314         break;
2315       case 'o':
2316         Imm |= RISCVFenceField::O;
2317         break;
2318       case 'r':
2319         Imm |= RISCVFenceField::R;
2320         break;
2321       case 'w':
2322         Imm |= RISCVFenceField::W;
2323         break;
2324       }
2325 
2326       if (c <= Prev) {
2327         Valid = false;
2328         break;
2329       }
2330       Prev = c;
2331     }
2332 
2333     if (!Valid)
2334       goto ParseFail;
2335 
2336     Operands.push_back(RISCVOperand::createFenceArg(Imm, getLoc()));
2337     Lex();
2338     return ParseStatus::Success;
2339   }
2340 
2341 ParseFail:
2342   return TokError("operand must be formed of letters selected in-order from "
2343                   "'iorw' or be 0");
2344 }
2345 
2346 ParseStatus RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) {
2347   if (parseToken(AsmToken::LParen, "expected '('"))
2348     return ParseStatus::Failure;
2349   Operands.push_back(RISCVOperand::createToken("(", getLoc()));
2350 
2351   if (!parseRegister(Operands).isSuccess())
2352     return Error(getLoc(), "expected register");
2353 
2354   if (parseToken(AsmToken::RParen, "expected ')'"))
2355     return ParseStatus::Failure;
2356   Operands.push_back(RISCVOperand::createToken(")", getLoc()));
2357 
2358   return ParseStatus::Success;
2359 }
2360 
2361 ParseStatus RISCVAsmParser::parseZeroOffsetMemOp(OperandVector &Operands) {
2362   // Atomic operations such as lr.w, sc.w, and amo*.w accept a "memory operand"
2363   // as one of their register operands, such as `(a0)`. This just denotes that
2364   // the register (in this case `a0`) contains a memory address.
2365   //
2366   // Normally, we would be able to parse these by putting the parens into the
2367   // instruction string. However, GNU as also accepts a zero-offset memory
2368   // operand (such as `0(a0)`), and ignores the 0. Normally this would be parsed
2369   // with parseImmediate followed by parseMemOpBaseReg, but these instructions
2370   // do not accept an immediate operand, and we do not want to add a "dummy"
2371   // operand that is silently dropped.
2372   //
2373   // Instead, we use this custom parser. This will: allow (and discard) an
2374   // offset if it is zero; require (and discard) parentheses; and add only the
2375   // parsed register operand to `Operands`.
2376   //
2377   // These operands are printed with RISCVInstPrinter::printZeroOffsetMemOp,
2378   // which will only print the register surrounded by parentheses (which GNU as
2379   // also uses as its canonical representation for these operands).
2380   std::unique_ptr<RISCVOperand> OptionalImmOp;
2381 
2382   if (getLexer().isNot(AsmToken::LParen)) {
2383     // Parse an Integer token. We do not accept arbritrary constant expressions
2384     // in the offset field (because they may include parens, which complicates
2385     // parsing a lot).
2386     int64_t ImmVal;
2387     SMLoc ImmStart = getLoc();
2388     if (getParser().parseIntToken(ImmVal,
2389                                   "expected '(' or optional integer offset"))
2390       return ParseStatus::Failure;
2391 
2392     // Create a RISCVOperand for checking later (so the error messages are
2393     // nicer), but we don't add it to Operands.
2394     SMLoc ImmEnd = getLoc();
2395     OptionalImmOp =
2396         RISCVOperand::createImm(MCConstantExpr::create(ImmVal, getContext()),
2397                                 ImmStart, ImmEnd, isRV64());
2398   }
2399 
2400   if (parseToken(AsmToken::LParen,
2401                  OptionalImmOp ? "expected '(' after optional integer offset"
2402                                : "expected '(' or optional integer offset"))
2403     return ParseStatus::Failure;
2404 
2405   if (!parseRegister(Operands).isSuccess())
2406     return Error(getLoc(), "expected register");
2407 
2408   if (parseToken(AsmToken::RParen, "expected ')'"))
2409     return ParseStatus::Failure;
2410 
2411   // Deferred Handling of non-zero offsets. This makes the error messages nicer.
2412   if (OptionalImmOp && !OptionalImmOp->isImmZero())
2413     return Error(
2414         OptionalImmOp->getStartLoc(), "optional integer offset must be 0",
2415         SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
2416 
2417   return ParseStatus::Success;
2418 }
2419 
2420 ParseStatus RISCVAsmParser::parseRegReg(OperandVector &Operands) {
2421   // RR : a2(a1)
2422   if (getLexer().getKind() != AsmToken::Identifier)
2423     return ParseStatus::NoMatch;
2424 
2425   StringRef RegName = getLexer().getTok().getIdentifier();
2426   MCRegister Reg = matchRegisterNameHelper(isRVE(), RegName);
2427   if (!Reg)
2428     return Error(getLoc(), "invalid register");
2429   getLexer().Lex();
2430 
2431   if (parseToken(AsmToken::LParen, "expected '(' or invalid operand"))
2432     return ParseStatus::Failure;
2433 
2434   if (getLexer().getKind() != AsmToken::Identifier)
2435     return Error(getLoc(), "expected register");
2436 
2437   StringRef Reg2Name = getLexer().getTok().getIdentifier();
2438   MCRegister Reg2 = matchRegisterNameHelper(isRVE(), Reg2Name);
2439   if (!Reg2)
2440     return Error(getLoc(), "invalid register");
2441   getLexer().Lex();
2442 
2443   if (parseToken(AsmToken::RParen, "expected ')'"))
2444     return ParseStatus::Failure;
2445 
2446   Operands.push_back(RISCVOperand::createRegReg(Reg, Reg2, getLoc()));
2447 
2448   return ParseStatus::Success;
2449 }
2450 
2451 ParseStatus RISCVAsmParser::parseReglist(OperandVector &Operands) {
2452   // Rlist: {ra [, s0[-sN]]}
2453   // XRlist: {x1 [, x8[-x9][, x18[-xN]]]}
2454   SMLoc S = getLoc();
2455 
2456   if (parseToken(AsmToken::LCurly, "register list must start with '{'"))
2457     return ParseStatus::Failure;
2458 
2459   bool IsEABI = isRVE();
2460 
2461   if (getLexer().isNot(AsmToken::Identifier))
2462     return Error(getLoc(), "register list must start from 'ra' or 'x1'");
2463 
2464   StringRef RegName = getLexer().getTok().getIdentifier();
2465   MCRegister RegStart = matchRegisterNameHelper(IsEABI, RegName);
2466   MCRegister RegEnd;
2467   if (RegStart != RISCV::X1)
2468     return Error(getLoc(), "register list must start from 'ra' or 'x1'");
2469   getLexer().Lex();
2470 
2471   // parse case like ,s0
2472   if (parseOptionalToken(AsmToken::Comma)) {
2473     if (getLexer().isNot(AsmToken::Identifier))
2474       return Error(getLoc(), "invalid register");
2475     StringRef RegName = getLexer().getTok().getIdentifier();
2476     RegStart = matchRegisterNameHelper(IsEABI, RegName);
2477     if (!RegStart)
2478       return Error(getLoc(), "invalid register");
2479     if (RegStart != RISCV::X8)
2480       return Error(getLoc(),
2481                    "continuous register list must start from 's0' or 'x8'");
2482     getLexer().Lex(); // eat reg
2483   }
2484 
2485   // parse case like -s1
2486   if (parseOptionalToken(AsmToken::Minus)) {
2487     StringRef EndName = getLexer().getTok().getIdentifier();
2488     // FIXME: the register mapping and checks of EABI is wrong
2489     RegEnd = matchRegisterNameHelper(IsEABI, EndName);
2490     if (!RegEnd)
2491       return Error(getLoc(), "invalid register");
2492     if (IsEABI && RegEnd != RISCV::X9)
2493       return Error(getLoc(), "contiguous register list of EABI can only be "
2494                              "'s0-s1' or 'x8-x9' pair");
2495     getLexer().Lex();
2496   }
2497 
2498   if (!IsEABI) {
2499     // parse extra part like ', x18[-x20]' for XRegList
2500     if (parseOptionalToken(AsmToken::Comma)) {
2501       if (RegEnd != RISCV::X9)
2502         return Error(
2503             getLoc(),
2504             "first contiguous registers pair of register list must be 'x8-x9'");
2505 
2506       // parse ', x18' for extra part
2507       if (getLexer().isNot(AsmToken::Identifier))
2508         return Error(getLoc(), "invalid register");
2509       StringRef EndName = getLexer().getTok().getIdentifier();
2510       if (MatchRegisterName(EndName) != RISCV::X18)
2511         return Error(getLoc(),
2512                      "second contiguous registers pair of register list "
2513                      "must start from 'x18'");
2514       getLexer().Lex();
2515 
2516       // parse '-x20' for extra part
2517       if (parseOptionalToken(AsmToken::Minus)) {
2518         if (getLexer().isNot(AsmToken::Identifier))
2519           return Error(getLoc(), "invalid register");
2520         EndName = getLexer().getTok().getIdentifier();
2521         if (MatchRegisterName(EndName) == RISCV::NoRegister)
2522           return Error(getLoc(), "invalid register");
2523         getLexer().Lex();
2524       }
2525       RegEnd = MatchRegisterName(EndName);
2526     }
2527   }
2528 
2529   if (RegEnd == RISCV::X26)
2530     return Error(getLoc(), "invalid register list, {ra, s0-s10} or {x1, x8-x9, "
2531                            "x18-x26} is not supported");
2532 
2533   if (parseToken(AsmToken::RCurly, "register list must end with '}'"))
2534     return ParseStatus::Failure;
2535 
2536   if (RegEnd == RISCV::NoRegister)
2537     RegEnd = RegStart;
2538 
2539   auto Encode = RISCVZC::encodeRlist(RegEnd, IsEABI);
2540   if (Encode == 16)
2541     return Error(S, "invalid register list");
2542   Operands.push_back(RISCVOperand::createRlist(Encode, S));
2543 
2544   return ParseStatus::Success;
2545 }
2546 
2547 ParseStatus RISCVAsmParser::parseZcmpSpimm(OperandVector &Operands) {
2548   (void)parseOptionalToken(AsmToken::Minus);
2549 
2550   SMLoc S = getLoc();
2551   int64_t StackAdjustment = getLexer().getTok().getIntVal();
2552   unsigned Spimm = 0;
2553   unsigned RlistVal = static_cast<RISCVOperand *>(Operands[1].get())->Rlist.Val;
2554 
2555   bool IsEABI = isRVE();
2556   if (!RISCVZC::getSpimm(RlistVal, Spimm, StackAdjustment, isRV64(), IsEABI))
2557     return ParseStatus::NoMatch;
2558   Operands.push_back(RISCVOperand::createSpimm(Spimm << 4, S));
2559   getLexer().Lex();
2560   return ParseStatus::Success;
2561 }
2562 
2563 /// Looks at a token type and creates the relevant operand from this
2564 /// information, adding to Operands. If operand was parsed, returns false, else
2565 /// true.
2566 bool RISCVAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2567   // Check if the current operand has a custom associated parser, if so, try to
2568   // custom parse the operand, or fallback to the general approach.
2569   ParseStatus Result =
2570       MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true);
2571   if (Result.isSuccess())
2572     return false;
2573   if (Result.isFailure())
2574     return true;
2575 
2576   // Attempt to parse token as a register.
2577   if (parseRegister(Operands, true).isSuccess())
2578     return false;
2579 
2580   // Attempt to parse token as an immediate
2581   if (parseImmediate(Operands).isSuccess()) {
2582     // Parse memory base register if present
2583     if (getLexer().is(AsmToken::LParen))
2584       return !parseMemOpBaseReg(Operands).isSuccess();
2585     return false;
2586   }
2587 
2588   // Finally we have exhausted all options and must declare defeat.
2589   Error(getLoc(), "unknown operand");
2590   return true;
2591 }
2592 
2593 bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info,
2594                                       StringRef Name, SMLoc NameLoc,
2595                                       OperandVector &Operands) {
2596   // Ensure that if the instruction occurs when relaxation is enabled,
2597   // relocations are forced for the file. Ideally this would be done when there
2598   // is enough information to reliably determine if the instruction itself may
2599   // cause relaxations. Unfortunately instruction processing stage occurs in the
2600   // same pass as relocation emission, so it's too late to set a 'sticky bit'
2601   // for the entire file.
2602   if (getSTI().hasFeature(RISCV::FeatureRelax)) {
2603     auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr();
2604     if (Assembler != nullptr) {
2605       RISCVAsmBackend &MAB =
2606           static_cast<RISCVAsmBackend &>(Assembler->getBackend());
2607       MAB.setForceRelocs();
2608     }
2609   }
2610 
2611   // First operand is token for instruction
2612   Operands.push_back(RISCVOperand::createToken(Name, NameLoc));
2613 
2614   // If there are no more operands, then finish
2615   if (getLexer().is(AsmToken::EndOfStatement)) {
2616     getParser().Lex(); // Consume the EndOfStatement.
2617     return false;
2618   }
2619 
2620   // Parse first operand
2621   if (parseOperand(Operands, Name))
2622     return true;
2623 
2624   // Parse until end of statement, consuming commas between operands
2625   while (parseOptionalToken(AsmToken::Comma)) {
2626     // Parse next operand
2627     if (parseOperand(Operands, Name))
2628       return true;
2629   }
2630 
2631   if (getParser().parseEOL("unexpected token")) {
2632     getParser().eatToEndOfStatement();
2633     return true;
2634   }
2635   return false;
2636 }
2637 
2638 bool RISCVAsmParser::classifySymbolRef(const MCExpr *Expr,
2639                                        RISCVMCExpr::VariantKind &Kind) {
2640   Kind = RISCVMCExpr::VK_RISCV_None;
2641 
2642   if (const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) {
2643     Kind = RE->getKind();
2644     Expr = RE->getSubExpr();
2645   }
2646 
2647   MCValue Res;
2648   MCFixup Fixup;
2649   if (Expr->evaluateAsRelocatable(Res, nullptr, &Fixup))
2650     return Res.getRefKind() == RISCVMCExpr::VK_RISCV_None;
2651   return false;
2652 }
2653 
2654 bool RISCVAsmParser::isSymbolDiff(const MCExpr *Expr) {
2655   MCValue Res;
2656   MCFixup Fixup;
2657   if (Expr->evaluateAsRelocatable(Res, nullptr, &Fixup)) {
2658     return Res.getRefKind() == RISCVMCExpr::VK_RISCV_None && Res.getSymA() &&
2659            Res.getSymB();
2660   }
2661   return false;
2662 }
2663 
2664 ParseStatus RISCVAsmParser::parseDirective(AsmToken DirectiveID) {
2665   StringRef IDVal = DirectiveID.getString();
2666 
2667   if (IDVal == ".option")
2668     return parseDirectiveOption();
2669   if (IDVal == ".attribute")
2670     return parseDirectiveAttribute();
2671   if (IDVal == ".insn")
2672     return parseDirectiveInsn(DirectiveID.getLoc());
2673   if (IDVal == ".variant_cc")
2674     return parseDirectiveVariantCC();
2675 
2676   return ParseStatus::NoMatch;
2677 }
2678 
2679 bool RISCVAsmParser::resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
2680                                  bool FromOptionDirective) {
2681   for (auto Feature : RISCVFeatureKV)
2682     if (llvm::RISCVISAInfo::isSupportedExtensionFeature(Feature.Key))
2683       clearFeatureBits(Feature.Value, Feature.Key);
2684 
2685   auto ParseResult = llvm::RISCVISAInfo::parseArchString(
2686       Arch, /*EnableExperimentalExtension=*/true,
2687       /*ExperimentalExtensionVersionCheck=*/true);
2688   if (!ParseResult) {
2689     std::string Buffer;
2690     raw_string_ostream OutputErrMsg(Buffer);
2691     handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
2692       OutputErrMsg << "invalid arch name '" << Arch << "', "
2693                    << ErrMsg.getMessage();
2694     });
2695 
2696     return Error(Loc, OutputErrMsg.str());
2697   }
2698   auto &ISAInfo = *ParseResult;
2699 
2700   for (auto Feature : RISCVFeatureKV)
2701     if (ISAInfo->hasExtension(Feature.Key))
2702       setFeatureBits(Feature.Value, Feature.Key);
2703 
2704   if (FromOptionDirective) {
2705     if (ISAInfo->getXLen() == 32 && isRV64())
2706       return Error(Loc, "bad arch string switching from rv64 to rv32");
2707     else if (ISAInfo->getXLen() == 64 && !isRV64())
2708       return Error(Loc, "bad arch string switching from rv32 to rv64");
2709   }
2710 
2711   if (ISAInfo->getXLen() == 32)
2712     clearFeatureBits(RISCV::Feature64Bit, "64bit");
2713   else if (ISAInfo->getXLen() == 64)
2714     setFeatureBits(RISCV::Feature64Bit, "64bit");
2715   else
2716     return Error(Loc, "bad arch string " + Arch);
2717 
2718   Result = ISAInfo->toString();
2719   return false;
2720 }
2721 
2722 bool RISCVAsmParser::parseDirectiveOption() {
2723   MCAsmParser &Parser = getParser();
2724   // Get the option token.
2725   AsmToken Tok = Parser.getTok();
2726 
2727   // At the moment only identifiers are supported.
2728   if (parseToken(AsmToken::Identifier, "expected identifier"))
2729     return true;
2730 
2731   StringRef Option = Tok.getIdentifier();
2732 
2733   if (Option == "push") {
2734     if (Parser.parseEOL())
2735       return true;
2736 
2737     getTargetStreamer().emitDirectiveOptionPush();
2738     pushFeatureBits();
2739     return false;
2740   }
2741 
2742   if (Option == "pop") {
2743     SMLoc StartLoc = Parser.getTok().getLoc();
2744     if (Parser.parseEOL())
2745       return true;
2746 
2747     getTargetStreamer().emitDirectiveOptionPop();
2748     if (popFeatureBits())
2749       return Error(StartLoc, ".option pop with no .option push");
2750 
2751     return false;
2752   }
2753 
2754   if (Option == "arch") {
2755     SmallVector<RISCVOptionArchArg> Args;
2756     do {
2757       if (Parser.parseComma())
2758         return true;
2759 
2760       RISCVOptionArchArgType Type;
2761       if (parseOptionalToken(AsmToken::Plus))
2762         Type = RISCVOptionArchArgType::Plus;
2763       else if (parseOptionalToken(AsmToken::Minus))
2764         Type = RISCVOptionArchArgType::Minus;
2765       else if (!Args.empty())
2766         return Error(Parser.getTok().getLoc(),
2767                      "unexpected token, expected + or -");
2768       else
2769         Type = RISCVOptionArchArgType::Full;
2770 
2771       if (Parser.getTok().isNot(AsmToken::Identifier))
2772         return Error(Parser.getTok().getLoc(),
2773                      "unexpected token, expected identifier");
2774 
2775       StringRef Arch = Parser.getTok().getString();
2776       SMLoc Loc = Parser.getTok().getLoc();
2777       Parser.Lex();
2778 
2779       if (Type == RISCVOptionArchArgType::Full) {
2780         std::string Result;
2781         if (resetToArch(Arch, Loc, Result, true))
2782           return true;
2783 
2784         Args.emplace_back(Type, Result);
2785         break;
2786       }
2787 
2788       ArrayRef<SubtargetFeatureKV> KVArray(RISCVFeatureKV);
2789       auto Ext = llvm::lower_bound(KVArray, Arch);
2790       if (Ext == KVArray.end() || StringRef(Ext->Key) != Arch ||
2791           !RISCVISAInfo::isSupportedExtension(Arch)) {
2792         if (isDigit(Arch.back()))
2793           return Error(
2794               Loc,
2795               "Extension version number parsing not currently implemented");
2796         return Error(Loc, "unknown extension feature");
2797       }
2798 
2799       Args.emplace_back(Type, Ext->Key);
2800 
2801       if (Type == RISCVOptionArchArgType::Plus) {
2802         FeatureBitset OldFeatureBits = STI->getFeatureBits();
2803 
2804         setFeatureBits(Ext->Value, Ext->Key);
2805         auto ParseResult = RISCVFeatures::parseFeatureBits(isRV64(), STI->getFeatureBits());
2806         if (!ParseResult) {
2807           copySTI().setFeatureBits(OldFeatureBits);
2808           setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
2809 
2810           std::string Buffer;
2811           raw_string_ostream OutputErrMsg(Buffer);
2812           handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
2813             OutputErrMsg << ErrMsg.getMessage();
2814           });
2815 
2816           return Error(Loc, OutputErrMsg.str());
2817         }
2818       } else {
2819         assert(Type == RISCVOptionArchArgType::Minus);
2820         // It is invalid to disable an extension that there are other enabled
2821         // extensions depend on it.
2822         // TODO: Make use of RISCVISAInfo to handle this
2823         for (auto Feature : KVArray) {
2824           if (getSTI().hasFeature(Feature.Value) &&
2825               Feature.Implies.test(Ext->Value))
2826             return Error(Loc,
2827                          Twine("Can't disable ") + Ext->Key + " extension, " +
2828                              Feature.Key + " extension requires " + Ext->Key +
2829                              " extension be enabled");
2830         }
2831 
2832         clearFeatureBits(Ext->Value, Ext->Key);
2833       }
2834     } while (Parser.getTok().isNot(AsmToken::EndOfStatement));
2835 
2836     if (Parser.parseEOL())
2837       return true;
2838 
2839     getTargetStreamer().emitDirectiveOptionArch(Args);
2840     return false;
2841   }
2842 
2843   if (Option == "rvc") {
2844     if (Parser.parseEOL())
2845       return true;
2846 
2847     getTargetStreamer().emitDirectiveOptionRVC();
2848     setFeatureBits(RISCV::FeatureStdExtC, "c");
2849     return false;
2850   }
2851 
2852   if (Option == "norvc") {
2853     if (Parser.parseEOL())
2854       return true;
2855 
2856     getTargetStreamer().emitDirectiveOptionNoRVC();
2857     clearFeatureBits(RISCV::FeatureStdExtC, "c");
2858     clearFeatureBits(RISCV::FeatureStdExtZca, "+zca");
2859     return false;
2860   }
2861 
2862   if (Option == "pic") {
2863     if (Parser.parseEOL())
2864       return true;
2865 
2866     getTargetStreamer().emitDirectiveOptionPIC();
2867     ParserOptions.IsPicEnabled = true;
2868     return false;
2869   }
2870 
2871   if (Option == "nopic") {
2872     if (Parser.parseEOL())
2873       return true;
2874 
2875     getTargetStreamer().emitDirectiveOptionNoPIC();
2876     ParserOptions.IsPicEnabled = false;
2877     return false;
2878   }
2879 
2880   if (Option == "relax") {
2881     if (Parser.parseEOL())
2882       return true;
2883 
2884     getTargetStreamer().emitDirectiveOptionRelax();
2885     setFeatureBits(RISCV::FeatureRelax, "relax");
2886     return false;
2887   }
2888 
2889   if (Option == "norelax") {
2890     if (Parser.parseEOL())
2891       return true;
2892 
2893     getTargetStreamer().emitDirectiveOptionNoRelax();
2894     clearFeatureBits(RISCV::FeatureRelax, "relax");
2895     return false;
2896   }
2897 
2898   // Unknown option.
2899   Warning(Parser.getTok().getLoc(), "unknown option, expected 'push', 'pop', "
2900                                     "'rvc', 'norvc', 'arch', 'relax' or "
2901                                     "'norelax'");
2902   Parser.eatToEndOfStatement();
2903   return false;
2904 }
2905 
2906 /// parseDirectiveAttribute
2907 ///  ::= .attribute expression ',' ( expression | "string" )
2908 ///  ::= .attribute identifier ',' ( expression | "string" )
2909 bool RISCVAsmParser::parseDirectiveAttribute() {
2910   MCAsmParser &Parser = getParser();
2911   int64_t Tag;
2912   SMLoc TagLoc;
2913   TagLoc = Parser.getTok().getLoc();
2914   if (Parser.getTok().is(AsmToken::Identifier)) {
2915     StringRef Name = Parser.getTok().getIdentifier();
2916     std::optional<unsigned> Ret =
2917         ELFAttrs::attrTypeFromString(Name, RISCVAttrs::getRISCVAttributeTags());
2918     if (!Ret)
2919       return Error(TagLoc, "attribute name not recognised: " + Name);
2920     Tag = *Ret;
2921     Parser.Lex();
2922   } else {
2923     const MCExpr *AttrExpr;
2924 
2925     TagLoc = Parser.getTok().getLoc();
2926     if (Parser.parseExpression(AttrExpr))
2927       return true;
2928 
2929     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr);
2930     if (check(!CE, TagLoc, "expected numeric constant"))
2931       return true;
2932 
2933     Tag = CE->getValue();
2934   }
2935 
2936   if (Parser.parseComma())
2937     return true;
2938 
2939   StringRef StringValue;
2940   int64_t IntegerValue = 0;
2941   bool IsIntegerValue = true;
2942 
2943   // RISC-V attributes have a string value if the tag number is odd
2944   // and an integer value if the tag number is even.
2945   if (Tag % 2)
2946     IsIntegerValue = false;
2947 
2948   SMLoc ValueExprLoc = Parser.getTok().getLoc();
2949   if (IsIntegerValue) {
2950     const MCExpr *ValueExpr;
2951     if (Parser.parseExpression(ValueExpr))
2952       return true;
2953 
2954     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr);
2955     if (!CE)
2956       return Error(ValueExprLoc, "expected numeric constant");
2957     IntegerValue = CE->getValue();
2958   } else {
2959     if (Parser.getTok().isNot(AsmToken::String))
2960       return Error(Parser.getTok().getLoc(), "expected string constant");
2961 
2962     StringValue = Parser.getTok().getStringContents();
2963     Parser.Lex();
2964   }
2965 
2966   if (Parser.parseEOL())
2967     return true;
2968 
2969   if (IsIntegerValue)
2970     getTargetStreamer().emitAttribute(Tag, IntegerValue);
2971   else if (Tag != RISCVAttrs::ARCH)
2972     getTargetStreamer().emitTextAttribute(Tag, StringValue);
2973   else {
2974     std::string Result;
2975     if (resetToArch(StringValue, ValueExprLoc, Result, false))
2976       return true;
2977 
2978     // Then emit the arch string.
2979     getTargetStreamer().emitTextAttribute(Tag, Result);
2980   }
2981 
2982   return false;
2983 }
2984 
2985 bool isValidInsnFormat(StringRef Format, bool AllowC) {
2986   return StringSwitch<bool>(Format)
2987       .Cases("r", "r4", "i", "b", "sb", "u", "j", "uj", "s", true)
2988       .Cases("cr", "ci", "ciw", "css", "cl", "cs", "ca", "cb", "cj", AllowC)
2989       .Default(false);
2990 }
2991 
2992 /// parseDirectiveInsn
2993 /// ::= .insn [ format encoding, (operands (, operands)*) ]
2994 bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) {
2995   MCAsmParser &Parser = getParser();
2996 
2997   // Expect instruction format as identifier.
2998   StringRef Format;
2999   SMLoc ErrorLoc = Parser.getTok().getLoc();
3000   if (Parser.parseIdentifier(Format))
3001     return Error(ErrorLoc, "expected instruction format");
3002 
3003   bool AllowC = getSTI().hasFeature(RISCV::FeatureStdExtC) ||
3004                 getSTI().hasFeature(RISCV::FeatureStdExtZca);
3005   if (!isValidInsnFormat(Format, AllowC))
3006     return Error(ErrorLoc, "invalid instruction format");
3007 
3008   std::string FormatName = (".insn_" + Format).str();
3009 
3010   ParseInstructionInfo Info;
3011   SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> Operands;
3012 
3013   if (ParseInstruction(Info, FormatName, L, Operands))
3014     return true;
3015 
3016   unsigned Opcode;
3017   uint64_t ErrorInfo;
3018   return MatchAndEmitInstruction(L, Opcode, Operands, Parser.getStreamer(),
3019                                  ErrorInfo,
3020                                  /*MatchingInlineAsm=*/false);
3021 }
3022 
3023 /// parseDirectiveVariantCC
3024 ///  ::= .variant_cc symbol
3025 bool RISCVAsmParser::parseDirectiveVariantCC() {
3026   StringRef Name;
3027   if (getParser().parseIdentifier(Name))
3028     return TokError("expected symbol name");
3029   if (parseEOL())
3030     return true;
3031   getTargetStreamer().emitDirectiveVariantCC(
3032       *getContext().getOrCreateSymbol(Name));
3033   return false;
3034 }
3035 
3036 void RISCVAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) {
3037   MCInst CInst;
3038   bool Res = RISCVRVC::compress(CInst, Inst, getSTI());
3039   if (Res)
3040     ++RISCVNumInstrsCompressed;
3041   S.emitInstruction((Res ? CInst : Inst), getSTI());
3042 }
3043 
3044 void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t Value,
3045                                  MCStreamer &Out) {
3046   RISCVMatInt::InstSeq Seq = RISCVMatInt::generateInstSeq(Value, getSTI());
3047 
3048   MCRegister SrcReg = RISCV::X0;
3049   for (const RISCVMatInt::Inst &Inst : Seq) {
3050     switch (Inst.getOpndKind()) {
3051     case RISCVMatInt::Imm:
3052       emitToStreamer(Out,
3053                      MCInstBuilder(Inst.getOpcode()).addReg(DestReg).addImm(Inst.getImm()));
3054       break;
3055     case RISCVMatInt::RegX0:
3056       emitToStreamer(
3057           Out, MCInstBuilder(Inst.getOpcode()).addReg(DestReg).addReg(SrcReg).addReg(
3058                    RISCV::X0));
3059       break;
3060     case RISCVMatInt::RegReg:
3061       emitToStreamer(
3062           Out, MCInstBuilder(Inst.getOpcode()).addReg(DestReg).addReg(SrcReg).addReg(
3063                    SrcReg));
3064       break;
3065     case RISCVMatInt::RegImm:
3066       emitToStreamer(
3067           Out, MCInstBuilder(Inst.getOpcode()).addReg(DestReg).addReg(SrcReg).addImm(
3068                    Inst.getImm()));
3069       break;
3070     }
3071 
3072     // Only the first instruction has X0 as its source.
3073     SrcReg = DestReg;
3074   }
3075 }
3076 
3077 void RISCVAsmParser::emitAuipcInstPair(MCOperand DestReg, MCOperand TmpReg,
3078                                        const MCExpr *Symbol,
3079                                        RISCVMCExpr::VariantKind VKHi,
3080                                        unsigned SecondOpcode, SMLoc IDLoc,
3081                                        MCStreamer &Out) {
3082   // A pair of instructions for PC-relative addressing; expands to
3083   //   TmpLabel: AUIPC TmpReg, VKHi(symbol)
3084   //             OP DestReg, TmpReg, %pcrel_lo(TmpLabel)
3085   MCContext &Ctx = getContext();
3086 
3087   MCSymbol *TmpLabel = Ctx.createNamedTempSymbol("pcrel_hi");
3088   Out.emitLabel(TmpLabel);
3089 
3090   const RISCVMCExpr *SymbolHi = RISCVMCExpr::create(Symbol, VKHi, Ctx);
3091   emitToStreamer(
3092       Out, MCInstBuilder(RISCV::AUIPC).addOperand(TmpReg).addExpr(SymbolHi));
3093 
3094   const MCExpr *RefToLinkTmpLabel =
3095       RISCVMCExpr::create(MCSymbolRefExpr::create(TmpLabel, Ctx),
3096                           RISCVMCExpr::VK_RISCV_PCREL_LO, Ctx);
3097 
3098   emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3099                           .addOperand(DestReg)
3100                           .addOperand(TmpReg)
3101                           .addExpr(RefToLinkTmpLabel));
3102 }
3103 
3104 void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
3105                                           MCStreamer &Out) {
3106   // The load local address pseudo-instruction "lla" is used in PC-relative
3107   // addressing of local symbols:
3108   //   lla rdest, symbol
3109   // expands to
3110   //   TmpLabel: AUIPC rdest, %pcrel_hi(symbol)
3111   //             ADDI rdest, rdest, %pcrel_lo(TmpLabel)
3112   MCOperand DestReg = Inst.getOperand(0);
3113   const MCExpr *Symbol = Inst.getOperand(1).getExpr();
3114   emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI,
3115                     RISCV::ADDI, IDLoc, Out);
3116 }
3117 
3118 void RISCVAsmParser::emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc,
3119                                            MCStreamer &Out) {
3120   // The load global address pseudo-instruction "lga" is used in GOT-indirect
3121   // addressing of global symbols:
3122   //   lga rdest, symbol
3123   // expands to
3124   //   TmpLabel: AUIPC rdest, %got_pcrel_hi(symbol)
3125   //             Lx rdest, %pcrel_lo(TmpLabel)(rdest)
3126   MCOperand DestReg = Inst.getOperand(0);
3127   const MCExpr *Symbol = Inst.getOperand(1).getExpr();
3128   unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3129   emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_GOT_HI,
3130                     SecondOpcode, IDLoc, Out);
3131 }
3132 
3133 void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc,
3134                                      MCStreamer &Out) {
3135   // The load address pseudo-instruction "la" is used in PC-relative and
3136   // GOT-indirect addressing of global symbols:
3137   //   la rdest, symbol
3138   // is an alias for either (for non-PIC)
3139   //   lla rdest, symbol
3140   // or (for PIC)
3141   //   lga rdest, symbol
3142   if (ParserOptions.IsPicEnabled)
3143     emitLoadGlobalAddress(Inst, IDLoc, Out);
3144   else
3145     emitLoadLocalAddress(Inst, IDLoc, Out);
3146 }
3147 
3148 void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc,
3149                                           MCStreamer &Out) {
3150   // The load TLS IE address pseudo-instruction "la.tls.ie" is used in
3151   // initial-exec TLS model addressing of global symbols:
3152   //   la.tls.ie rdest, symbol
3153   // expands to
3154   //   TmpLabel: AUIPC rdest, %tls_ie_pcrel_hi(symbol)
3155   //             Lx rdest, %pcrel_lo(TmpLabel)(rdest)
3156   MCOperand DestReg = Inst.getOperand(0);
3157   const MCExpr *Symbol = Inst.getOperand(1).getExpr();
3158   unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3159   emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_TLS_GOT_HI,
3160                     SecondOpcode, IDLoc, Out);
3161 }
3162 
3163 void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc,
3164                                           MCStreamer &Out) {
3165   // The load TLS GD address pseudo-instruction "la.tls.gd" is used in
3166   // global-dynamic TLS model addressing of global symbols:
3167   //   la.tls.gd rdest, symbol
3168   // expands to
3169   //   TmpLabel: AUIPC rdest, %tls_gd_pcrel_hi(symbol)
3170   //             ADDI rdest, rdest, %pcrel_lo(TmpLabel)
3171   MCOperand DestReg = Inst.getOperand(0);
3172   const MCExpr *Symbol = Inst.getOperand(1).getExpr();
3173   emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_TLS_GD_HI,
3174                     RISCV::ADDI, IDLoc, Out);
3175 }
3176 
3177 void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode,
3178                                          SMLoc IDLoc, MCStreamer &Out,
3179                                          bool HasTmpReg) {
3180   // The load/store pseudo-instruction does a pc-relative load with
3181   // a symbol.
3182   //
3183   // The expansion looks like this
3184   //
3185   //   TmpLabel: AUIPC tmp, %pcrel_hi(symbol)
3186   //             [S|L]X    rd, %pcrel_lo(TmpLabel)(tmp)
3187   unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3188   MCOperand DestReg = Inst.getOperand(DestRegOpIdx);
3189   unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3190   MCOperand TmpReg = Inst.getOperand(0);
3191   const MCExpr *Symbol = Inst.getOperand(SymbolOpIdx).getExpr();
3192   emitAuipcInstPair(DestReg, TmpReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI,
3193                     Opcode, IDLoc, Out);
3194 }
3195 
3196 void RISCVAsmParser::emitPseudoExtend(MCInst &Inst, bool SignExtend,
3197                                       int64_t Width, SMLoc IDLoc,
3198                                       MCStreamer &Out) {
3199   // The sign/zero extend pseudo-instruction does two shifts, with the shift
3200   // amounts dependent on the XLEN.
3201   //
3202   // The expansion looks like this
3203   //
3204   //    SLLI rd, rs, XLEN - Width
3205   //    SR[A|R]I rd, rd, XLEN - Width
3206   MCOperand DestReg = Inst.getOperand(0);
3207   MCOperand SourceReg = Inst.getOperand(1);
3208 
3209   unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
3210   int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
3211 
3212   assert(ShAmt > 0 && "Shift amount must be non-zero.");
3213 
3214   emitToStreamer(Out, MCInstBuilder(RISCV::SLLI)
3215                           .addOperand(DestReg)
3216                           .addOperand(SourceReg)
3217                           .addImm(ShAmt));
3218 
3219   emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3220                           .addOperand(DestReg)
3221                           .addOperand(DestReg)
3222                           .addImm(ShAmt));
3223 }
3224 
3225 void RISCVAsmParser::emitVMSGE(MCInst &Inst, unsigned Opcode, SMLoc IDLoc,
3226                                MCStreamer &Out) {
3227   if (Inst.getNumOperands() == 3) {
3228     // unmasked va >= x
3229     //
3230     //  pseudoinstruction: vmsge{u}.vx vd, va, x
3231     //  expansion: vmslt{u}.vx vd, va, x; vmnand.mm vd, vd, vd
3232     emitToStreamer(Out, MCInstBuilder(Opcode)
3233                             .addOperand(Inst.getOperand(0))
3234                             .addOperand(Inst.getOperand(1))
3235                             .addOperand(Inst.getOperand(2))
3236                             .addReg(RISCV::NoRegister));
3237     emitToStreamer(Out, MCInstBuilder(RISCV::VMNAND_MM)
3238                             .addOperand(Inst.getOperand(0))
3239                             .addOperand(Inst.getOperand(0))
3240                             .addOperand(Inst.getOperand(0)));
3241   } else if (Inst.getNumOperands() == 4) {
3242     // masked va >= x, vd != v0
3243     //
3244     //  pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t
3245     //  expansion: vmslt{u}.vx vd, va, x, v0.t; vmxor.mm vd, vd, v0
3246     assert(Inst.getOperand(0).getReg() != RISCV::V0 &&
3247            "The destination register should not be V0.");
3248     emitToStreamer(Out, MCInstBuilder(Opcode)
3249                             .addOperand(Inst.getOperand(0))
3250                             .addOperand(Inst.getOperand(1))
3251                             .addOperand(Inst.getOperand(2))
3252                             .addOperand(Inst.getOperand(3)));
3253     emitToStreamer(Out, MCInstBuilder(RISCV::VMXOR_MM)
3254                             .addOperand(Inst.getOperand(0))
3255                             .addOperand(Inst.getOperand(0))
3256                             .addReg(RISCV::V0));
3257   } else if (Inst.getNumOperands() == 5 &&
3258              Inst.getOperand(0).getReg() == RISCV::V0) {
3259     // masked va >= x, vd == v0
3260     //
3261     //  pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t, vt
3262     //  expansion: vmslt{u}.vx vt, va, x;  vmandn.mm vd, vd, vt
3263     assert(Inst.getOperand(0).getReg() == RISCV::V0 &&
3264            "The destination register should be V0.");
3265     assert(Inst.getOperand(1).getReg() != RISCV::V0 &&
3266            "The temporary vector register should not be V0.");
3267     emitToStreamer(Out, MCInstBuilder(Opcode)
3268                             .addOperand(Inst.getOperand(1))
3269                             .addOperand(Inst.getOperand(2))
3270                             .addOperand(Inst.getOperand(3))
3271                             .addReg(RISCV::NoRegister));
3272     emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3273                             .addOperand(Inst.getOperand(0))
3274                             .addOperand(Inst.getOperand(0))
3275                             .addOperand(Inst.getOperand(1)));
3276   } else if (Inst.getNumOperands() == 5) {
3277     // masked va >= x, any vd
3278     //
3279     // pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t, vt
3280     // expansion: vmslt{u}.vx vt, va, x; vmandn.mm vt, v0, vt;
3281     //            vmandn.mm vd, vd, v0;  vmor.mm vd, vt, vd
3282     assert(Inst.getOperand(1).getReg() != RISCV::V0 &&
3283            "The temporary vector register should not be V0.");
3284     emitToStreamer(Out, MCInstBuilder(Opcode)
3285                             .addOperand(Inst.getOperand(1))
3286                             .addOperand(Inst.getOperand(2))
3287                             .addOperand(Inst.getOperand(3))
3288                             .addReg(RISCV::NoRegister));
3289     emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3290                             .addOperand(Inst.getOperand(1))
3291                             .addReg(RISCV::V0)
3292                             .addOperand(Inst.getOperand(1)));
3293     emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3294                             .addOperand(Inst.getOperand(0))
3295                             .addOperand(Inst.getOperand(0))
3296                             .addReg(RISCV::V0));
3297     emitToStreamer(Out, MCInstBuilder(RISCV::VMOR_MM)
3298                             .addOperand(Inst.getOperand(0))
3299                             .addOperand(Inst.getOperand(1))
3300                             .addOperand(Inst.getOperand(0)));
3301   }
3302 }
3303 
3304 bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
3305                                          OperandVector &Operands) {
3306   assert(Inst.getOpcode() == RISCV::PseudoAddTPRel && "Invalid instruction");
3307   assert(Inst.getOperand(2).isReg() && "Unexpected second operand kind");
3308   if (Inst.getOperand(2).getReg() != RISCV::X4) {
3309     SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();
3310     return Error(ErrorLoc, "the second input operand must be tp/x4 when using "
3311                            "%tprel_add modifier");
3312   }
3313 
3314   return false;
3315 }
3316 
3317 std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp() const {
3318   return RISCVOperand::createReg(RISCV::NoRegister, llvm::SMLoc(),
3319                                  llvm::SMLoc());
3320 }
3321 
3322 std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp() const {
3323   return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
3324                                     llvm::SMLoc());
3325 }
3326 
3327 std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp() const {
3328   return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
3329                                     llvm::SMLoc());
3330 }
3331 
3332 bool RISCVAsmParser::validateInstruction(MCInst &Inst,
3333                                          OperandVector &Operands) {
3334   unsigned Opcode = Inst.getOpcode();
3335 
3336   if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
3337       Opcode == RISCV::PseudoVMSGE_VX_M_T) {
3338     unsigned DestReg = Inst.getOperand(0).getReg();
3339     unsigned TempReg = Inst.getOperand(1).getReg();
3340     if (DestReg == TempReg) {
3341       SMLoc Loc = Operands.back()->getStartLoc();
3342       return Error(Loc, "The temporary vector register cannot be the same as "
3343                         "the destination register.");
3344     }
3345   }
3346 
3347   if (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_LWUD ||
3348       Opcode == RISCV::TH_LWD) {
3349     unsigned Rd1 = Inst.getOperand(0).getReg();
3350     unsigned Rd2 = Inst.getOperand(1).getReg();
3351     unsigned Rs1 = Inst.getOperand(2).getReg();
3352     // The encoding with rd1 == rd2 == rs1 is reserved for XTHead load pair.
3353     if (Rs1 == Rd1 && Rs1 == Rd2) {
3354       SMLoc Loc = Operands[1]->getStartLoc();
3355       return Error(Loc, "The source register and destination registers "
3356                         "cannot be equal.");
3357     }
3358   }
3359 
3360   if (Opcode == RISCV::CM_MVSA01) {
3361     unsigned Rd1 = Inst.getOperand(0).getReg();
3362     unsigned Rd2 = Inst.getOperand(1).getReg();
3363     if (Rd1 == Rd2) {
3364       SMLoc Loc = Operands[1]->getStartLoc();
3365       return Error(Loc, "'rs1' and 'rs2' must be different.");
3366     }
3367   }
3368 
3369   bool IsTHeadMemPair32 = (Opcode == RISCV::TH_LWD ||
3370                            Opcode == RISCV::TH_LWUD || Opcode == RISCV::TH_SWD);
3371   bool IsTHeadMemPair64 = (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_SDD);
3372   // The last operand of XTHeadMemPair instructions must be constant 3 or 4
3373   // depending on the data width.
3374   if (IsTHeadMemPair32 && Inst.getOperand(4).getImm() != 3) {
3375     SMLoc Loc = Operands.back()->getStartLoc();
3376     return Error(Loc, "Operand must be constant 3.");
3377   } else if (IsTHeadMemPair64 && Inst.getOperand(4).getImm() != 4) {
3378     SMLoc Loc = Operands.back()->getStartLoc();
3379     return Error(Loc, "Operand must be constant 4.");
3380   }
3381 
3382   bool IsAMOCAS_D = Opcode == RISCV::AMOCAS_D || Opcode == RISCV::AMOCAS_D_AQ ||
3383                     Opcode == RISCV::AMOCAS_D_RL ||
3384                     Opcode == RISCV::AMOCAS_D_AQ_RL;
3385   bool IsAMOCAS_Q = Opcode == RISCV::AMOCAS_Q || Opcode == RISCV::AMOCAS_Q_AQ ||
3386                     Opcode == RISCV::AMOCAS_Q_RL ||
3387                     Opcode == RISCV::AMOCAS_Q_AQ_RL;
3388   if ((!isRV64() && IsAMOCAS_D) || IsAMOCAS_Q) {
3389     unsigned Rd = Inst.getOperand(0).getReg();
3390     unsigned Rs2 = Inst.getOperand(2).getReg();
3391     assert(Rd >= RISCV::X0 && Rd <= RISCV::X31);
3392     if ((Rd - RISCV::X0) % 2 != 0) {
3393       SMLoc Loc = Operands[1]->getStartLoc();
3394       return Error(Loc, "The destination register must be even.");
3395     }
3396     assert(Rs2 >= RISCV::X0 && Rs2 <= RISCV::X31);
3397     if ((Rs2 - RISCV::X0) % 2 != 0) {
3398       SMLoc Loc = Operands[2]->getStartLoc();
3399       return Error(Loc, "The source register must be even.");
3400     }
3401   }
3402 
3403   const MCInstrDesc &MCID = MII.get(Opcode);
3404   if (!(MCID.TSFlags & RISCVII::ConstraintMask))
3405     return false;
3406 
3407   if (Opcode == RISCV::VC_V_XVW || Opcode == RISCV::VC_V_IVW ||
3408       Opcode == RISCV::VC_V_FVW || Opcode == RISCV::VC_V_VVW) {
3409     // Operands Opcode, Dst, uimm, Dst, Rs2, Rs1 for VC_V_XVW.
3410     unsigned VCIXDst = Inst.getOperand(0).getReg();
3411     SMLoc VCIXDstLoc = Operands[2]->getStartLoc();
3412     if (MCID.TSFlags & RISCVII::VS1Constraint) {
3413       unsigned VCIXRs1 = Inst.getOperand(Inst.getNumOperands() - 1).getReg();
3414       if (VCIXDst == VCIXRs1)
3415         return Error(VCIXDstLoc, "The destination vector register group cannot"
3416                                  " overlap the source vector register group.");
3417     }
3418     if (MCID.TSFlags & RISCVII::VS2Constraint) {
3419       unsigned VCIXRs2 = Inst.getOperand(Inst.getNumOperands() - 2).getReg();
3420       if (VCIXDst == VCIXRs2)
3421         return Error(VCIXDstLoc, "The destination vector register group cannot"
3422                                  " overlap the source vector register group.");
3423     }
3424     return false;
3425   }
3426 
3427   unsigned DestReg = Inst.getOperand(0).getReg();
3428   unsigned Offset = 0;
3429   int TiedOp = MCID.getOperandConstraint(1, MCOI::TIED_TO);
3430   if (TiedOp == 0)
3431     Offset = 1;
3432 
3433   // Operands[1] will be the first operand, DestReg.
3434   SMLoc Loc = Operands[1]->getStartLoc();
3435   if (MCID.TSFlags & RISCVII::VS2Constraint) {
3436     unsigned CheckReg = Inst.getOperand(Offset + 1).getReg();
3437     if (DestReg == CheckReg)
3438       return Error(Loc, "The destination vector register group cannot overlap"
3439                         " the source vector register group.");
3440   }
3441   if ((MCID.TSFlags & RISCVII::VS1Constraint) && Inst.getOperand(Offset + 2).isReg()) {
3442     unsigned CheckReg = Inst.getOperand(Offset + 2).getReg();
3443     if (DestReg == CheckReg)
3444       return Error(Loc, "The destination vector register group cannot overlap"
3445                         " the source vector register group.");
3446   }
3447   if ((MCID.TSFlags & RISCVII::VMConstraint) && (DestReg == RISCV::V0)) {
3448     // vadc, vsbc are special cases. These instructions have no mask register.
3449     // The destination register could not be V0.
3450     if (Opcode == RISCV::VADC_VVM || Opcode == RISCV::VADC_VXM ||
3451         Opcode == RISCV::VADC_VIM || Opcode == RISCV::VSBC_VVM ||
3452         Opcode == RISCV::VSBC_VXM || Opcode == RISCV::VFMERGE_VFM ||
3453         Opcode == RISCV::VMERGE_VIM || Opcode == RISCV::VMERGE_VVM ||
3454         Opcode == RISCV::VMERGE_VXM)
3455       return Error(Loc, "The destination vector register group cannot be V0.");
3456 
3457     // Regardless masked or unmasked version, the number of operands is the
3458     // same. For example, "viota.m v0, v2" is "viota.m v0, v2, NoRegister"
3459     // actually. We need to check the last operand to ensure whether it is
3460     // masked or not.
3461     unsigned CheckReg = Inst.getOperand(Inst.getNumOperands() - 1).getReg();
3462     assert((CheckReg == RISCV::V0 || CheckReg == RISCV::NoRegister) &&
3463            "Unexpected register for mask operand");
3464 
3465     if (DestReg == CheckReg)
3466       return Error(Loc, "The destination vector register group cannot overlap"
3467                         " the mask register.");
3468   }
3469   return false;
3470 }
3471 
3472 bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
3473                                         OperandVector &Operands,
3474                                         MCStreamer &Out) {
3475   Inst.setLoc(IDLoc);
3476 
3477   switch (Inst.getOpcode()) {
3478   default:
3479     break;
3480   case RISCV::PseudoLLAImm:
3481   case RISCV::PseudoLAImm:
3482   case RISCV::PseudoLI: {
3483     MCRegister Reg = Inst.getOperand(0).getReg();
3484     const MCOperand &Op1 = Inst.getOperand(1);
3485     if (Op1.isExpr()) {
3486       // We must have li reg, %lo(sym) or li reg, %pcrel_lo(sym) or similar.
3487       // Just convert to an addi. This allows compatibility with gas.
3488       emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
3489                               .addReg(Reg)
3490                               .addReg(RISCV::X0)
3491                               .addExpr(Op1.getExpr()));
3492       return false;
3493     }
3494     int64_t Imm = Inst.getOperand(1).getImm();
3495     // On RV32 the immediate here can either be a signed or an unsigned
3496     // 32-bit number. Sign extension has to be performed to ensure that Imm
3497     // represents the expected signed 64-bit number.
3498     if (!isRV64())
3499       Imm = SignExtend64<32>(Imm);
3500     emitLoadImm(Reg, Imm, Out);
3501     return false;
3502   }
3503   case RISCV::PseudoLLA:
3504     emitLoadLocalAddress(Inst, IDLoc, Out);
3505     return false;
3506   case RISCV::PseudoLGA:
3507     emitLoadGlobalAddress(Inst, IDLoc, Out);
3508     return false;
3509   case RISCV::PseudoLA:
3510     emitLoadAddress(Inst, IDLoc, Out);
3511     return false;
3512   case RISCV::PseudoLA_TLS_IE:
3513     emitLoadTLSIEAddress(Inst, IDLoc, Out);
3514     return false;
3515   case RISCV::PseudoLA_TLS_GD:
3516     emitLoadTLSGDAddress(Inst, IDLoc, Out);
3517     return false;
3518   case RISCV::PseudoLB:
3519     emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out, /*HasTmpReg=*/false);
3520     return false;
3521   case RISCV::PseudoLBU:
3522     emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out, /*HasTmpReg=*/false);
3523     return false;
3524   case RISCV::PseudoLH:
3525     emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out, /*HasTmpReg=*/false);
3526     return false;
3527   case RISCV::PseudoLHU:
3528     emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out, /*HasTmpReg=*/false);
3529     return false;
3530   case RISCV::PseudoLW:
3531     emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out, /*HasTmpReg=*/false);
3532     return false;
3533   case RISCV::PseudoLWU:
3534     emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out, /*HasTmpReg=*/false);
3535     return false;
3536   case RISCV::PseudoLD:
3537     emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out, /*HasTmpReg=*/false);
3538     return false;
3539   case RISCV::PseudoFLH:
3540     emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out, /*HasTmpReg=*/true);
3541     return false;
3542   case RISCV::PseudoFLW:
3543     emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out, /*HasTmpReg=*/true);
3544     return false;
3545   case RISCV::PseudoFLD:
3546     emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out, /*HasTmpReg=*/true);
3547     return false;
3548   case RISCV::PseudoSB:
3549     emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out, /*HasTmpReg=*/true);
3550     return false;
3551   case RISCV::PseudoSH:
3552     emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out, /*HasTmpReg=*/true);
3553     return false;
3554   case RISCV::PseudoSW:
3555     emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out, /*HasTmpReg=*/true);
3556     return false;
3557   case RISCV::PseudoSD:
3558     emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out, /*HasTmpReg=*/true);
3559     return false;
3560   case RISCV::PseudoFSH:
3561     emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out, /*HasTmpReg=*/true);
3562     return false;
3563   case RISCV::PseudoFSW:
3564     emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out, /*HasTmpReg=*/true);
3565     return false;
3566   case RISCV::PseudoFSD:
3567     emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out, /*HasTmpReg=*/true);
3568     return false;
3569   case RISCV::PseudoAddTPRel:
3570     if (checkPseudoAddTPRel(Inst, Operands))
3571       return true;
3572     break;
3573   case RISCV::PseudoSEXT_B:
3574     emitPseudoExtend(Inst, /*SignExtend=*/true, /*Width=*/8, IDLoc, Out);
3575     return false;
3576   case RISCV::PseudoSEXT_H:
3577     emitPseudoExtend(Inst, /*SignExtend=*/true, /*Width=*/16, IDLoc, Out);
3578     return false;
3579   case RISCV::PseudoZEXT_H:
3580     emitPseudoExtend(Inst, /*SignExtend=*/false, /*Width=*/16, IDLoc, Out);
3581     return false;
3582   case RISCV::PseudoZEXT_W:
3583     emitPseudoExtend(Inst, /*SignExtend=*/false, /*Width=*/32, IDLoc, Out);
3584     return false;
3585   case RISCV::PseudoVMSGEU_VX:
3586   case RISCV::PseudoVMSGEU_VX_M:
3587   case RISCV::PseudoVMSGEU_VX_M_T:
3588     emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
3589     return false;
3590   case RISCV::PseudoVMSGE_VX:
3591   case RISCV::PseudoVMSGE_VX_M:
3592   case RISCV::PseudoVMSGE_VX_M_T:
3593     emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
3594     return false;
3595   case RISCV::PseudoVMSGE_VI:
3596   case RISCV::PseudoVMSLT_VI: {
3597     // These instructions are signed and so is immediate so we can subtract one
3598     // and change the opcode.
3599     int64_t Imm = Inst.getOperand(2).getImm();
3600     unsigned Opc = Inst.getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
3601                                                              : RISCV::VMSLE_VI;
3602     emitToStreamer(Out, MCInstBuilder(Opc)
3603                             .addOperand(Inst.getOperand(0))
3604                             .addOperand(Inst.getOperand(1))
3605                             .addImm(Imm - 1)
3606                             .addOperand(Inst.getOperand(3)));
3607     return false;
3608   }
3609   case RISCV::PseudoVMSGEU_VI:
3610   case RISCV::PseudoVMSLTU_VI: {
3611     int64_t Imm = Inst.getOperand(2).getImm();
3612     // Unsigned comparisons are tricky because the immediate is signed. If the
3613     // immediate is 0 we can't just subtract one. vmsltu.vi v0, v1, 0 is always
3614     // false, but vmsle.vi v0, v1, -1 is always true. Instead we use
3615     // vmsne v0, v1, v1 which is always false.
3616     if (Imm == 0) {
3617       unsigned Opc = Inst.getOpcode() == RISCV::PseudoVMSGEU_VI
3618                          ? RISCV::VMSEQ_VV
3619                          : RISCV::VMSNE_VV;
3620       emitToStreamer(Out, MCInstBuilder(Opc)
3621                               .addOperand(Inst.getOperand(0))
3622                               .addOperand(Inst.getOperand(1))
3623                               .addOperand(Inst.getOperand(1))
3624                               .addOperand(Inst.getOperand(3)));
3625     } else {
3626       // Other immediate values can subtract one like signed.
3627       unsigned Opc = Inst.getOpcode() == RISCV::PseudoVMSGEU_VI
3628                          ? RISCV::VMSGTU_VI
3629                          : RISCV::VMSLEU_VI;
3630       emitToStreamer(Out, MCInstBuilder(Opc)
3631                               .addOperand(Inst.getOperand(0))
3632                               .addOperand(Inst.getOperand(1))
3633                               .addImm(Imm - 1)
3634                               .addOperand(Inst.getOperand(3)));
3635     }
3636 
3637     return false;
3638   }
3639   }
3640 
3641   emitToStreamer(Out, Inst);
3642   return false;
3643 }
3644 
3645 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVAsmParser() {
3646   RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target());
3647   RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target());
3648 }
3649