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