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/RISCVBaseInfo.h"
11 #include "MCTargetDesc/RISCVMCExpr.h"
12 #include "MCTargetDesc/RISCVMCTargetDesc.h"
13 #include "llvm/ADT/STLExtras.h"
14 #include "llvm/ADT/StringSwitch.h"
15 #include "llvm/MC/MCContext.h"
16 #include "llvm/MC/MCExpr.h"
17 #include "llvm/MC/MCInst.h"
18 #include "llvm/MC/MCParser/MCAsmLexer.h"
19 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
20 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
21 #include "llvm/MC/MCRegisterInfo.h"
22 #include "llvm/MC/MCStreamer.h"
23 #include "llvm/MC/MCSubtargetInfo.h"
24 #include "llvm/Support/Casting.h"
25 #include "llvm/Support/TargetRegistry.h"
26 
27 using namespace llvm;
28 
29 namespace {
30 struct RISCVOperand;
31 
32 class RISCVAsmParser : public MCTargetAsmParser {
33   SMLoc getLoc() const { return getParser().getTok().getLoc(); }
34   bool isRV64() const { return getSTI().hasFeature(RISCV::Feature64Bit); }
35 
36   unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
37                                       unsigned Kind) override;
38 
39   bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo,
40                                   int Lower, int Upper, Twine Msg);
41 
42   bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
43                                OperandVector &Operands, MCStreamer &Out,
44                                uint64_t &ErrorInfo,
45                                bool MatchingInlineAsm) override;
46 
47   bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
48 
49   bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
50                         SMLoc NameLoc, OperandVector &Operands) override;
51 
52   bool ParseDirective(AsmToken DirectiveID) override;
53 
54 // Auto-generated instruction matching functions
55 #define GET_ASSEMBLER_HEADER
56 #include "RISCVGenAsmMatcher.inc"
57 
58   OperandMatchResultTy parseImmediate(OperandVector &Operands);
59   OperandMatchResultTy parseRegister(OperandVector &Operands,
60                                      bool AllowParens = false);
61   OperandMatchResultTy parseMemOpBaseReg(OperandVector &Operands);
62   OperandMatchResultTy parseOperandWithModifier(OperandVector &Operands);
63 
64   bool parseOperand(OperandVector &Operands);
65 
66 public:
67   enum RISCVMatchResultTy {
68     Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
69 #define GET_OPERAND_DIAGNOSTIC_TYPES
70 #include "RISCVGenAsmMatcher.inc"
71 #undef GET_OPERAND_DIAGNOSTIC_TYPES
72   };
73 
74   static bool classifySymbolRef(const MCExpr *Expr,
75                                 RISCVMCExpr::VariantKind &Kind,
76                                 int64_t &Addend);
77 
78   RISCVAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
79                  const MCInstrInfo &MII, const MCTargetOptions &Options)
80       : MCTargetAsmParser(Options, STI, MII) {
81     setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
82   }
83 };
84 
85 /// RISCVOperand - Instances of this class represent a parsed machine
86 /// instruction
87 struct RISCVOperand : public MCParsedAsmOperand {
88 
89   enum KindTy {
90     Token,
91     Register,
92     Immediate,
93   } Kind;
94 
95   bool IsRV64;
96 
97   struct RegOp {
98     unsigned RegNum;
99   };
100 
101   struct ImmOp {
102     const MCExpr *Val;
103   };
104 
105   SMLoc StartLoc, EndLoc;
106   union {
107     StringRef Tok;
108     RegOp Reg;
109     ImmOp Imm;
110   };
111 
112   RISCVOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
113 
114 public:
115   RISCVOperand(const RISCVOperand &o) : MCParsedAsmOperand() {
116     Kind = o.Kind;
117     IsRV64 = o.IsRV64;
118     StartLoc = o.StartLoc;
119     EndLoc = o.EndLoc;
120     switch (Kind) {
121     case Register:
122       Reg = o.Reg;
123       break;
124     case Immediate:
125       Imm = o.Imm;
126       break;
127     case Token:
128       Tok = o.Tok;
129       break;
130     }
131   }
132 
133   bool isToken() const override { return Kind == Token; }
134   bool isReg() const override { return Kind == Register; }
135   bool isImm() const override { return Kind == Immediate; }
136   bool isMem() const override { return false; }
137 
138   bool evaluateConstantImm(int64_t &Imm, RISCVMCExpr::VariantKind &VK) const {
139     const MCExpr *Val = getImm();
140     bool Ret = false;
141     if (auto *RE = dyn_cast<RISCVMCExpr>(Val)) {
142       Ret = RE->evaluateAsConstant(Imm);
143       VK = RE->getKind();
144     } else if (auto CE = dyn_cast<MCConstantExpr>(Val)) {
145       Ret = true;
146       VK = RISCVMCExpr::VK_RISCV_None;
147       Imm = CE->getValue();
148     }
149     return Ret;
150   }
151 
152   // True if operand is a symbol with no modifiers, or a constant with no
153   // modifiers and isShiftedInt<N-1, 1>(Op).
154   template <int N> bool isBareSimmNLsb0() const {
155     int64_t Imm;
156     RISCVMCExpr::VariantKind VK;
157     if (!isImm())
158       return false;
159     bool IsConstantImm = evaluateConstantImm(Imm, VK);
160     bool IsValid;
161     if (!IsConstantImm)
162       IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
163     else
164       IsValid = isShiftedInt<N - 1, 1>(Imm);
165     return IsValid && VK == RISCVMCExpr::VK_RISCV_None;
166   }
167 
168   // Predicate methods for AsmOperands defined in RISCVInstrInfo.td
169 
170   /// Return true if the operand is a valid for the fence instruction e.g.
171   /// ('iorw').
172   bool isFenceArg() const {
173     if (!isImm())
174       return false;
175     const MCExpr *Val = getImm();
176     auto *SVal = dyn_cast<MCSymbolRefExpr>(Val);
177     if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None)
178       return false;
179 
180     StringRef Str = SVal->getSymbol().getName();
181     // Letters must be unique, taken from 'iorw', and in ascending order. This
182     // holds as long as each individual character is one of 'iorw' and is
183     // greater than the previous character.
184     char Prev = '\0';
185     for (char c : Str) {
186       if (c != 'i' && c != 'o' && c != 'r' && c != 'w')
187         return false;
188       if (c <= Prev)
189         return false;
190       Prev = c;
191     }
192     return true;
193   }
194 
195   /// Return true if the operand is a valid floating point rounding mode.
196   bool isFRMArg() const {
197     if (!isImm())
198       return false;
199     const MCExpr *Val = getImm();
200     auto *SVal = dyn_cast<MCSymbolRefExpr>(Val);
201     if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None)
202       return false;
203 
204     StringRef Str = SVal->getSymbol().getName();
205 
206     return RISCVFPRndMode::stringToRoundingMode(Str) != RISCVFPRndMode::Invalid;
207   }
208 
209   bool isUImmLog2XLen() const {
210     int64_t Imm;
211     RISCVMCExpr::VariantKind VK;
212     if (!isImm())
213       return false;
214     if (!evaluateConstantImm(Imm, VK) || VK != RISCVMCExpr::VK_RISCV_None)
215       return false;
216     return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm);
217   }
218 
219   bool isUImmLog2XLenNonZero() const {
220     int64_t Imm;
221     RISCVMCExpr::VariantKind VK;
222     if (!isImm())
223       return false;
224     if (!evaluateConstantImm(Imm, VK) || VK != RISCVMCExpr::VK_RISCV_None)
225       return false;
226     if (Imm == 0)
227       return false;
228     return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm);
229   }
230 
231   bool isUImm5() const {
232     int64_t Imm;
233     RISCVMCExpr::VariantKind VK;
234     if (!isImm())
235       return false;
236     bool IsConstantImm = evaluateConstantImm(Imm, VK);
237     return IsConstantImm && isUInt<5>(Imm) && VK == RISCVMCExpr::VK_RISCV_None;
238   }
239 
240   bool isUImm5NonZero() const {
241     int64_t Imm;
242     RISCVMCExpr::VariantKind VK;
243     if (!isImm())
244       return false;
245     bool IsConstantImm = evaluateConstantImm(Imm, VK);
246     return IsConstantImm && isUInt<5>(Imm) && (Imm != 0) &&
247            VK == RISCVMCExpr::VK_RISCV_None;
248   }
249 
250   bool isSImm6() const {
251     RISCVMCExpr::VariantKind VK;
252     int64_t Imm;
253     bool IsValid;
254     bool IsConstantImm = evaluateConstantImm(Imm, VK);
255     if (!IsConstantImm)
256       IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
257     else
258       IsValid = isInt<6>(Imm);
259     return IsValid &&
260            (VK == RISCVMCExpr::VK_RISCV_None || VK == RISCVMCExpr::VK_RISCV_LO);
261   }
262 
263   bool isSImm6NonZero() const {
264     RISCVMCExpr::VariantKind VK;
265     int64_t Imm;
266     bool IsValid;
267     bool IsConstantImm = evaluateConstantImm(Imm, VK);
268     if (!IsConstantImm)
269       IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
270     else
271       IsValid = ((Imm != 0) && isInt<6>(Imm));
272     return IsValid &&
273            (VK == RISCVMCExpr::VK_RISCV_None || VK == RISCVMCExpr::VK_RISCV_LO);
274   }
275 
276   bool isUImm6NonZero() const {
277     int64_t Imm;
278     RISCVMCExpr::VariantKind VK;
279     bool IsConstantImm = evaluateConstantImm(Imm, VK);
280     return IsConstantImm && isUInt<6>(Imm) && (Imm != 0) &&
281            VK == RISCVMCExpr::VK_RISCV_None;
282   }
283 
284   bool isUImm7Lsb00() const {
285     int64_t Imm;
286     RISCVMCExpr::VariantKind VK;
287     bool IsConstantImm = evaluateConstantImm(Imm, VK);
288     return IsConstantImm && isShiftedUInt<5, 2>(Imm) &&
289            VK == RISCVMCExpr::VK_RISCV_None;
290   }
291 
292   bool isUImm8Lsb00() const {
293     int64_t Imm;
294     RISCVMCExpr::VariantKind VK;
295     bool IsConstantImm = evaluateConstantImm(Imm, VK);
296     return IsConstantImm && isShiftedUInt<6, 2>(Imm) &&
297            VK == RISCVMCExpr::VK_RISCV_None;
298   }
299 
300   bool isUImm8Lsb000() const {
301     int64_t Imm;
302     RISCVMCExpr::VariantKind VK;
303     bool IsConstantImm = evaluateConstantImm(Imm, VK);
304     return IsConstantImm && isShiftedUInt<5, 3>(Imm) &&
305            VK == RISCVMCExpr::VK_RISCV_None;
306   }
307 
308   bool isSImm9Lsb0() const { return isBareSimmNLsb0<9>(); }
309 
310   bool isUImm9Lsb000() const {
311     int64_t Imm;
312     RISCVMCExpr::VariantKind VK;
313     bool IsConstantImm = evaluateConstantImm(Imm, VK);
314     return IsConstantImm && isShiftedUInt<6, 3>(Imm) &&
315            VK == RISCVMCExpr::VK_RISCV_None;
316   }
317 
318   bool isUImm10Lsb00NonZero() const {
319     int64_t Imm;
320     RISCVMCExpr::VariantKind VK;
321     bool IsConstantImm = evaluateConstantImm(Imm, VK);
322     return IsConstantImm && isShiftedUInt<8, 2>(Imm) && (Imm != 0) &&
323            VK == RISCVMCExpr::VK_RISCV_None;
324   }
325 
326   bool isSImm12() const {
327     RISCVMCExpr::VariantKind VK;
328     int64_t Imm;
329     bool IsValid;
330     if (!isImm())
331       return false;
332     bool IsConstantImm = evaluateConstantImm(Imm, VK);
333     if (!IsConstantImm)
334       IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
335     else
336       IsValid = isInt<12>(Imm);
337     return IsValid && (VK == RISCVMCExpr::VK_RISCV_None ||
338                        VK == RISCVMCExpr::VK_RISCV_LO ||
339                        VK == RISCVMCExpr::VK_RISCV_PCREL_LO);
340   }
341 
342   bool isSImm12Lsb0() const { return isBareSimmNLsb0<12>(); }
343 
344   bool isUImm12() const {
345     int64_t Imm;
346     RISCVMCExpr::VariantKind VK;
347     if (!isImm())
348       return false;
349     bool IsConstantImm = evaluateConstantImm(Imm, VK);
350     return IsConstantImm && isUInt<12>(Imm) && VK == RISCVMCExpr::VK_RISCV_None;
351   }
352 
353   bool isSImm13Lsb0() const { return isBareSimmNLsb0<13>(); }
354 
355   bool isSImm10Lsb0000NonZero() const {
356     int64_t Imm;
357     RISCVMCExpr::VariantKind VK;
358     bool IsConstantImm = evaluateConstantImm(Imm, VK);
359     return IsConstantImm && (Imm != 0) && isShiftedInt<6, 4>(Imm) &&
360            VK == RISCVMCExpr::VK_RISCV_None;
361   }
362 
363   bool isUImm20() const {
364     RISCVMCExpr::VariantKind VK;
365     int64_t Imm;
366     bool IsValid;
367     if (!isImm())
368       return false;
369     bool IsConstantImm = evaluateConstantImm(Imm, VK);
370     if (!IsConstantImm)
371       IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
372     else
373       IsValid = isUInt<20>(Imm);
374     return IsValid && (VK == RISCVMCExpr::VK_RISCV_None ||
375                        VK == RISCVMCExpr::VK_RISCV_HI ||
376                        VK == RISCVMCExpr::VK_RISCV_PCREL_HI);
377   }
378 
379   bool isSImm21Lsb0() const { return isBareSimmNLsb0<21>(); }
380 
381   /// getStartLoc - Gets location of the first token of this operand
382   SMLoc getStartLoc() const override { return StartLoc; }
383   /// getEndLoc - Gets location of the last token of this operand
384   SMLoc getEndLoc() const override { return EndLoc; }
385   /// True if this operand is for an RV64 instruction
386   bool isRV64() const { return IsRV64; }
387 
388   unsigned getReg() const override {
389     assert(Kind == Register && "Invalid type access!");
390     return Reg.RegNum;
391   }
392 
393   const MCExpr *getImm() const {
394     assert(Kind == Immediate && "Invalid type access!");
395     return Imm.Val;
396   }
397 
398   StringRef getToken() const {
399     assert(Kind == Token && "Invalid type access!");
400     return Tok;
401   }
402 
403   void print(raw_ostream &OS) const override {
404     switch (Kind) {
405     case Immediate:
406       OS << *getImm();
407       break;
408     case Register:
409       OS << "<register x";
410       OS << getReg() << ">";
411       break;
412     case Token:
413       OS << "'" << getToken() << "'";
414       break;
415     }
416   }
417 
418   static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S,
419                                                    bool IsRV64) {
420     auto Op = make_unique<RISCVOperand>(Token);
421     Op->Tok = Str;
422     Op->StartLoc = S;
423     Op->EndLoc = S;
424     Op->IsRV64 = IsRV64;
425     return Op;
426   }
427 
428   static std::unique_ptr<RISCVOperand> createReg(unsigned RegNo, SMLoc S,
429                                                  SMLoc E, bool IsRV64) {
430     auto Op = make_unique<RISCVOperand>(Register);
431     Op->Reg.RegNum = RegNo;
432     Op->StartLoc = S;
433     Op->EndLoc = E;
434     Op->IsRV64 = IsRV64;
435     return Op;
436   }
437 
438   static std::unique_ptr<RISCVOperand> createImm(const MCExpr *Val, SMLoc S,
439                                                  SMLoc E, bool IsRV64) {
440     auto Op = make_unique<RISCVOperand>(Immediate);
441     Op->Imm.Val = Val;
442     Op->StartLoc = S;
443     Op->EndLoc = E;
444     Op->IsRV64 = IsRV64;
445     return Op;
446   }
447 
448   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
449     assert(Expr && "Expr shouldn't be null!");
450     int64_t Imm = 0;
451     bool IsConstant = false;
452     if (auto *RE = dyn_cast<RISCVMCExpr>(Expr)) {
453       IsConstant = RE->evaluateAsConstant(Imm);
454     } else if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) {
455       IsConstant = true;
456       Imm = CE->getValue();
457     }
458 
459     if (IsConstant)
460       Inst.addOperand(MCOperand::createImm(Imm));
461     else
462       Inst.addOperand(MCOperand::createExpr(Expr));
463   }
464 
465   // Used by the TableGen Code
466   void addRegOperands(MCInst &Inst, unsigned N) const {
467     assert(N == 1 && "Invalid number of operands!");
468     Inst.addOperand(MCOperand::createReg(getReg()));
469   }
470 
471   void addImmOperands(MCInst &Inst, unsigned N) const {
472     assert(N == 1 && "Invalid number of operands!");
473     addExpr(Inst, getImm());
474   }
475 
476   void addFenceArgOperands(MCInst &Inst, unsigned N) const {
477     assert(N == 1 && "Invalid number of operands!");
478     // isFenceArg has validated the operand, meaning this cast is safe
479     auto SE = cast<MCSymbolRefExpr>(getImm());
480 
481     unsigned Imm = 0;
482     for (char c : SE->getSymbol().getName()) {
483       switch (c) {
484         default: llvm_unreachable("FenceArg must contain only [iorw]");
485         case 'i': Imm |= RISCVFenceField::I; break;
486         case 'o': Imm |= RISCVFenceField::O; break;
487         case 'r': Imm |= RISCVFenceField::R; break;
488         case 'w': Imm |= RISCVFenceField::W; break;
489       }
490     }
491     Inst.addOperand(MCOperand::createImm(Imm));
492   }
493 
494   // Returns the rounding mode represented by this RISCVOperand. Should only
495   // be called after checking isFRMArg.
496   RISCVFPRndMode::RoundingMode getRoundingMode() const {
497     // isFRMArg has validated the operand, meaning this cast is safe.
498     auto SE = cast<MCSymbolRefExpr>(getImm());
499     RISCVFPRndMode::RoundingMode FRM =
500         RISCVFPRndMode::stringToRoundingMode(SE->getSymbol().getName());
501     assert(FRM != RISCVFPRndMode::Invalid && "Invalid rounding mode");
502     return FRM;
503   }
504 
505   void addFRMArgOperands(MCInst &Inst, unsigned N) const {
506     assert(N == 1 && "Invalid number of operands!");
507     Inst.addOperand(MCOperand::createImm(getRoundingMode()));
508   }
509 };
510 } // end anonymous namespace.
511 
512 #define GET_REGISTER_MATCHER
513 #define GET_MATCHER_IMPLEMENTATION
514 #include "RISCVGenAsmMatcher.inc"
515 
516 // Return the matching FPR64 register for the given FPR32.
517 // FIXME: Ideally this function could be removed in favour of using
518 // information from TableGen.
519 unsigned convertFPR32ToFPR64(unsigned Reg) {
520   switch (Reg) {
521     default:
522       llvm_unreachable("Not a recognised FPR32 register");
523     case RISCV::F0_32: return RISCV::F0_64;
524     case RISCV::F1_32: return RISCV::F1_64;
525     case RISCV::F2_32: return RISCV::F2_64;
526     case RISCV::F3_32: return RISCV::F3_64;
527     case RISCV::F4_32: return RISCV::F4_64;
528     case RISCV::F5_32: return RISCV::F5_64;
529     case RISCV::F6_32: return RISCV::F6_64;
530     case RISCV::F7_32: return RISCV::F7_64;
531     case RISCV::F8_32: return RISCV::F8_64;
532     case RISCV::F9_32: return RISCV::F9_64;
533     case RISCV::F10_32: return RISCV::F10_64;
534     case RISCV::F11_32: return RISCV::F11_64;
535     case RISCV::F12_32: return RISCV::F12_64;
536     case RISCV::F13_32: return RISCV::F13_64;
537     case RISCV::F14_32: return RISCV::F14_64;
538     case RISCV::F15_32: return RISCV::F15_64;
539     case RISCV::F16_32: return RISCV::F16_64;
540     case RISCV::F17_32: return RISCV::F17_64;
541     case RISCV::F18_32: return RISCV::F18_64;
542     case RISCV::F19_32: return RISCV::F19_64;
543     case RISCV::F20_32: return RISCV::F20_64;
544     case RISCV::F21_32: return RISCV::F21_64;
545     case RISCV::F22_32: return RISCV::F22_64;
546     case RISCV::F23_32: return RISCV::F23_64;
547     case RISCV::F24_32: return RISCV::F24_64;
548     case RISCV::F25_32: return RISCV::F25_64;
549     case RISCV::F26_32: return RISCV::F26_64;
550     case RISCV::F27_32: return RISCV::F27_64;
551     case RISCV::F28_32: return RISCV::F28_64;
552     case RISCV::F29_32: return RISCV::F29_64;
553     case RISCV::F30_32: return RISCV::F30_64;
554     case RISCV::F31_32: return RISCV::F31_64;
555   }
556 }
557 
558 unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
559                                                     unsigned Kind) {
560   RISCVOperand &Op = static_cast<RISCVOperand &>(AsmOp);
561   if (!Op.isReg())
562     return Match_InvalidOperand;
563 
564   unsigned Reg = Op.getReg();
565   bool IsRegFPR32 =
566       RISCVMCRegisterClasses[RISCV::FPR32RegClassID].contains(Reg);
567   bool IsRegFPR32C =
568       RISCVMCRegisterClasses[RISCV::FPR32CRegClassID].contains(Reg);
569 
570   // As the parser couldn't differentiate an FPR32 from an FPR64, coerce the
571   // register from FPR32 to FPR64 or FPR32C to FPR64C if necessary.
572   if ((IsRegFPR32 && Kind == MCK_FPR64) ||
573       (IsRegFPR32C && Kind == MCK_FPR64C)) {
574     Op.Reg.RegNum = convertFPR32ToFPR64(Reg);
575     return Match_Success;
576   }
577   return Match_InvalidOperand;
578 }
579 
580 bool RISCVAsmParser::generateImmOutOfRangeError(
581     OperandVector &Operands, uint64_t ErrorInfo, int Lower, int Upper,
582     Twine Msg = "immediate must be an integer in the range") {
583   SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
584   return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]");
585 }
586 
587 bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
588                                              OperandVector &Operands,
589                                              MCStreamer &Out,
590                                              uint64_t &ErrorInfo,
591                                              bool MatchingInlineAsm) {
592   MCInst Inst;
593 
594   switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
595   default:
596     break;
597   case Match_Success:
598     Inst.setLoc(IDLoc);
599     Out.EmitInstruction(Inst, getSTI());
600     return false;
601   case Match_MissingFeature:
602     return Error(IDLoc, "instruction use requires an option to be enabled");
603   case Match_MnemonicFail:
604     return Error(IDLoc, "unrecognized instruction mnemonic");
605   case Match_InvalidOperand: {
606     SMLoc ErrorLoc = IDLoc;
607     if (ErrorInfo != ~0U) {
608       if (ErrorInfo >= Operands.size())
609         return Error(ErrorLoc, "too few operands for instruction");
610 
611       ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
612       if (ErrorLoc == SMLoc())
613         ErrorLoc = IDLoc;
614     }
615     return Error(ErrorLoc, "invalid operand for instruction");
616   }
617   case Match_InvalidUImmLog2XLen:
618     if (isRV64())
619       return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
620     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
621   case Match_InvalidUImmLog2XLenNonZero:
622     if (isRV64())
623       return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1);
624     return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
625   case Match_InvalidUImm5:
626     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
627   case Match_InvalidSImm6:
628     return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5),
629                                       (1 << 5) - 1);
630   case Match_InvalidSImm6NonZero:
631     return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5),
632                                       (1 << 5) - 1,
633         "immediate must be non-zero in the range");
634   case Match_InvalidUImm6NonZero:
635     return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1);
636   case Match_InvalidUImm7Lsb00:
637     return generateImmOutOfRangeError(
638         Operands, ErrorInfo, 0, (1 << 7) - 4,
639         "immediate must be a multiple of 4 bytes in the range");
640   case Match_InvalidUImm8Lsb00:
641     return generateImmOutOfRangeError(
642         Operands, ErrorInfo, 0, (1 << 8) - 4,
643         "immediate must be a multiple of 4 bytes in the range");
644   case Match_InvalidUImm8Lsb000:
645     return generateImmOutOfRangeError(
646         Operands, ErrorInfo, 0, (1 << 8) - 8,
647         "immediate must be a multiple of 8 bytes in the range");
648   case Match_InvalidSImm9Lsb0:
649     return generateImmOutOfRangeError(
650         Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2,
651         "immediate must be a multiple of 2 bytes in the range");
652   case Match_InvalidUImm9Lsb000:
653     return generateImmOutOfRangeError(
654         Operands, ErrorInfo, 0, (1 << 9) - 8,
655         "immediate must be a multiple of 8 bytes in the range");
656   case Match_InvalidUImm10Lsb00NonZero:
657     return generateImmOutOfRangeError(
658         Operands, ErrorInfo, 4, (1 << 10) - 4,
659         "immediate must be a multiple of 4 bytes in the range");
660   case Match_InvalidSImm10Lsb0000NonZero:
661     return generateImmOutOfRangeError(
662         Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
663         "immediate must be a multiple of 16 bytes and non-zero in the range");
664   case Match_InvalidSImm12:
665     return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 11),
666                                       (1 << 11) - 1);
667   case Match_InvalidSImm12Lsb0:
668     return generateImmOutOfRangeError(
669         Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2,
670         "immediate must be a multiple of 2 bytes in the range");
671   case Match_InvalidUImm12:
672     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1);
673   case Match_InvalidSImm13Lsb0:
674     return generateImmOutOfRangeError(
675         Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2,
676         "immediate must be a multiple of 2 bytes in the range");
677   case Match_InvalidUImm20:
678     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1);
679   case Match_InvalidSImm21Lsb0:
680     return generateImmOutOfRangeError(
681         Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2,
682         "immediate must be a multiple of 2 bytes in the range");
683   case Match_InvalidFenceArg: {
684     SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
685     return Error(
686         ErrorLoc,
687         "operand must be formed of letters selected in-order from 'iorw'");
688   }
689   case Match_InvalidFRMArg: {
690     SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
691     return Error(
692         ErrorLoc,
693         "operand must be a valid floating point rounding mode mnemonic");
694   }
695   }
696 
697   llvm_unreachable("Unknown match type detected!");
698 }
699 
700 bool RISCVAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
701                                    SMLoc &EndLoc) {
702   const AsmToken &Tok = getParser().getTok();
703   StartLoc = Tok.getLoc();
704   EndLoc = Tok.getEndLoc();
705   RegNo = 0;
706   StringRef Name = getLexer().getTok().getIdentifier();
707 
708   if (!MatchRegisterName(Name) || !MatchRegisterAltName(Name)) {
709     getParser().Lex(); // Eat identifier token.
710     return false;
711   }
712 
713   return Error(StartLoc, "invalid register name");
714 }
715 
716 OperandMatchResultTy RISCVAsmParser::parseRegister(OperandVector &Operands,
717                                                    bool AllowParens) {
718   SMLoc FirstS = getLoc();
719   bool HadParens = false;
720   AsmToken Buf[2];
721 
722   // If this a parenthesised register name is allowed, parse it atomically
723   if (AllowParens && getLexer().is(AsmToken::LParen)) {
724     size_t ReadCount = getLexer().peekTokens(Buf);
725     if (ReadCount == 2 && Buf[1].getKind() == AsmToken::RParen) {
726       HadParens = true;
727       getParser().Lex(); // Eat '('
728     }
729   }
730 
731   switch (getLexer().getKind()) {
732   default:
733     return MatchOperand_NoMatch;
734   case AsmToken::Identifier:
735     StringRef Name = getLexer().getTok().getIdentifier();
736     unsigned RegNo = MatchRegisterName(Name);
737     if (RegNo == 0) {
738       RegNo = MatchRegisterAltName(Name);
739       if (RegNo == 0) {
740         if (HadParens)
741           getLexer().UnLex(Buf[0]);
742         return MatchOperand_NoMatch;
743       }
744     }
745     if (HadParens)
746       Operands.push_back(RISCVOperand::createToken("(", FirstS, isRV64()));
747     SMLoc S = getLoc();
748     SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
749     getLexer().Lex();
750     Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64()));
751   }
752 
753   if (HadParens) {
754     getParser().Lex(); // Eat ')'
755     Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64()));
756   }
757 
758   return MatchOperand_Success;
759 }
760 
761 OperandMatchResultTy RISCVAsmParser::parseImmediate(OperandVector &Operands) {
762   SMLoc S = getLoc();
763   SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
764   const MCExpr *Res;
765 
766   switch (getLexer().getKind()) {
767   default:
768     return MatchOperand_NoMatch;
769   case AsmToken::LParen:
770   case AsmToken::Minus:
771   case AsmToken::Plus:
772   case AsmToken::Integer:
773   case AsmToken::String:
774     if (getParser().parseExpression(Res))
775       return MatchOperand_ParseFail;
776     break;
777   case AsmToken::Identifier: {
778     StringRef Identifier;
779     if (getParser().parseIdentifier(Identifier))
780       return MatchOperand_ParseFail;
781     MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
782     Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
783     break;
784   }
785   case AsmToken::Percent:
786     return parseOperandWithModifier(Operands);
787   }
788 
789   Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
790   return MatchOperand_Success;
791 }
792 
793 OperandMatchResultTy
794 RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) {
795   SMLoc S = getLoc();
796   SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
797 
798   if (getLexer().getKind() != AsmToken::Percent) {
799     Error(getLoc(), "expected '%' for operand modifier");
800     return MatchOperand_ParseFail;
801   }
802 
803   getParser().Lex(); // Eat '%'
804 
805   if (getLexer().getKind() != AsmToken::Identifier) {
806     Error(getLoc(), "expected valid identifier for operand modifier");
807     return MatchOperand_ParseFail;
808   }
809   StringRef Identifier = getParser().getTok().getIdentifier();
810   RISCVMCExpr::VariantKind VK = RISCVMCExpr::getVariantKindForName(Identifier);
811   if (VK == RISCVMCExpr::VK_RISCV_Invalid) {
812     Error(getLoc(), "unrecognized operand modifier");
813     return MatchOperand_ParseFail;
814   }
815 
816   getParser().Lex(); // Eat the identifier
817   if (getLexer().getKind() != AsmToken::LParen) {
818     Error(getLoc(), "expected '('");
819     return MatchOperand_ParseFail;
820   }
821   getParser().Lex(); // Eat '('
822 
823   const MCExpr *SubExpr;
824   if (getParser().parseParenExpression(SubExpr, E)) {
825     return MatchOperand_ParseFail;
826   }
827 
828   const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, VK, getContext());
829   Operands.push_back(RISCVOperand::createImm(ModExpr, S, E, isRV64()));
830   return MatchOperand_Success;
831 }
832 
833 OperandMatchResultTy
834 RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) {
835   if (getLexer().isNot(AsmToken::LParen)) {
836     Error(getLoc(), "expected '('");
837     return MatchOperand_ParseFail;
838   }
839 
840   getParser().Lex(); // Eat '('
841   Operands.push_back(RISCVOperand::createToken("(", getLoc(), isRV64()));
842 
843   if (parseRegister(Operands) != MatchOperand_Success) {
844     Error(getLoc(), "expected register");
845     return MatchOperand_ParseFail;
846   }
847 
848   if (getLexer().isNot(AsmToken::RParen)) {
849     Error(getLoc(), "expected ')'");
850     return MatchOperand_ParseFail;
851   }
852 
853   getParser().Lex(); // Eat ')'
854   Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64()));
855 
856   return MatchOperand_Success;
857 }
858 
859 /// Looks at a token type and creates the relevant operand
860 /// from this information, adding to Operands.
861 /// If operand was parsed, returns false, else true.
862 bool RISCVAsmParser::parseOperand(OperandVector &Operands) {
863   // Attempt to parse token as register
864   if (parseRegister(Operands, true) == MatchOperand_Success)
865     return false;
866 
867   // Attempt to parse token as an immediate
868   if (parseImmediate(Operands) == MatchOperand_Success) {
869     // Parse memory base register if present
870     if (getLexer().is(AsmToken::LParen))
871       return parseMemOpBaseReg(Operands) != MatchOperand_Success;
872     return false;
873   }
874 
875   // Finally we have exhausted all options and must declare defeat.
876   Error(getLoc(), "unknown operand");
877   return true;
878 }
879 
880 bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info,
881                                       StringRef Name, SMLoc NameLoc,
882                                       OperandVector &Operands) {
883   // First operand is token for instruction
884   Operands.push_back(RISCVOperand::createToken(Name, NameLoc, isRV64()));
885 
886   // If there are no more operands, then finish
887   if (getLexer().is(AsmToken::EndOfStatement))
888     return false;
889 
890   // Parse first operand
891   if (parseOperand(Operands))
892     return true;
893 
894   // Parse until end of statement, consuming commas between operands
895   while (getLexer().is(AsmToken::Comma)) {
896     // Consume comma token
897     getLexer().Lex();
898 
899     // Parse next operand
900     if (parseOperand(Operands))
901       return true;
902   }
903 
904   if (getLexer().isNot(AsmToken::EndOfStatement)) {
905     SMLoc Loc = getLexer().getLoc();
906     getParser().eatToEndOfStatement();
907     return Error(Loc, "unexpected token");
908   }
909 
910   getParser().Lex(); // Consume the EndOfStatement.
911   return false;
912 }
913 
914 bool RISCVAsmParser::classifySymbolRef(const MCExpr *Expr,
915                                        RISCVMCExpr::VariantKind &Kind,
916                                        int64_t &Addend) {
917   Kind = RISCVMCExpr::VK_RISCV_None;
918   Addend = 0;
919 
920   if (const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) {
921     Kind = RE->getKind();
922     Expr = RE->getSubExpr();
923   }
924 
925   // It's a simple symbol reference or constant with no addend.
926   if (isa<MCConstantExpr>(Expr) || isa<MCSymbolRefExpr>(Expr))
927     return true;
928 
929   const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr);
930   if (!BE)
931     return false;
932 
933   if (!isa<MCSymbolRefExpr>(BE->getLHS()))
934     return false;
935 
936   if (BE->getOpcode() != MCBinaryExpr::Add &&
937       BE->getOpcode() != MCBinaryExpr::Sub)
938     return false;
939 
940   // We are able to support the subtraction of two symbol references
941   if (BE->getOpcode() == MCBinaryExpr::Sub &&
942       isa<MCSymbolRefExpr>(BE->getRHS()))
943     return true;
944 
945   // See if the addend is is a constant, otherwise there's more going
946   // on here than we can deal with.
947   auto AddendExpr = dyn_cast<MCConstantExpr>(BE->getRHS());
948   if (!AddendExpr)
949     return false;
950 
951   Addend = AddendExpr->getValue();
952   if (BE->getOpcode() == MCBinaryExpr::Sub)
953     Addend = -Addend;
954 
955   // It's some symbol reference + a constant addend
956   return Kind != RISCVMCExpr::VK_RISCV_Invalid;
957 }
958 
959 bool RISCVAsmParser::ParseDirective(AsmToken DirectiveID) { return true; }
960 
961 extern "C" void LLVMInitializeRISCVAsmParser() {
962   RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target());
963   RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target());
964 }
965