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