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