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