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