1 //===-- RISCVAsmParser.cpp - Parse RISCV assembly to MCInst instructions --===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "MCTargetDesc/RISCVAsmBackend.h"
11 #include "MCTargetDesc/RISCVMCExpr.h"
12 #include "MCTargetDesc/RISCVMCTargetDesc.h"
13 #include "MCTargetDesc/RISCVTargetStreamer.h"
14 #include "Utils/RISCVBaseInfo.h"
15 #include "Utils/RISCVMatInt.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/MC/MCAssembler.h"
20 #include "llvm/MC/MCContext.h"
21 #include "llvm/MC/MCExpr.h"
22 #include "llvm/MC/MCInst.h"
23 #include "llvm/MC/MCInstBuilder.h"
24 #include "llvm/MC/MCParser/MCAsmLexer.h"
25 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
26 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
27 #include "llvm/MC/MCRegisterInfo.h"
28 #include "llvm/MC/MCStreamer.h"
29 #include "llvm/MC/MCSubtargetInfo.h"
30 #include "llvm/Support/Casting.h"
31 #include "llvm/Support/MathExtras.h"
32 #include "llvm/Support/TargetRegistry.h"
33 
34 #include <limits>
35 
36 using namespace llvm;
37 
38 // Include the auto-generated portion of the compress emitter.
39 #define GEN_COMPRESS_INSTR
40 #include "RISCVGenCompressInstEmitter.inc"
41 
42 namespace {
43 struct RISCVOperand;
44 
45 class RISCVAsmParser : public MCTargetAsmParser {
46   SmallVector<FeatureBitset, 4> FeatureBitStack;
47 
48   SMLoc getLoc() const { return getParser().getTok().getLoc(); }
49   bool isRV64() const { return getSTI().hasFeature(RISCV::Feature64Bit); }
50 
51   RISCVTargetStreamer &getTargetStreamer() {
52     MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
53     return static_cast<RISCVTargetStreamer &>(TS);
54   }
55 
56   unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
57                                       unsigned Kind) override;
58 
59   bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo,
60                                   int64_t Lower, int64_t Upper, Twine Msg);
61 
62   bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
63                                OperandVector &Operands, MCStreamer &Out,
64                                uint64_t &ErrorInfo,
65                                bool MatchingInlineAsm) override;
66 
67   bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
68 
69   bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
70                         SMLoc NameLoc, OperandVector &Operands) override;
71 
72   bool ParseDirective(AsmToken DirectiveID) override;
73 
74   // Helper to actually emit an instruction to the MCStreamer. Also, when
75   // possible, compression of the instruction is performed.
76   void emitToStreamer(MCStreamer &S, const MCInst &Inst);
77 
78   // Helper to emit a combination of LUI, ADDI(W), and SLLI instructions that
79   // synthesize the desired immedate value into the destination register.
80   void emitLoadImm(unsigned DestReg, int64_t Value, MCStreamer &Out);
81 
82   // Helper to emit pseudo instruction "lla" used in PC-rel addressing.
83   void emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
84 
85   /// Helper for processing MC instructions that have been successfully matched
86   /// by MatchAndEmitInstruction. Modifications to the emitted instructions,
87   /// like the expansion of pseudo instructions (e.g., "li"), can be performed
88   /// in this method.
89   bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
90 
91 // Auto-generated instruction matching functions
92 #define GET_ASSEMBLER_HEADER
93 #include "RISCVGenAsmMatcher.inc"
94 
95   OperandMatchResultTy parseCSRSystemRegister(OperandVector &Operands);
96   OperandMatchResultTy parseImmediate(OperandVector &Operands);
97   OperandMatchResultTy parseRegister(OperandVector &Operands,
98                                      bool AllowParens = false);
99   OperandMatchResultTy parseMemOpBaseReg(OperandVector &Operands);
100   OperandMatchResultTy parseOperandWithModifier(OperandVector &Operands);
101   OperandMatchResultTy parseBareSymbol(OperandVector &Operands);
102   OperandMatchResultTy parseJALOffset(OperandVector &Operands);
103 
104   bool parseOperand(OperandVector &Operands, StringRef Mnemonic);
105 
106   bool parseDirectiveOption();
107 
108   void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
109     if (!(getSTI().getFeatureBits()[Feature])) {
110       MCSubtargetInfo &STI = copySTI();
111       setAvailableFeatures(
112           ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
113     }
114   }
115 
116   void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
117     if (getSTI().getFeatureBits()[Feature]) {
118       MCSubtargetInfo &STI = copySTI();
119       setAvailableFeatures(
120           ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
121     }
122   }
123 
124   void pushFeatureBits() {
125     FeatureBitStack.push_back(getSTI().getFeatureBits());
126   }
127 
128   bool popFeatureBits() {
129     if (FeatureBitStack.empty())
130       return true;
131 
132     FeatureBitset FeatureBits = FeatureBitStack.pop_back_val();
133     copySTI().setFeatureBits(FeatureBits);
134     setAvailableFeatures(ComputeAvailableFeatures(FeatureBits));
135 
136     return false;
137   }
138 public:
139   enum RISCVMatchResultTy {
140     Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
141 #define GET_OPERAND_DIAGNOSTIC_TYPES
142 #include "RISCVGenAsmMatcher.inc"
143 #undef GET_OPERAND_DIAGNOSTIC_TYPES
144   };
145 
146   static bool classifySymbolRef(const MCExpr *Expr,
147                                 RISCVMCExpr::VariantKind &Kind,
148                                 int64_t &Addend);
149 
150   RISCVAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
151                  const MCInstrInfo &MII, const MCTargetOptions &Options)
152       : MCTargetAsmParser(Options, STI, MII) {
153     Parser.addAliasForDirective(".half", ".2byte");
154     Parser.addAliasForDirective(".hword", ".2byte");
155     Parser.addAliasForDirective(".word", ".4byte");
156     Parser.addAliasForDirective(".dword", ".8byte");
157     setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
158   }
159 };
160 
161 /// RISCVOperand - Instances of this class represent a parsed machine
162 /// instruction
163 struct RISCVOperand : public MCParsedAsmOperand {
164 
165   enum KindTy {
166     Token,
167     Register,
168     Immediate,
169     SystemRegister
170   } Kind;
171 
172   bool IsRV64;
173 
174   struct RegOp {
175     unsigned RegNum;
176   };
177 
178   struct ImmOp {
179     const MCExpr *Val;
180   };
181 
182   struct SysRegOp {
183     const char *Data;
184     unsigned Length;
185     unsigned Encoding;
186     // FIXME: Add the Encoding parsed fields as needed for checks,
187     // e.g.: read/write or user/supervisor/machine privileges.
188   };
189 
190   SMLoc StartLoc, EndLoc;
191   union {
192     StringRef Tok;
193     RegOp Reg;
194     ImmOp Imm;
195     struct SysRegOp SysReg;
196   };
197 
198   RISCVOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
199 
200 public:
201   RISCVOperand(const RISCVOperand &o) : MCParsedAsmOperand() {
202     Kind = o.Kind;
203     IsRV64 = o.IsRV64;
204     StartLoc = o.StartLoc;
205     EndLoc = o.EndLoc;
206     switch (Kind) {
207     case Register:
208       Reg = o.Reg;
209       break;
210     case Immediate:
211       Imm = o.Imm;
212       break;
213     case Token:
214       Tok = o.Tok;
215       break;
216     case SystemRegister:
217       SysReg = o.SysReg;
218       break;
219     }
220   }
221 
222   bool isToken() const override { return Kind == Token; }
223   bool isReg() const override { return Kind == Register; }
224   bool isImm() const override { return Kind == Immediate; }
225   bool isMem() const override { return false; }
226   bool isSystemRegister() const { return Kind == SystemRegister; }
227 
228   static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm,
229                                   RISCVMCExpr::VariantKind &VK) {
230     if (auto *RE = dyn_cast<RISCVMCExpr>(Expr)) {
231       VK = RE->getKind();
232       return RE->evaluateAsConstant(Imm);
233     }
234 
235     if (auto CE = dyn_cast<MCConstantExpr>(Expr)) {
236       VK = RISCVMCExpr::VK_RISCV_None;
237       Imm = CE->getValue();
238       return true;
239     }
240 
241     return false;
242   }
243 
244   // True if operand is a symbol with no modifiers, or a constant with no
245   // modifiers and isShiftedInt<N-1, 1>(Op).
246   template <int N> bool isBareSimmNLsb0() const {
247     int64_t Imm;
248     RISCVMCExpr::VariantKind VK;
249     if (!isImm())
250       return false;
251     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
252     bool IsValid;
253     if (!IsConstantImm)
254       IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
255     else
256       IsValid = isShiftedInt<N - 1, 1>(Imm);
257     return IsValid && VK == RISCVMCExpr::VK_RISCV_None;
258   }
259 
260   // Predicate methods for AsmOperands defined in RISCVInstrInfo.td
261 
262   bool isBareSymbol() const {
263     int64_t Imm;
264     RISCVMCExpr::VariantKind VK;
265     // Must be of 'immediate' type but not a constant.
266     if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
267       return false;
268     return RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm) &&
269            VK == RISCVMCExpr::VK_RISCV_None;
270   }
271 
272   bool isCSRSystemRegister() const { return isSystemRegister(); }
273 
274   /// Return true if the operand is a valid for the fence instruction e.g.
275   /// ('iorw').
276   bool isFenceArg() const {
277     if (!isImm())
278       return false;
279     const MCExpr *Val = getImm();
280     auto *SVal = dyn_cast<MCSymbolRefExpr>(Val);
281     if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None)
282       return false;
283 
284     StringRef Str = SVal->getSymbol().getName();
285     // Letters must be unique, taken from 'iorw', and in ascending order. This
286     // holds as long as each individual character is one of 'iorw' and is
287     // greater than the previous character.
288     char Prev = '\0';
289     for (char c : Str) {
290       if (c != 'i' && c != 'o' && c != 'r' && c != 'w')
291         return false;
292       if (c <= Prev)
293         return false;
294       Prev = c;
295     }
296     return true;
297   }
298 
299   /// Return true if the operand is a valid floating point rounding mode.
300   bool isFRMArg() const {
301     if (!isImm())
302       return false;
303     const MCExpr *Val = getImm();
304     auto *SVal = dyn_cast<MCSymbolRefExpr>(Val);
305     if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None)
306       return false;
307 
308     StringRef Str = SVal->getSymbol().getName();
309 
310     return RISCVFPRndMode::stringToRoundingMode(Str) != RISCVFPRndMode::Invalid;
311   }
312 
313   bool isImmXLenLI() const {
314     int64_t Imm;
315     RISCVMCExpr::VariantKind VK;
316     if (!isImm())
317       return false;
318     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
319     if (VK == RISCVMCExpr::VK_RISCV_LO || VK == RISCVMCExpr::VK_RISCV_PCREL_LO)
320       return true;
321     // Given only Imm, ensuring that the actually specified constant is either
322     // a signed or unsigned 64-bit number is unfortunately impossible.
323     bool IsInRange = isRV64() ? true : isInt<32>(Imm) || isUInt<32>(Imm);
324     return IsConstantImm && IsInRange && VK == RISCVMCExpr::VK_RISCV_None;
325   }
326 
327   bool isUImmLog2XLen() const {
328     int64_t Imm;
329     RISCVMCExpr::VariantKind VK;
330     if (!isImm())
331       return false;
332     if (!evaluateConstantImm(getImm(), Imm, VK) ||
333         VK != RISCVMCExpr::VK_RISCV_None)
334       return false;
335     return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm);
336   }
337 
338   bool isUImmLog2XLenNonZero() const {
339     int64_t Imm;
340     RISCVMCExpr::VariantKind VK;
341     if (!isImm())
342       return false;
343     if (!evaluateConstantImm(getImm(), Imm, VK) ||
344         VK != RISCVMCExpr::VK_RISCV_None)
345       return false;
346     if (Imm == 0)
347       return false;
348     return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm);
349   }
350 
351   bool isUImm5() const {
352     int64_t Imm;
353     RISCVMCExpr::VariantKind VK;
354     if (!isImm())
355       return false;
356     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
357     return IsConstantImm && isUInt<5>(Imm) && VK == RISCVMCExpr::VK_RISCV_None;
358   }
359 
360   bool isUImm5NonZero() const {
361     int64_t Imm;
362     RISCVMCExpr::VariantKind VK;
363     if (!isImm())
364       return false;
365     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
366     return IsConstantImm && isUInt<5>(Imm) && (Imm != 0) &&
367            VK == RISCVMCExpr::VK_RISCV_None;
368   }
369 
370   bool isSImm6() const {
371     if (!isImm())
372       return false;
373     RISCVMCExpr::VariantKind VK;
374     int64_t Imm;
375     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
376     return IsConstantImm && isInt<6>(Imm) &&
377            VK == RISCVMCExpr::VK_RISCV_None;
378   }
379 
380   bool isSImm6NonZero() const {
381     if (!isImm())
382       return false;
383     RISCVMCExpr::VariantKind VK;
384     int64_t Imm;
385     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
386     return IsConstantImm && isInt<6>(Imm) && (Imm != 0) &&
387            VK == RISCVMCExpr::VK_RISCV_None;
388   }
389 
390   bool isCLUIImm() const {
391     if (!isImm())
392       return false;
393     int64_t Imm;
394     RISCVMCExpr::VariantKind VK;
395     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
396     return IsConstantImm && (Imm != 0) &&
397            (isUInt<5>(Imm) || (Imm >= 0xfffe0 && Imm <= 0xfffff)) &&
398            VK == RISCVMCExpr::VK_RISCV_None;
399   }
400 
401   bool isUImm7Lsb00() const {
402     if (!isImm())
403       return false;
404     int64_t Imm;
405     RISCVMCExpr::VariantKind VK;
406     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
407     return IsConstantImm && isShiftedUInt<5, 2>(Imm) &&
408            VK == RISCVMCExpr::VK_RISCV_None;
409   }
410 
411   bool isUImm8Lsb00() const {
412     if (!isImm())
413       return false;
414     int64_t Imm;
415     RISCVMCExpr::VariantKind VK;
416     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
417     return IsConstantImm && isShiftedUInt<6, 2>(Imm) &&
418            VK == RISCVMCExpr::VK_RISCV_None;
419   }
420 
421   bool isUImm8Lsb000() const {
422     if (!isImm())
423       return false;
424     int64_t Imm;
425     RISCVMCExpr::VariantKind VK;
426     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
427     return IsConstantImm && isShiftedUInt<5, 3>(Imm) &&
428            VK == RISCVMCExpr::VK_RISCV_None;
429   }
430 
431   bool isSImm9Lsb0() const { return isBareSimmNLsb0<9>(); }
432 
433   bool isUImm9Lsb000() const {
434     if (!isImm())
435       return false;
436     int64_t Imm;
437     RISCVMCExpr::VariantKind VK;
438     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
439     return IsConstantImm && isShiftedUInt<6, 3>(Imm) &&
440            VK == RISCVMCExpr::VK_RISCV_None;
441   }
442 
443   bool isUImm10Lsb00NonZero() const {
444     if (!isImm())
445       return false;
446     int64_t Imm;
447     RISCVMCExpr::VariantKind VK;
448     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
449     return IsConstantImm && isShiftedUInt<8, 2>(Imm) && (Imm != 0) &&
450            VK == RISCVMCExpr::VK_RISCV_None;
451   }
452 
453   bool isSImm12() const {
454     RISCVMCExpr::VariantKind VK;
455     int64_t Imm;
456     bool IsValid;
457     if (!isImm())
458       return false;
459     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
460     if (!IsConstantImm)
461       IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
462     else
463       IsValid = isInt<12>(Imm);
464     return IsValid && ((IsConstantImm && VK == RISCVMCExpr::VK_RISCV_None) ||
465                        VK == RISCVMCExpr::VK_RISCV_LO ||
466                        VK == RISCVMCExpr::VK_RISCV_PCREL_LO);
467   }
468 
469   bool isSImm12Lsb0() const { return isBareSimmNLsb0<12>(); }
470 
471   bool isSImm13Lsb0() const { return isBareSimmNLsb0<13>(); }
472 
473   bool isSImm10Lsb0000NonZero() const {
474     if (!isImm())
475       return false;
476     int64_t Imm;
477     RISCVMCExpr::VariantKind VK;
478     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
479     return IsConstantImm && (Imm != 0) && isShiftedInt<6, 4>(Imm) &&
480            VK == RISCVMCExpr::VK_RISCV_None;
481   }
482 
483   bool isUImm20LUI() const {
484     RISCVMCExpr::VariantKind VK;
485     int64_t Imm;
486     bool IsValid;
487     if (!isImm())
488       return false;
489     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
490     if (!IsConstantImm) {
491       IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
492       return IsValid && VK == RISCVMCExpr::VK_RISCV_HI;
493     } else {
494       return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None ||
495                                  VK == RISCVMCExpr::VK_RISCV_HI);
496     }
497   }
498 
499   bool isUImm20AUIPC() const {
500     RISCVMCExpr::VariantKind VK;
501     int64_t Imm;
502     bool IsValid;
503     if (!isImm())
504       return false;
505     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
506     if (!IsConstantImm) {
507       IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
508       return IsValid && VK == RISCVMCExpr::VK_RISCV_PCREL_HI;
509     } else {
510       return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None ||
511                                  VK == RISCVMCExpr::VK_RISCV_PCREL_HI);
512     }
513   }
514 
515   bool isSImm21Lsb0JAL() const { return isBareSimmNLsb0<21>(); }
516 
517   /// getStartLoc - Gets location of the first token of this operand
518   SMLoc getStartLoc() const override { return StartLoc; }
519   /// getEndLoc - Gets location of the last token of this operand
520   SMLoc getEndLoc() const override { return EndLoc; }
521   /// True if this operand is for an RV64 instruction
522   bool isRV64() const { return IsRV64; }
523 
524   unsigned getReg() const override {
525     assert(Kind == Register && "Invalid type access!");
526     return Reg.RegNum;
527   }
528 
529   StringRef getSysReg() const {
530     assert(Kind == SystemRegister && "Invalid access!");
531     return StringRef(SysReg.Data, SysReg.Length);
532   }
533 
534   const MCExpr *getImm() const {
535     assert(Kind == Immediate && "Invalid type access!");
536     return Imm.Val;
537   }
538 
539   StringRef getToken() const {
540     assert(Kind == Token && "Invalid type access!");
541     return Tok;
542   }
543 
544   void print(raw_ostream &OS) const override {
545     switch (Kind) {
546     case Immediate:
547       OS << *getImm();
548       break;
549     case Register:
550       OS << "<register x";
551       OS << getReg() << ">";
552       break;
553     case Token:
554       OS << "'" << getToken() << "'";
555       break;
556     case SystemRegister:
557       OS << "<sysreg: " << getSysReg() << '>';
558       break;
559     }
560   }
561 
562   static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S,
563                                                    bool IsRV64) {
564     auto Op = make_unique<RISCVOperand>(Token);
565     Op->Tok = Str;
566     Op->StartLoc = S;
567     Op->EndLoc = S;
568     Op->IsRV64 = IsRV64;
569     return Op;
570   }
571 
572   static std::unique_ptr<RISCVOperand> createReg(unsigned RegNo, SMLoc S,
573                                                  SMLoc E, bool IsRV64) {
574     auto Op = make_unique<RISCVOperand>(Register);
575     Op->Reg.RegNum = RegNo;
576     Op->StartLoc = S;
577     Op->EndLoc = E;
578     Op->IsRV64 = IsRV64;
579     return Op;
580   }
581 
582   static std::unique_ptr<RISCVOperand> createImm(const MCExpr *Val, SMLoc S,
583                                                  SMLoc E, bool IsRV64) {
584     auto Op = make_unique<RISCVOperand>(Immediate);
585     Op->Imm.Val = Val;
586     Op->StartLoc = S;
587     Op->EndLoc = E;
588     Op->IsRV64 = IsRV64;
589     return Op;
590   }
591 
592   static std::unique_ptr<RISCVOperand>
593   createSysReg(StringRef Str, SMLoc S, unsigned Encoding, bool IsRV64) {
594     auto Op = make_unique<RISCVOperand>(SystemRegister);
595     Op->SysReg.Data = Str.data();
596     Op->SysReg.Length = Str.size();
597     Op->SysReg.Encoding = Encoding;
598     Op->StartLoc = S;
599     Op->IsRV64 = IsRV64;
600     return Op;
601   }
602 
603   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
604     assert(Expr && "Expr shouldn't be null!");
605     int64_t Imm = 0;
606     RISCVMCExpr::VariantKind VK;
607     bool IsConstant = evaluateConstantImm(Expr, Imm, VK);
608 
609     if (IsConstant)
610       Inst.addOperand(MCOperand::createImm(Imm));
611     else
612       Inst.addOperand(MCOperand::createExpr(Expr));
613   }
614 
615   // Used by the TableGen Code
616   void addRegOperands(MCInst &Inst, unsigned N) const {
617     assert(N == 1 && "Invalid number of operands!");
618     Inst.addOperand(MCOperand::createReg(getReg()));
619   }
620 
621   void addImmOperands(MCInst &Inst, unsigned N) const {
622     assert(N == 1 && "Invalid number of operands!");
623     addExpr(Inst, getImm());
624   }
625 
626   void addFenceArgOperands(MCInst &Inst, unsigned N) const {
627     assert(N == 1 && "Invalid number of operands!");
628     // isFenceArg has validated the operand, meaning this cast is safe
629     auto SE = cast<MCSymbolRefExpr>(getImm());
630 
631     unsigned Imm = 0;
632     for (char c : SE->getSymbol().getName()) {
633       switch (c) {
634       default:
635         llvm_unreachable("FenceArg must contain only [iorw]");
636       case 'i': Imm |= RISCVFenceField::I; break;
637       case 'o': Imm |= RISCVFenceField::O; break;
638       case 'r': Imm |= RISCVFenceField::R; break;
639       case 'w': Imm |= RISCVFenceField::W; break;
640       }
641     }
642     Inst.addOperand(MCOperand::createImm(Imm));
643   }
644 
645   void addCSRSystemRegisterOperands(MCInst &Inst, unsigned N) const {
646     assert(N == 1 && "Invalid number of operands!");
647     Inst.addOperand(MCOperand::createImm(SysReg.Encoding));
648   }
649 
650   // Returns the rounding mode represented by this RISCVOperand. Should only
651   // be called after checking isFRMArg.
652   RISCVFPRndMode::RoundingMode getRoundingMode() const {
653     // isFRMArg has validated the operand, meaning this cast is safe.
654     auto SE = cast<MCSymbolRefExpr>(getImm());
655     RISCVFPRndMode::RoundingMode FRM =
656         RISCVFPRndMode::stringToRoundingMode(SE->getSymbol().getName());
657     assert(FRM != RISCVFPRndMode::Invalid && "Invalid rounding mode");
658     return FRM;
659   }
660 
661   void addFRMArgOperands(MCInst &Inst, unsigned N) const {
662     assert(N == 1 && "Invalid number of operands!");
663     Inst.addOperand(MCOperand::createImm(getRoundingMode()));
664   }
665 };
666 } // end anonymous namespace.
667 
668 #define GET_REGISTER_MATCHER
669 #define GET_MATCHER_IMPLEMENTATION
670 #include "RISCVGenAsmMatcher.inc"
671 
672 // Return the matching FPR64 register for the given FPR32.
673 // FIXME: Ideally this function could be removed in favour of using
674 // information from TableGen.
675 unsigned convertFPR32ToFPR64(unsigned Reg) {
676   switch (Reg) {
677   default:
678     llvm_unreachable("Not a recognised FPR32 register");
679   case RISCV::F0_32: return RISCV::F0_64;
680   case RISCV::F1_32: return RISCV::F1_64;
681   case RISCV::F2_32: return RISCV::F2_64;
682   case RISCV::F3_32: return RISCV::F3_64;
683   case RISCV::F4_32: return RISCV::F4_64;
684   case RISCV::F5_32: return RISCV::F5_64;
685   case RISCV::F6_32: return RISCV::F6_64;
686   case RISCV::F7_32: return RISCV::F7_64;
687   case RISCV::F8_32: return RISCV::F8_64;
688   case RISCV::F9_32: return RISCV::F9_64;
689   case RISCV::F10_32: return RISCV::F10_64;
690   case RISCV::F11_32: return RISCV::F11_64;
691   case RISCV::F12_32: return RISCV::F12_64;
692   case RISCV::F13_32: return RISCV::F13_64;
693   case RISCV::F14_32: return RISCV::F14_64;
694   case RISCV::F15_32: return RISCV::F15_64;
695   case RISCV::F16_32: return RISCV::F16_64;
696   case RISCV::F17_32: return RISCV::F17_64;
697   case RISCV::F18_32: return RISCV::F18_64;
698   case RISCV::F19_32: return RISCV::F19_64;
699   case RISCV::F20_32: return RISCV::F20_64;
700   case RISCV::F21_32: return RISCV::F21_64;
701   case RISCV::F22_32: return RISCV::F22_64;
702   case RISCV::F23_32: return RISCV::F23_64;
703   case RISCV::F24_32: return RISCV::F24_64;
704   case RISCV::F25_32: return RISCV::F25_64;
705   case RISCV::F26_32: return RISCV::F26_64;
706   case RISCV::F27_32: return RISCV::F27_64;
707   case RISCV::F28_32: return RISCV::F28_64;
708   case RISCV::F29_32: return RISCV::F29_64;
709   case RISCV::F30_32: return RISCV::F30_64;
710   case RISCV::F31_32: return RISCV::F31_64;
711   }
712 }
713 
714 unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
715                                                     unsigned Kind) {
716   RISCVOperand &Op = static_cast<RISCVOperand &>(AsmOp);
717   if (!Op.isReg())
718     return Match_InvalidOperand;
719 
720   unsigned Reg = Op.getReg();
721   bool IsRegFPR32 =
722       RISCVMCRegisterClasses[RISCV::FPR32RegClassID].contains(Reg);
723   bool IsRegFPR32C =
724       RISCVMCRegisterClasses[RISCV::FPR32CRegClassID].contains(Reg);
725 
726   // As the parser couldn't differentiate an FPR32 from an FPR64, coerce the
727   // register from FPR32 to FPR64 or FPR32C to FPR64C if necessary.
728   if ((IsRegFPR32 && Kind == MCK_FPR64) ||
729       (IsRegFPR32C && Kind == MCK_FPR64C)) {
730     Op.Reg.RegNum = convertFPR32ToFPR64(Reg);
731     return Match_Success;
732   }
733   return Match_InvalidOperand;
734 }
735 
736 bool RISCVAsmParser::generateImmOutOfRangeError(
737     OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper,
738     Twine Msg = "immediate must be an integer in the range") {
739   SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
740   return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]");
741 }
742 
743 bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
744                                              OperandVector &Operands,
745                                              MCStreamer &Out,
746                                              uint64_t &ErrorInfo,
747                                              bool MatchingInlineAsm) {
748   MCInst Inst;
749 
750   auto Result =
751     MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
752   switch (Result) {
753   default:
754     break;
755   case Match_Success:
756     return processInstruction(Inst, IDLoc, Out);
757   case Match_MissingFeature:
758     return Error(IDLoc, "instruction use requires an option to be enabled");
759   case Match_MnemonicFail:
760     return Error(IDLoc, "unrecognized instruction mnemonic");
761   case Match_InvalidOperand: {
762     SMLoc ErrorLoc = IDLoc;
763     if (ErrorInfo != ~0U) {
764       if (ErrorInfo >= Operands.size())
765         return Error(ErrorLoc, "too few operands for instruction");
766 
767       ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
768       if (ErrorLoc == SMLoc())
769         ErrorLoc = IDLoc;
770     }
771     return Error(ErrorLoc, "invalid operand for instruction");
772   }
773   }
774 
775   // Handle the case when the error message is of specific type
776   // other than the generic Match_InvalidOperand, and the
777   // corresponding operand is missing.
778   if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
779     SMLoc ErrorLoc = IDLoc;
780     if (ErrorInfo != ~0U && ErrorInfo >= Operands.size())
781         return Error(ErrorLoc, "too few operands for instruction");
782   }
783 
784   switch(Result) {
785   default:
786     break;
787   case Match_InvalidImmXLenLI:
788     if (isRV64()) {
789       SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
790       return Error(ErrorLoc, "operand must be a constant 64-bit integer");
791     }
792     return generateImmOutOfRangeError(Operands, ErrorInfo,
793                                       std::numeric_limits<int32_t>::min(),
794                                       std::numeric_limits<uint32_t>::max());
795   case Match_InvalidUImmLog2XLen:
796     if (isRV64())
797       return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
798     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
799   case Match_InvalidUImmLog2XLenNonZero:
800     if (isRV64())
801       return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1);
802     return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
803   case Match_InvalidUImm5:
804     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
805   case Match_InvalidSImm6:
806     return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5),
807                                       (1 << 5) - 1);
808   case Match_InvalidSImm6NonZero:
809     return generateImmOutOfRangeError(
810         Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1,
811         "immediate must be non-zero in the range");
812   case Match_InvalidCLUIImm:
813     return generateImmOutOfRangeError(
814         Operands, ErrorInfo, 1, (1 << 5) - 1,
815         "immediate must be in [0xfffe0, 0xfffff] or");
816   case Match_InvalidUImm7Lsb00:
817     return generateImmOutOfRangeError(
818         Operands, ErrorInfo, 0, (1 << 7) - 4,
819         "immediate must be a multiple of 4 bytes in the range");
820   case Match_InvalidUImm8Lsb00:
821     return generateImmOutOfRangeError(
822         Operands, ErrorInfo, 0, (1 << 8) - 4,
823         "immediate must be a multiple of 4 bytes in the range");
824   case Match_InvalidUImm8Lsb000:
825     return generateImmOutOfRangeError(
826         Operands, ErrorInfo, 0, (1 << 8) - 8,
827         "immediate must be a multiple of 8 bytes in the range");
828   case Match_InvalidSImm9Lsb0:
829     return generateImmOutOfRangeError(
830         Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2,
831         "immediate must be a multiple of 2 bytes in the range");
832   case Match_InvalidUImm9Lsb000:
833     return generateImmOutOfRangeError(
834         Operands, ErrorInfo, 0, (1 << 9) - 8,
835         "immediate must be a multiple of 8 bytes in the range");
836   case Match_InvalidUImm10Lsb00NonZero:
837     return generateImmOutOfRangeError(
838         Operands, ErrorInfo, 4, (1 << 10) - 4,
839         "immediate must be a multiple of 4 bytes in the range");
840   case Match_InvalidSImm10Lsb0000NonZero:
841     return generateImmOutOfRangeError(
842         Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
843         "immediate must be a multiple of 16 bytes and non-zero in the range");
844   case Match_InvalidSImm12:
845     return generateImmOutOfRangeError(
846         Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1,
847         "operand must be a symbol with %lo/%pcrel_lo modifier or an integer in "
848         "the range");
849   case Match_InvalidSImm12Lsb0:
850     return generateImmOutOfRangeError(
851         Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2,
852         "immediate must be a multiple of 2 bytes in the range");
853   case Match_InvalidSImm13Lsb0:
854     return generateImmOutOfRangeError(
855         Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2,
856         "immediate must be a multiple of 2 bytes in the range");
857   case Match_InvalidUImm20LUI:
858     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1,
859                                       "operand must be a symbol with %hi() "
860                                       "modifier or an integer in the range");
861   case Match_InvalidUImm20AUIPC:
862     return generateImmOutOfRangeError(
863         Operands, ErrorInfo, 0, (1 << 20) - 1,
864         "operand must be a symbol with %pcrel_hi() modifier or an integer in "
865         "the range");
866   case Match_InvalidSImm21Lsb0JAL:
867     return generateImmOutOfRangeError(
868         Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2,
869         "immediate must be a multiple of 2 bytes in the range");
870   case Match_InvalidCSRSystemRegister: {
871     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1,
872                                       "operand must be a valid system register "
873                                       "name or an integer in the range");
874   }
875   case Match_InvalidFenceArg: {
876     SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
877     return Error(
878         ErrorLoc,
879         "operand must be formed of letters selected in-order from 'iorw'");
880   }
881   case Match_InvalidFRMArg: {
882     SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
883     return Error(
884         ErrorLoc,
885         "operand must be a valid floating point rounding mode mnemonic");
886   }
887   case Match_InvalidBareSymbol: {
888     SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
889     return Error(ErrorLoc, "operand must be a bare symbol name");
890   }
891   }
892 
893   llvm_unreachable("Unknown match type detected!");
894 }
895 
896 bool RISCVAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
897                                    SMLoc &EndLoc) {
898   const AsmToken &Tok = getParser().getTok();
899   StartLoc = Tok.getLoc();
900   EndLoc = Tok.getEndLoc();
901   RegNo = 0;
902   StringRef Name = getLexer().getTok().getIdentifier();
903 
904   if (!MatchRegisterName(Name) || !MatchRegisterAltName(Name)) {
905     getParser().Lex(); // Eat identifier token.
906     return false;
907   }
908 
909   return Error(StartLoc, "invalid register name");
910 }
911 
912 OperandMatchResultTy RISCVAsmParser::parseRegister(OperandVector &Operands,
913                                                    bool AllowParens) {
914   SMLoc FirstS = getLoc();
915   bool HadParens = false;
916   AsmToken Buf[2];
917 
918   // If this a parenthesised register name is allowed, parse it atomically
919   if (AllowParens && getLexer().is(AsmToken::LParen)) {
920     size_t ReadCount = getLexer().peekTokens(Buf);
921     if (ReadCount == 2 && Buf[1].getKind() == AsmToken::RParen) {
922       HadParens = true;
923       getParser().Lex(); // Eat '('
924     }
925   }
926 
927   switch (getLexer().getKind()) {
928   default:
929     return MatchOperand_NoMatch;
930   case AsmToken::Identifier:
931     StringRef Name = getLexer().getTok().getIdentifier();
932     unsigned RegNo = MatchRegisterName(Name);
933     if (RegNo == 0) {
934       RegNo = MatchRegisterAltName(Name);
935       if (RegNo == 0) {
936         if (HadParens)
937           getLexer().UnLex(Buf[0]);
938         return MatchOperand_NoMatch;
939       }
940     }
941     if (HadParens)
942       Operands.push_back(RISCVOperand::createToken("(", FirstS, isRV64()));
943     SMLoc S = getLoc();
944     SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
945     getLexer().Lex();
946     Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64()));
947   }
948 
949   if (HadParens) {
950     getParser().Lex(); // Eat ')'
951     Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64()));
952   }
953 
954   return MatchOperand_Success;
955 }
956 
957 OperandMatchResultTy
958 RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) {
959   SMLoc S = getLoc();
960   const MCExpr *Res;
961 
962   switch (getLexer().getKind()) {
963   default:
964     return MatchOperand_NoMatch;
965   case AsmToken::LParen:
966   case AsmToken::Minus:
967   case AsmToken::Plus:
968   case AsmToken::Integer:
969   case AsmToken::String: {
970     if (getParser().parseExpression(Res))
971       return MatchOperand_ParseFail;
972 
973     auto *CE = dyn_cast<MCConstantExpr>(Res);
974     if (CE) {
975       int64_t Imm = CE->getValue();
976       if (isUInt<12>(Imm)) {
977         auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm);
978         // Accept an immediate representing a named or un-named Sys Reg
979         // if the range is valid, regardless of the required features.
980         Operands.push_back(RISCVOperand::createSysReg(
981             SysReg ? SysReg->Name : "", S, Imm, isRV64()));
982         return MatchOperand_Success;
983       }
984     }
985 
986     Twine Msg = "immediate must be an integer in the range";
987     Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]");
988     return MatchOperand_ParseFail;
989   }
990   case AsmToken::Identifier: {
991     StringRef Identifier;
992     if (getParser().parseIdentifier(Identifier))
993       return MatchOperand_ParseFail;
994 
995     auto SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
996     // Accept a named Sys Reg if the required features are present.
997     if (SysReg) {
998       if (!SysReg->haveRequiredFeatures(getSTI().getFeatureBits())) {
999         Error(S, "system register use requires an option to be enabled");
1000         return MatchOperand_ParseFail;
1001       }
1002       Operands.push_back(RISCVOperand::createSysReg(
1003           Identifier, S, SysReg->Encoding, isRV64()));
1004       return MatchOperand_Success;
1005     }
1006 
1007     Twine Msg = "operand must be a valid system register name "
1008                 "or an integer in the range";
1009     Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]");
1010     return MatchOperand_ParseFail;
1011   }
1012   case AsmToken::Percent: {
1013     // Discard operand with modifier.
1014     Twine Msg = "immediate must be an integer in the range";
1015     Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]");
1016     return MatchOperand_ParseFail;
1017   }
1018   }
1019 
1020   return MatchOperand_NoMatch;
1021 }
1022 
1023 OperandMatchResultTy RISCVAsmParser::parseImmediate(OperandVector &Operands) {
1024   SMLoc S = getLoc();
1025   SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1026   const MCExpr *Res;
1027 
1028   switch (getLexer().getKind()) {
1029   default:
1030     return MatchOperand_NoMatch;
1031   case AsmToken::LParen:
1032   case AsmToken::Minus:
1033   case AsmToken::Plus:
1034   case AsmToken::Integer:
1035   case AsmToken::String:
1036     if (getParser().parseExpression(Res))
1037       return MatchOperand_ParseFail;
1038     break;
1039   case AsmToken::Identifier: {
1040     StringRef Identifier;
1041     if (getParser().parseIdentifier(Identifier))
1042       return MatchOperand_ParseFail;
1043     MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1044     Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1045     break;
1046   }
1047   case AsmToken::Percent:
1048     return parseOperandWithModifier(Operands);
1049   }
1050 
1051   Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1052   return MatchOperand_Success;
1053 }
1054 
1055 OperandMatchResultTy
1056 RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) {
1057   SMLoc S = getLoc();
1058   SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1059 
1060   if (getLexer().getKind() != AsmToken::Percent) {
1061     Error(getLoc(), "expected '%' for operand modifier");
1062     return MatchOperand_ParseFail;
1063   }
1064 
1065   getParser().Lex(); // Eat '%'
1066 
1067   if (getLexer().getKind() != AsmToken::Identifier) {
1068     Error(getLoc(), "expected valid identifier for operand modifier");
1069     return MatchOperand_ParseFail;
1070   }
1071   StringRef Identifier = getParser().getTok().getIdentifier();
1072   RISCVMCExpr::VariantKind VK = RISCVMCExpr::getVariantKindForName(Identifier);
1073   if (VK == RISCVMCExpr::VK_RISCV_Invalid) {
1074     Error(getLoc(), "unrecognized operand modifier");
1075     return MatchOperand_ParseFail;
1076   }
1077 
1078   getParser().Lex(); // Eat the identifier
1079   if (getLexer().getKind() != AsmToken::LParen) {
1080     Error(getLoc(), "expected '('");
1081     return MatchOperand_ParseFail;
1082   }
1083   getParser().Lex(); // Eat '('
1084 
1085   const MCExpr *SubExpr;
1086   if (getParser().parseParenExpression(SubExpr, E)) {
1087     return MatchOperand_ParseFail;
1088   }
1089 
1090   const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, VK, getContext());
1091   Operands.push_back(RISCVOperand::createImm(ModExpr, S, E, isRV64()));
1092   return MatchOperand_Success;
1093 }
1094 
1095 OperandMatchResultTy RISCVAsmParser::parseBareSymbol(OperandVector &Operands) {
1096   SMLoc S = getLoc();
1097   SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1098   const MCExpr *Res;
1099 
1100   if (getLexer().getKind() != AsmToken::Identifier)
1101     return MatchOperand_NoMatch;
1102 
1103   StringRef Identifier;
1104   if (getParser().parseIdentifier(Identifier))
1105     return MatchOperand_ParseFail;
1106 
1107   MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1108   Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1109   Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1110   return MatchOperand_Success;
1111 }
1112 
1113 OperandMatchResultTy RISCVAsmParser::parseJALOffset(OperandVector &Operands) {
1114   // Parsing jal operands is fiddly due to the `jal foo` and `jal ra, foo`
1115   // both being acceptable forms. When parsing `jal ra, foo` this function
1116   // will be called for the `ra` register operand in an attempt to match the
1117   // single-operand alias. parseJALOffset must fail for this case. It would
1118   // seem logical to try parse the operand using parseImmediate and return
1119   // NoMatch if the next token is a comma (meaning we must be parsing a jal in
1120   // the second form rather than the first). We can't do this as there's no
1121   // way of rewinding the lexer state. Instead, return NoMatch if this operand
1122   // is an identifier and is followed by a comma.
1123   if (getLexer().is(AsmToken::Identifier) &&
1124       getLexer().peekTok().is(AsmToken::Comma))
1125     return MatchOperand_NoMatch;
1126 
1127   return parseImmediate(Operands);
1128 }
1129 
1130 OperandMatchResultTy
1131 RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) {
1132   if (getLexer().isNot(AsmToken::LParen)) {
1133     Error(getLoc(), "expected '('");
1134     return MatchOperand_ParseFail;
1135   }
1136 
1137   getParser().Lex(); // Eat '('
1138   Operands.push_back(RISCVOperand::createToken("(", getLoc(), isRV64()));
1139 
1140   if (parseRegister(Operands) != MatchOperand_Success) {
1141     Error(getLoc(), "expected register");
1142     return MatchOperand_ParseFail;
1143   }
1144 
1145   if (getLexer().isNot(AsmToken::RParen)) {
1146     Error(getLoc(), "expected ')'");
1147     return MatchOperand_ParseFail;
1148   }
1149 
1150   getParser().Lex(); // Eat ')'
1151   Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64()));
1152 
1153   return MatchOperand_Success;
1154 }
1155 
1156 /// Looks at a token type and creates the relevant operand from this
1157 /// information, adding to Operands. If operand was parsed, returns false, else
1158 /// true.
1159 bool RISCVAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
1160   // Check if the current operand has a custom associated parser, if so, try to
1161   // custom parse the operand, or fallback to the general approach.
1162   OperandMatchResultTy Result =
1163       MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true);
1164   if (Result == MatchOperand_Success)
1165     return false;
1166   if (Result == MatchOperand_ParseFail)
1167     return true;
1168 
1169   // Attempt to parse token as a register.
1170   if (parseRegister(Operands, true) == MatchOperand_Success)
1171     return false;
1172 
1173   // Attempt to parse token as an immediate
1174   if (parseImmediate(Operands) == MatchOperand_Success) {
1175     // Parse memory base register if present
1176     if (getLexer().is(AsmToken::LParen))
1177       return parseMemOpBaseReg(Operands) != MatchOperand_Success;
1178     return false;
1179   }
1180 
1181   // Finally we have exhausted all options and must declare defeat.
1182   Error(getLoc(), "unknown operand");
1183   return true;
1184 }
1185 
1186 bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info,
1187                                       StringRef Name, SMLoc NameLoc,
1188                                       OperandVector &Operands) {
1189   // Ensure that if the instruction occurs when relaxation is enabled,
1190   // relocations are forced for the file. Ideally this would be done when there
1191   // is enough information to reliably determine if the instruction itself may
1192   // cause relaxations. Unfortunately instruction processing stage occurs in the
1193   // same pass as relocation emission, so it's too late to set a 'sticky bit'
1194   // for the entire file.
1195   if (getSTI().getFeatureBits()[RISCV::FeatureRelax]) {
1196     auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr();
1197     if (Assembler != nullptr) {
1198       RISCVAsmBackend &MAB =
1199           static_cast<RISCVAsmBackend &>(Assembler->getBackend());
1200       MAB.setForceRelocs();
1201     }
1202   }
1203 
1204   // First operand is token for instruction
1205   Operands.push_back(RISCVOperand::createToken(Name, NameLoc, isRV64()));
1206 
1207   // If there are no more operands, then finish
1208   if (getLexer().is(AsmToken::EndOfStatement))
1209     return false;
1210 
1211   // Parse first operand
1212   if (parseOperand(Operands, Name))
1213     return true;
1214 
1215   // Parse until end of statement, consuming commas between operands
1216   unsigned OperandIdx = 1;
1217   while (getLexer().is(AsmToken::Comma)) {
1218     // Consume comma token
1219     getLexer().Lex();
1220 
1221     // Parse next operand
1222     if (parseOperand(Operands, Name))
1223       return true;
1224 
1225     ++OperandIdx;
1226   }
1227 
1228   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1229     SMLoc Loc = getLexer().getLoc();
1230     getParser().eatToEndOfStatement();
1231     return Error(Loc, "unexpected token");
1232   }
1233 
1234   getParser().Lex(); // Consume the EndOfStatement.
1235   return false;
1236 }
1237 
1238 bool RISCVAsmParser::classifySymbolRef(const MCExpr *Expr,
1239                                        RISCVMCExpr::VariantKind &Kind,
1240                                        int64_t &Addend) {
1241   Kind = RISCVMCExpr::VK_RISCV_None;
1242   Addend = 0;
1243 
1244   if (const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) {
1245     Kind = RE->getKind();
1246     Expr = RE->getSubExpr();
1247   }
1248 
1249   // It's a simple symbol reference or constant with no addend.
1250   if (isa<MCConstantExpr>(Expr) || isa<MCSymbolRefExpr>(Expr))
1251     return true;
1252 
1253   const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr);
1254   if (!BE)
1255     return false;
1256 
1257   if (!isa<MCSymbolRefExpr>(BE->getLHS()))
1258     return false;
1259 
1260   if (BE->getOpcode() != MCBinaryExpr::Add &&
1261       BE->getOpcode() != MCBinaryExpr::Sub)
1262     return false;
1263 
1264   // We are able to support the subtraction of two symbol references
1265   if (BE->getOpcode() == MCBinaryExpr::Sub &&
1266       isa<MCSymbolRefExpr>(BE->getRHS()))
1267     return true;
1268 
1269   // See if the addend is a constant, otherwise there's more going
1270   // on here than we can deal with.
1271   auto AddendExpr = dyn_cast<MCConstantExpr>(BE->getRHS());
1272   if (!AddendExpr)
1273     return false;
1274 
1275   Addend = AddendExpr->getValue();
1276   if (BE->getOpcode() == MCBinaryExpr::Sub)
1277     Addend = -Addend;
1278 
1279   // It's some symbol reference + a constant addend
1280   return Kind != RISCVMCExpr::VK_RISCV_Invalid;
1281 }
1282 
1283 bool RISCVAsmParser::ParseDirective(AsmToken DirectiveID) {
1284   // This returns false if this function recognizes the directive
1285   // regardless of whether it is successfully handles or reports an
1286   // error. Otherwise it returns true to give the generic parser a
1287   // chance at recognizing it.
1288   StringRef IDVal = DirectiveID.getString();
1289 
1290   if (IDVal == ".option")
1291     return parseDirectiveOption();
1292 
1293   return true;
1294 }
1295 
1296 bool RISCVAsmParser::parseDirectiveOption() {
1297   MCAsmParser &Parser = getParser();
1298   // Get the option token.
1299   AsmToken Tok = Parser.getTok();
1300   // At the moment only identifiers are supported.
1301   if (Tok.isNot(AsmToken::Identifier))
1302     return Error(Parser.getTok().getLoc(),
1303                  "unexpected token, expected identifier");
1304 
1305   StringRef Option = Tok.getIdentifier();
1306 
1307   if (Option == "push") {
1308     getTargetStreamer().emitDirectiveOptionPush();
1309 
1310     Parser.Lex();
1311     if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1312       return Error(Parser.getTok().getLoc(),
1313                    "unexpected token, expected end of statement");
1314 
1315     pushFeatureBits();
1316     return false;
1317   }
1318 
1319   if (Option == "pop") {
1320     SMLoc StartLoc = Parser.getTok().getLoc();
1321     getTargetStreamer().emitDirectiveOptionPop();
1322 
1323     Parser.Lex();
1324     if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1325       return Error(Parser.getTok().getLoc(),
1326                    "unexpected token, expected end of statement");
1327 
1328     if (popFeatureBits())
1329       return Error(StartLoc, ".option pop with no .option push");
1330 
1331     return false;
1332   }
1333 
1334   if (Option == "rvc") {
1335     getTargetStreamer().emitDirectiveOptionRVC();
1336 
1337     Parser.Lex();
1338     if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1339       return Error(Parser.getTok().getLoc(),
1340                    "unexpected token, expected end of statement");
1341 
1342     setFeatureBits(RISCV::FeatureStdExtC, "c");
1343     return false;
1344   }
1345 
1346   if (Option == "norvc") {
1347     getTargetStreamer().emitDirectiveOptionNoRVC();
1348 
1349     Parser.Lex();
1350     if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1351       return Error(Parser.getTok().getLoc(),
1352                    "unexpected token, expected end of statement");
1353 
1354     clearFeatureBits(RISCV::FeatureStdExtC, "c");
1355     return false;
1356   }
1357 
1358   if (Option == "relax") {
1359     getTargetStreamer().emitDirectiveOptionRelax();
1360 
1361     Parser.Lex();
1362     if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1363       return Error(Parser.getTok().getLoc(),
1364                    "unexpected token, expected end of statement");
1365 
1366     setFeatureBits(RISCV::FeatureRelax, "relax");
1367     return false;
1368   }
1369 
1370   if (Option == "norelax") {
1371     getTargetStreamer().emitDirectiveOptionNoRelax();
1372 
1373     Parser.Lex();
1374     if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1375       return Error(Parser.getTok().getLoc(),
1376                    "unexpected token, expected end of statement");
1377 
1378     clearFeatureBits(RISCV::FeatureRelax, "relax");
1379     return false;
1380   }
1381 
1382   // Unknown option.
1383   Warning(Parser.getTok().getLoc(),
1384           "unknown option, expected 'push', 'pop', 'rvc', 'norvc', 'relax' or "
1385           "'norelax'");
1386   Parser.eatToEndOfStatement();
1387   return false;
1388 }
1389 
1390 void RISCVAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) {
1391   MCInst CInst;
1392   bool Res = compressInst(CInst, Inst, getSTI(), S.getContext());
1393   CInst.setLoc(Inst.getLoc());
1394   S.EmitInstruction((Res ? CInst : Inst), getSTI());
1395 }
1396 
1397 void RISCVAsmParser::emitLoadImm(unsigned DestReg, int64_t Value,
1398                                  MCStreamer &Out) {
1399   RISCVMatInt::InstSeq Seq;
1400   RISCVMatInt::generateInstSeq(Value, isRV64(), Seq);
1401 
1402   unsigned SrcReg = RISCV::X0;
1403   for (RISCVMatInt::Inst &Inst : Seq) {
1404     if (Inst.Opc == RISCV::LUI) {
1405       emitToStreamer(
1406           Out, MCInstBuilder(RISCV::LUI).addReg(DestReg).addImm(Inst.Imm));
1407     } else {
1408       emitToStreamer(
1409           Out, MCInstBuilder(Inst.Opc).addReg(DestReg).addReg(SrcReg).addImm(
1410                    Inst.Imm));
1411     }
1412 
1413     // Only the first instruction has X0 as its source.
1414     SrcReg = DestReg;
1415   }
1416 }
1417 
1418 void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
1419                                           MCStreamer &Out) {
1420   // The local load address pseudo-instruction "lla" is used in PC-relative
1421   // addressing of symbols:
1422   //   lla rdest, symbol
1423   // expands to
1424   //   TmpLabel: AUIPC rdest, %pcrel_hi(symbol)
1425   //             ADDI rdest, %pcrel_lo(TmpLabel)
1426   MCContext &Ctx = getContext();
1427 
1428   MCSymbol *TmpLabel = Ctx.createTempSymbol(
1429       "pcrel_hi", /* AlwaysAddSuffix */ true, /* CanBeUnnamed */ false);
1430   Out.EmitLabel(TmpLabel);
1431 
1432   MCOperand DestReg = Inst.getOperand(0);
1433   const RISCVMCExpr *Symbol = RISCVMCExpr::create(
1434       Inst.getOperand(1).getExpr(), RISCVMCExpr::VK_RISCV_PCREL_HI, Ctx);
1435 
1436   emitToStreamer(
1437       Out, MCInstBuilder(RISCV::AUIPC).addOperand(DestReg).addExpr(Symbol));
1438 
1439   const MCExpr *RefToLinkTmpLabel =
1440       RISCVMCExpr::create(MCSymbolRefExpr::create(TmpLabel, Ctx),
1441                           RISCVMCExpr::VK_RISCV_PCREL_LO, Ctx);
1442 
1443   emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
1444                           .addOperand(DestReg)
1445                           .addOperand(DestReg)
1446                           .addExpr(RefToLinkTmpLabel));
1447 }
1448 
1449 bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1450                                         MCStreamer &Out) {
1451   Inst.setLoc(IDLoc);
1452 
1453   if (Inst.getOpcode() == RISCV::PseudoLI) {
1454     unsigned Reg = Inst.getOperand(0).getReg();
1455     const MCOperand &Op1 = Inst.getOperand(1);
1456     if (Op1.isExpr()) {
1457       // We must have li reg, %lo(sym) or li reg, %pcrel_lo(sym) or similar.
1458       // Just convert to an addi. This allows compatibility with gas.
1459       emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
1460                               .addReg(Reg)
1461                               .addReg(RISCV::X0)
1462                               .addExpr(Op1.getExpr()));
1463       return false;
1464     }
1465     int64_t Imm = Inst.getOperand(1).getImm();
1466     // On RV32 the immediate here can either be a signed or an unsigned
1467     // 32-bit number. Sign extension has to be performed to ensure that Imm
1468     // represents the expected signed 64-bit number.
1469     if (!isRV64())
1470       Imm = SignExtend64<32>(Imm);
1471     emitLoadImm(Reg, Imm, Out);
1472     return false;
1473   } else if (Inst.getOpcode() == RISCV::PseudoLLA) {
1474     emitLoadLocalAddress(Inst, IDLoc, Out);
1475     return false;
1476   }
1477 
1478   emitToStreamer(Out, Inst);
1479   return false;
1480 }
1481 
1482 extern "C" void LLVMInitializeRISCVAsmParser() {
1483   RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target());
1484   RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target());
1485 }
1486