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