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 
getLoc() const48   SMLoc getLoc() const { return getParser().getTok().getLoc(); }
isRV64() const49   bool isRV64() const { return getSTI().hasFeature(RISCV::Feature64Bit); }
50 
getTargetStreamer()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 
setFeatureBits(uint64_t Feature,StringRef FeatureString)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 
clearFeatureBits(uint64_t Feature,StringRef FeatureString)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 
pushFeatureBits()124   void pushFeatureBits() {
125     FeatureBitStack.push_back(getSTI().getFeatureBits());
126   }
127 
popFeatureBits()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 
RISCVAsmParser(const MCSubtargetInfo & STI,MCAsmParser & Parser,const MCInstrInfo & MII,const MCTargetOptions & Options)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 
RISCVOperand__anond849e6730111::RISCVOperand198   RISCVOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
199 
200 public:
RISCVOperand__anond849e6730111::RISCVOperand201   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 
isToken__anond849e6730111::RISCVOperand222   bool isToken() const override { return Kind == Token; }
isReg__anond849e6730111::RISCVOperand223   bool isReg() const override { return Kind == Register; }
isImm__anond849e6730111::RISCVOperand224   bool isImm() const override { return Kind == Immediate; }
isMem__anond849e6730111::RISCVOperand225   bool isMem() const override { return false; }
isSystemRegister__anond849e6730111::RISCVOperand226   bool isSystemRegister() const { return Kind == SystemRegister; }
227 
evaluateConstantImm__anond849e6730111::RISCVOperand228   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).
isBareSimmNLsb0__anond849e6730111::RISCVOperand246   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 
isBareSymbol__anond849e6730111::RISCVOperand262   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 
isCSRSystemRegister__anond849e6730111::RISCVOperand272   bool isCSRSystemRegister() const { return isSystemRegister(); }
273 
274   /// Return true if the operand is a valid for the fence instruction e.g.
275   /// ('iorw').
isFenceArg__anond849e6730111::RISCVOperand276   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.
isFRMArg__anond849e6730111::RISCVOperand300   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 
isImmXLenLI__anond849e6730111::RISCVOperand313   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 
isUImmLog2XLen__anond849e6730111::RISCVOperand327   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 
isUImmLog2XLenNonZero__anond849e6730111::RISCVOperand338   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 
isUImm5__anond849e6730111::RISCVOperand351   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 
isUImm5NonZero__anond849e6730111::RISCVOperand360   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 
isSImm6__anond849e6730111::RISCVOperand370   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 
isSImm6NonZero__anond849e6730111::RISCVOperand380   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 
isCLUIImm__anond849e6730111::RISCVOperand390   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 
isUImm7Lsb00__anond849e6730111::RISCVOperand401   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 
isUImm8Lsb00__anond849e6730111::RISCVOperand411   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 
isUImm8Lsb000__anond849e6730111::RISCVOperand421   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 
isSImm9Lsb0__anond849e6730111::RISCVOperand431   bool isSImm9Lsb0() const { return isBareSimmNLsb0<9>(); }
432 
isUImm9Lsb000__anond849e6730111::RISCVOperand433   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 
isUImm10Lsb00NonZero__anond849e6730111::RISCVOperand443   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 
isSImm12__anond849e6730111::RISCVOperand453   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 
isSImm12Lsb0__anond849e6730111::RISCVOperand469   bool isSImm12Lsb0() const { return isBareSimmNLsb0<12>(); }
470 
isSImm13Lsb0__anond849e6730111::RISCVOperand471   bool isSImm13Lsb0() const { return isBareSimmNLsb0<13>(); }
472 
isSImm10Lsb0000NonZero__anond849e6730111::RISCVOperand473   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 
isUImm20LUI__anond849e6730111::RISCVOperand483   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 
isUImm20AUIPC__anond849e6730111::RISCVOperand499   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 
isSImm21Lsb0JAL__anond849e6730111::RISCVOperand515   bool isSImm21Lsb0JAL() const { return isBareSimmNLsb0<21>(); }
516 
517   /// getStartLoc - Gets location of the first token of this operand
getStartLoc__anond849e6730111::RISCVOperand518   SMLoc getStartLoc() const override { return StartLoc; }
519   /// getEndLoc - Gets location of the last token of this operand
getEndLoc__anond849e6730111::RISCVOperand520   SMLoc getEndLoc() const override { return EndLoc; }
521   /// True if this operand is for an RV64 instruction
isRV64__anond849e6730111::RISCVOperand522   bool isRV64() const { return IsRV64; }
523 
getReg__anond849e6730111::RISCVOperand524   unsigned getReg() const override {
525     assert(Kind == Register && "Invalid type access!");
526     return Reg.RegNum;
527   }
528 
getSysReg__anond849e6730111::RISCVOperand529   StringRef getSysReg() const {
530     assert(Kind == SystemRegister && "Invalid access!");
531     return StringRef(SysReg.Data, SysReg.Length);
532   }
533 
getImm__anond849e6730111::RISCVOperand534   const MCExpr *getImm() const {
535     assert(Kind == Immediate && "Invalid type access!");
536     return Imm.Val;
537   }
538 
getToken__anond849e6730111::RISCVOperand539   StringRef getToken() const {
540     assert(Kind == Token && "Invalid type access!");
541     return Tok;
542   }
543 
print__anond849e6730111::RISCVOperand544   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 
createToken__anond849e6730111::RISCVOperand562   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 
createReg__anond849e6730111::RISCVOperand572   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 
createImm__anond849e6730111::RISCVOperand582   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>
createSysReg__anond849e6730111::RISCVOperand593   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 
addExpr__anond849e6730111::RISCVOperand603   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
addRegOperands__anond849e6730111::RISCVOperand616   void addRegOperands(MCInst &Inst, unsigned N) const {
617     assert(N == 1 && "Invalid number of operands!");
618     Inst.addOperand(MCOperand::createReg(getReg()));
619   }
620 
addImmOperands__anond849e6730111::RISCVOperand621   void addImmOperands(MCInst &Inst, unsigned N) const {
622     assert(N == 1 && "Invalid number of operands!");
623     addExpr(Inst, getImm());
624   }
625 
addFenceArgOperands__anond849e6730111::RISCVOperand626   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 
addCSRSystemRegisterOperands__anond849e6730111::RISCVOperand645   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.
getRoundingMode__anond849e6730111::RISCVOperand652   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 
addFRMArgOperands__anond849e6730111::RISCVOperand661   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.
convertFPR32ToFPR64(unsigned Reg)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 
validateTargetOperandClass(MCParsedAsmOperand & AsmOp,unsigned Kind)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 
generateImmOutOfRangeError(OperandVector & Operands,uint64_t ErrorInfo,int64_t Lower,int64_t Upper,Twine Msg="immediate must be an integer in the range")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 
MatchAndEmitInstruction(SMLoc IDLoc,unsigned & Opcode,OperandVector & Operands,MCStreamer & Out,uint64_t & ErrorInfo,bool MatchingInlineAsm)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 
ParseRegister(unsigned & RegNo,SMLoc & StartLoc,SMLoc & EndLoc)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 
parseRegister(OperandVector & Operands,bool AllowParens)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
parseCSRSystemRegister(OperandVector & Operands)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 
parseImmediate(OperandVector & Operands)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   case AsmToken::Identifier:
1037     if (getParser().parseExpression(Res))
1038       return MatchOperand_ParseFail;
1039     break;
1040   case AsmToken::Percent:
1041     return parseOperandWithModifier(Operands);
1042   }
1043 
1044   Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1045   return MatchOperand_Success;
1046 }
1047 
1048 OperandMatchResultTy
parseOperandWithModifier(OperandVector & Operands)1049 RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) {
1050   SMLoc S = getLoc();
1051   SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1052 
1053   if (getLexer().getKind() != AsmToken::Percent) {
1054     Error(getLoc(), "expected '%' for operand modifier");
1055     return MatchOperand_ParseFail;
1056   }
1057 
1058   getParser().Lex(); // Eat '%'
1059 
1060   if (getLexer().getKind() != AsmToken::Identifier) {
1061     Error(getLoc(), "expected valid identifier for operand modifier");
1062     return MatchOperand_ParseFail;
1063   }
1064   StringRef Identifier = getParser().getTok().getIdentifier();
1065   RISCVMCExpr::VariantKind VK = RISCVMCExpr::getVariantKindForName(Identifier);
1066   if (VK == RISCVMCExpr::VK_RISCV_Invalid) {
1067     Error(getLoc(), "unrecognized operand modifier");
1068     return MatchOperand_ParseFail;
1069   }
1070 
1071   getParser().Lex(); // Eat the identifier
1072   if (getLexer().getKind() != AsmToken::LParen) {
1073     Error(getLoc(), "expected '('");
1074     return MatchOperand_ParseFail;
1075   }
1076   getParser().Lex(); // Eat '('
1077 
1078   const MCExpr *SubExpr;
1079   if (getParser().parseParenExpression(SubExpr, E)) {
1080     return MatchOperand_ParseFail;
1081   }
1082 
1083   const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, VK, getContext());
1084   Operands.push_back(RISCVOperand::createImm(ModExpr, S, E, isRV64()));
1085   return MatchOperand_Success;
1086 }
1087 
parseBareSymbol(OperandVector & Operands)1088 OperandMatchResultTy RISCVAsmParser::parseBareSymbol(OperandVector &Operands) {
1089   SMLoc S = getLoc();
1090   SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1091   const MCExpr *Res;
1092 
1093   if (getLexer().getKind() != AsmToken::Identifier)
1094     return MatchOperand_NoMatch;
1095 
1096   StringRef Identifier;
1097   if (getParser().parseIdentifier(Identifier))
1098     return MatchOperand_ParseFail;
1099 
1100   MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1101   Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1102   Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1103   return MatchOperand_Success;
1104 }
1105 
parseJALOffset(OperandVector & Operands)1106 OperandMatchResultTy RISCVAsmParser::parseJALOffset(OperandVector &Operands) {
1107   // Parsing jal operands is fiddly due to the `jal foo` and `jal ra, foo`
1108   // both being acceptable forms. When parsing `jal ra, foo` this function
1109   // will be called for the `ra` register operand in an attempt to match the
1110   // single-operand alias. parseJALOffset must fail for this case. It would
1111   // seem logical to try parse the operand using parseImmediate and return
1112   // NoMatch if the next token is a comma (meaning we must be parsing a jal in
1113   // the second form rather than the first). We can't do this as there's no
1114   // way of rewinding the lexer state. Instead, return NoMatch if this operand
1115   // is an identifier and is followed by a comma.
1116   if (getLexer().is(AsmToken::Identifier) &&
1117       getLexer().peekTok().is(AsmToken::Comma))
1118     return MatchOperand_NoMatch;
1119 
1120   return parseImmediate(Operands);
1121 }
1122 
1123 OperandMatchResultTy
parseMemOpBaseReg(OperandVector & Operands)1124 RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) {
1125   if (getLexer().isNot(AsmToken::LParen)) {
1126     Error(getLoc(), "expected '('");
1127     return MatchOperand_ParseFail;
1128   }
1129 
1130   getParser().Lex(); // Eat '('
1131   Operands.push_back(RISCVOperand::createToken("(", getLoc(), isRV64()));
1132 
1133   if (parseRegister(Operands) != MatchOperand_Success) {
1134     Error(getLoc(), "expected register");
1135     return MatchOperand_ParseFail;
1136   }
1137 
1138   if (getLexer().isNot(AsmToken::RParen)) {
1139     Error(getLoc(), "expected ')'");
1140     return MatchOperand_ParseFail;
1141   }
1142 
1143   getParser().Lex(); // Eat ')'
1144   Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64()));
1145 
1146   return MatchOperand_Success;
1147 }
1148 
1149 /// Looks at a token type and creates the relevant operand from this
1150 /// information, adding to Operands. If operand was parsed, returns false, else
1151 /// true.
parseOperand(OperandVector & Operands,StringRef Mnemonic)1152 bool RISCVAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
1153   // Check if the current operand has a custom associated parser, if so, try to
1154   // custom parse the operand, or fallback to the general approach.
1155   OperandMatchResultTy Result =
1156       MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true);
1157   if (Result == MatchOperand_Success)
1158     return false;
1159   if (Result == MatchOperand_ParseFail)
1160     return true;
1161 
1162   // Attempt to parse token as a register.
1163   if (parseRegister(Operands, true) == MatchOperand_Success)
1164     return false;
1165 
1166   // Attempt to parse token as an immediate
1167   if (parseImmediate(Operands) == MatchOperand_Success) {
1168     // Parse memory base register if present
1169     if (getLexer().is(AsmToken::LParen))
1170       return parseMemOpBaseReg(Operands) != MatchOperand_Success;
1171     return false;
1172   }
1173 
1174   // Finally we have exhausted all options and must declare defeat.
1175   Error(getLoc(), "unknown operand");
1176   return true;
1177 }
1178 
ParseInstruction(ParseInstructionInfo & Info,StringRef Name,SMLoc NameLoc,OperandVector & Operands)1179 bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info,
1180                                       StringRef Name, SMLoc NameLoc,
1181                                       OperandVector &Operands) {
1182   // Ensure that if the instruction occurs when relaxation is enabled,
1183   // relocations are forced for the file. Ideally this would be done when there
1184   // is enough information to reliably determine if the instruction itself may
1185   // cause relaxations. Unfortunately instruction processing stage occurs in the
1186   // same pass as relocation emission, so it's too late to set a 'sticky bit'
1187   // for the entire file.
1188   if (getSTI().getFeatureBits()[RISCV::FeatureRelax]) {
1189     auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr();
1190     if (Assembler != nullptr) {
1191       RISCVAsmBackend &MAB =
1192           static_cast<RISCVAsmBackend &>(Assembler->getBackend());
1193       MAB.setForceRelocs();
1194     }
1195   }
1196 
1197   // First operand is token for instruction
1198   Operands.push_back(RISCVOperand::createToken(Name, NameLoc, isRV64()));
1199 
1200   // If there are no more operands, then finish
1201   if (getLexer().is(AsmToken::EndOfStatement))
1202     return false;
1203 
1204   // Parse first operand
1205   if (parseOperand(Operands, Name))
1206     return true;
1207 
1208   // Parse until end of statement, consuming commas between operands
1209   unsigned OperandIdx = 1;
1210   while (getLexer().is(AsmToken::Comma)) {
1211     // Consume comma token
1212     getLexer().Lex();
1213 
1214     // Parse next operand
1215     if (parseOperand(Operands, Name))
1216       return true;
1217 
1218     ++OperandIdx;
1219   }
1220 
1221   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1222     SMLoc Loc = getLexer().getLoc();
1223     getParser().eatToEndOfStatement();
1224     return Error(Loc, "unexpected token");
1225   }
1226 
1227   getParser().Lex(); // Consume the EndOfStatement.
1228   return false;
1229 }
1230 
classifySymbolRef(const MCExpr * Expr,RISCVMCExpr::VariantKind & Kind,int64_t & Addend)1231 bool RISCVAsmParser::classifySymbolRef(const MCExpr *Expr,
1232                                        RISCVMCExpr::VariantKind &Kind,
1233                                        int64_t &Addend) {
1234   Kind = RISCVMCExpr::VK_RISCV_None;
1235   Addend = 0;
1236 
1237   if (const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) {
1238     Kind = RE->getKind();
1239     Expr = RE->getSubExpr();
1240   }
1241 
1242   // It's a simple symbol reference or constant with no addend.
1243   if (isa<MCConstantExpr>(Expr) || isa<MCSymbolRefExpr>(Expr))
1244     return true;
1245 
1246   const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr);
1247   if (!BE)
1248     return false;
1249 
1250   if (!isa<MCSymbolRefExpr>(BE->getLHS()))
1251     return false;
1252 
1253   if (BE->getOpcode() != MCBinaryExpr::Add &&
1254       BE->getOpcode() != MCBinaryExpr::Sub)
1255     return false;
1256 
1257   // We are able to support the subtraction of two symbol references
1258   if (BE->getOpcode() == MCBinaryExpr::Sub &&
1259       isa<MCSymbolRefExpr>(BE->getRHS()))
1260     return true;
1261 
1262   // See if the addend is a constant, otherwise there's more going
1263   // on here than we can deal with.
1264   auto AddendExpr = dyn_cast<MCConstantExpr>(BE->getRHS());
1265   if (!AddendExpr)
1266     return false;
1267 
1268   Addend = AddendExpr->getValue();
1269   if (BE->getOpcode() == MCBinaryExpr::Sub)
1270     Addend = -Addend;
1271 
1272   // It's some symbol reference + a constant addend
1273   return Kind != RISCVMCExpr::VK_RISCV_Invalid;
1274 }
1275 
ParseDirective(AsmToken DirectiveID)1276 bool RISCVAsmParser::ParseDirective(AsmToken DirectiveID) {
1277   // This returns false if this function recognizes the directive
1278   // regardless of whether it is successfully handles or reports an
1279   // error. Otherwise it returns true to give the generic parser a
1280   // chance at recognizing it.
1281   StringRef IDVal = DirectiveID.getString();
1282 
1283   if (IDVal == ".option")
1284     return parseDirectiveOption();
1285 
1286   return true;
1287 }
1288 
parseDirectiveOption()1289 bool RISCVAsmParser::parseDirectiveOption() {
1290   MCAsmParser &Parser = getParser();
1291   // Get the option token.
1292   AsmToken Tok = Parser.getTok();
1293   // At the moment only identifiers are supported.
1294   if (Tok.isNot(AsmToken::Identifier))
1295     return Error(Parser.getTok().getLoc(),
1296                  "unexpected token, expected identifier");
1297 
1298   StringRef Option = Tok.getIdentifier();
1299 
1300   if (Option == "push") {
1301     getTargetStreamer().emitDirectiveOptionPush();
1302 
1303     Parser.Lex();
1304     if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1305       return Error(Parser.getTok().getLoc(),
1306                    "unexpected token, expected end of statement");
1307 
1308     pushFeatureBits();
1309     return false;
1310   }
1311 
1312   if (Option == "pop") {
1313     SMLoc StartLoc = Parser.getTok().getLoc();
1314     getTargetStreamer().emitDirectiveOptionPop();
1315 
1316     Parser.Lex();
1317     if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1318       return Error(Parser.getTok().getLoc(),
1319                    "unexpected token, expected end of statement");
1320 
1321     if (popFeatureBits())
1322       return Error(StartLoc, ".option pop with no .option push");
1323 
1324     return false;
1325   }
1326 
1327   if (Option == "rvc") {
1328     getTargetStreamer().emitDirectiveOptionRVC();
1329 
1330     Parser.Lex();
1331     if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1332       return Error(Parser.getTok().getLoc(),
1333                    "unexpected token, expected end of statement");
1334 
1335     setFeatureBits(RISCV::FeatureStdExtC, "c");
1336     return false;
1337   }
1338 
1339   if (Option == "norvc") {
1340     getTargetStreamer().emitDirectiveOptionNoRVC();
1341 
1342     Parser.Lex();
1343     if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1344       return Error(Parser.getTok().getLoc(),
1345                    "unexpected token, expected end of statement");
1346 
1347     clearFeatureBits(RISCV::FeatureStdExtC, "c");
1348     return false;
1349   }
1350 
1351   if (Option == "relax") {
1352     getTargetStreamer().emitDirectiveOptionRelax();
1353 
1354     Parser.Lex();
1355     if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1356       return Error(Parser.getTok().getLoc(),
1357                    "unexpected token, expected end of statement");
1358 
1359     setFeatureBits(RISCV::FeatureRelax, "relax");
1360     return false;
1361   }
1362 
1363   if (Option == "norelax") {
1364     getTargetStreamer().emitDirectiveOptionNoRelax();
1365 
1366     Parser.Lex();
1367     if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1368       return Error(Parser.getTok().getLoc(),
1369                    "unexpected token, expected end of statement");
1370 
1371     clearFeatureBits(RISCV::FeatureRelax, "relax");
1372     return false;
1373   }
1374 
1375   // Unknown option.
1376   Warning(Parser.getTok().getLoc(),
1377           "unknown option, expected 'push', 'pop', 'rvc', 'norvc', 'relax' or "
1378           "'norelax'");
1379   Parser.eatToEndOfStatement();
1380   return false;
1381 }
1382 
emitToStreamer(MCStreamer & S,const MCInst & Inst)1383 void RISCVAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) {
1384   MCInst CInst;
1385   bool Res = compressInst(CInst, Inst, getSTI(), S.getContext());
1386   CInst.setLoc(Inst.getLoc());
1387   S.EmitInstruction((Res ? CInst : Inst), getSTI());
1388 }
1389 
emitLoadImm(unsigned DestReg,int64_t Value,MCStreamer & Out)1390 void RISCVAsmParser::emitLoadImm(unsigned DestReg, int64_t Value,
1391                                  MCStreamer &Out) {
1392   RISCVMatInt::InstSeq Seq;
1393   RISCVMatInt::generateInstSeq(Value, isRV64(), Seq);
1394 
1395   unsigned SrcReg = RISCV::X0;
1396   for (RISCVMatInt::Inst &Inst : Seq) {
1397     if (Inst.Opc == RISCV::LUI) {
1398       emitToStreamer(
1399           Out, MCInstBuilder(RISCV::LUI).addReg(DestReg).addImm(Inst.Imm));
1400     } else {
1401       emitToStreamer(
1402           Out, MCInstBuilder(Inst.Opc).addReg(DestReg).addReg(SrcReg).addImm(
1403                    Inst.Imm));
1404     }
1405 
1406     // Only the first instruction has X0 as its source.
1407     SrcReg = DestReg;
1408   }
1409 }
1410 
emitLoadLocalAddress(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out)1411 void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
1412                                           MCStreamer &Out) {
1413   // The local load address pseudo-instruction "lla" is used in PC-relative
1414   // addressing of symbols:
1415   //   lla rdest, symbol
1416   // expands to
1417   //   TmpLabel: AUIPC rdest, %pcrel_hi(symbol)
1418   //             ADDI rdest, %pcrel_lo(TmpLabel)
1419   MCContext &Ctx = getContext();
1420 
1421   MCSymbol *TmpLabel = Ctx.createTempSymbol(
1422       "pcrel_hi", /* AlwaysAddSuffix */ true, /* CanBeUnnamed */ false);
1423   Out.EmitLabel(TmpLabel);
1424 
1425   MCOperand DestReg = Inst.getOperand(0);
1426   const RISCVMCExpr *Symbol = RISCVMCExpr::create(
1427       Inst.getOperand(1).getExpr(), RISCVMCExpr::VK_RISCV_PCREL_HI, Ctx);
1428 
1429   emitToStreamer(
1430       Out, MCInstBuilder(RISCV::AUIPC).addOperand(DestReg).addExpr(Symbol));
1431 
1432   const MCExpr *RefToLinkTmpLabel =
1433       RISCVMCExpr::create(MCSymbolRefExpr::create(TmpLabel, Ctx),
1434                           RISCVMCExpr::VK_RISCV_PCREL_LO, Ctx);
1435 
1436   emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
1437                           .addOperand(DestReg)
1438                           .addOperand(DestReg)
1439                           .addExpr(RefToLinkTmpLabel));
1440 }
1441 
processInstruction(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out)1442 bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1443                                         MCStreamer &Out) {
1444   Inst.setLoc(IDLoc);
1445 
1446   if (Inst.getOpcode() == RISCV::PseudoLI) {
1447     unsigned Reg = Inst.getOperand(0).getReg();
1448     const MCOperand &Op1 = Inst.getOperand(1);
1449     if (Op1.isExpr()) {
1450       // We must have li reg, %lo(sym) or li reg, %pcrel_lo(sym) or similar.
1451       // Just convert to an addi. This allows compatibility with gas.
1452       emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
1453                               .addReg(Reg)
1454                               .addReg(RISCV::X0)
1455                               .addExpr(Op1.getExpr()));
1456       return false;
1457     }
1458     int64_t Imm = Inst.getOperand(1).getImm();
1459     // On RV32 the immediate here can either be a signed or an unsigned
1460     // 32-bit number. Sign extension has to be performed to ensure that Imm
1461     // represents the expected signed 64-bit number.
1462     if (!isRV64())
1463       Imm = SignExtend64<32>(Imm);
1464     emitLoadImm(Reg, Imm, Out);
1465     return false;
1466   } else if (Inst.getOpcode() == RISCV::PseudoLLA) {
1467     emitLoadLocalAddress(Inst, IDLoc, Out);
1468     return false;
1469   }
1470 
1471   emitToStreamer(Out, Inst);
1472   return false;
1473 }
1474 
LLVMInitializeRISCVAsmParser()1475 extern "C" void LLVMInitializeRISCVAsmParser() {
1476   RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target());
1477   RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target());
1478 }
1479