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