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