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