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