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