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 "RISCVInstrInfo.h"
14 #include "TargetInfo/RISCVTargetInfo.h"
15 #include "Utils/RISCVBaseInfo.h"
16 #include "Utils/RISCVMatInt.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/SmallBitVector.h"
19 #include "llvm/ADT/SmallString.h"
20 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/ADT/Statistic.h"
22 #include "llvm/ADT/StringSwitch.h"
23 #include "llvm/CodeGen/Register.h"
24 #include "llvm/MC/MCAssembler.h"
25 #include "llvm/MC/MCContext.h"
26 #include "llvm/MC/MCExpr.h"
27 #include "llvm/MC/MCInst.h"
28 #include "llvm/MC/MCInstBuilder.h"
29 #include "llvm/MC/MCObjectFileInfo.h"
30 #include "llvm/MC/MCParser/MCAsmLexer.h"
31 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
32 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
33 #include "llvm/MC/MCRegisterInfo.h"
34 #include "llvm/MC/MCStreamer.h"
35 #include "llvm/MC/MCSubtargetInfo.h"
36 #include "llvm/Support/Casting.h"
37 #include "llvm/Support/MathExtras.h"
38 #include "llvm/Support/RISCVAttributes.h"
39 #include "llvm/Support/TargetRegistry.h"
40 
41 #include <limits>
42 
43 using namespace llvm;
44 
45 #define DEBUG_TYPE "riscv-asm-parser"
46 
47 // Include the auto-generated portion of the compress emitter.
48 #define GEN_COMPRESS_INSTR
49 #include "RISCVGenCompressInstEmitter.inc"
50 
51 STATISTIC(RISCVNumInstrsCompressed,
52           "Number of RISC-V Compressed instructions emitted");
53 
54 namespace {
55 struct RISCVOperand;
56 
57 struct ParserOptionsSet {
58   bool IsPicEnabled;
59 };
60 
61 class RISCVAsmParser : public MCTargetAsmParser {
62   SmallVector<FeatureBitset, 4> FeatureBitStack;
63 
64   SmallVector<ParserOptionsSet, 4> ParserOptionsStack;
65   ParserOptionsSet ParserOptions;
66 
getLoc() const67   SMLoc getLoc() const { return getParser().getTok().getLoc(); }
isRV64() const68   bool isRV64() const { return getSTI().hasFeature(RISCV::Feature64Bit); }
isRV32E() const69   bool isRV32E() const { return getSTI().hasFeature(RISCV::FeatureRV32E); }
70 
getTargetStreamer()71   RISCVTargetStreamer &getTargetStreamer() {
72     MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
73     return static_cast<RISCVTargetStreamer &>(TS);
74   }
75 
76   unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
77                                       unsigned Kind) override;
78 
79   bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo,
80                                   int64_t Lower, int64_t Upper, Twine Msg);
81 
82   bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
83                                OperandVector &Operands, MCStreamer &Out,
84                                uint64_t &ErrorInfo,
85                                bool MatchingInlineAsm) override;
86 
87   bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
88   OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc,
89                                         SMLoc &EndLoc) override;
90 
91   bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
92                         SMLoc NameLoc, OperandVector &Operands) override;
93 
94   bool ParseDirective(AsmToken DirectiveID) override;
95 
96   // Helper to actually emit an instruction to the MCStreamer. Also, when
97   // possible, compression of the instruction is performed.
98   void emitToStreamer(MCStreamer &S, const MCInst &Inst);
99 
100   // Helper to emit a combination of LUI, ADDI(W), and SLLI instructions that
101   // synthesize the desired immedate value into the destination register.
102   void emitLoadImm(Register DestReg, int64_t Value, MCStreamer &Out);
103 
104   // Helper to emit a combination of AUIPC and SecondOpcode. Used to implement
105   // helpers such as emitLoadLocalAddress and emitLoadAddress.
106   void emitAuipcInstPair(MCOperand DestReg, MCOperand TmpReg,
107                          const MCExpr *Symbol, RISCVMCExpr::VariantKind VKHi,
108                          unsigned SecondOpcode, SMLoc IDLoc, MCStreamer &Out);
109 
110   // Helper to emit pseudo instruction "lla" used in PC-rel addressing.
111   void emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
112 
113   // Helper to emit pseudo instruction "la" used in GOT/PC-rel addressing.
114   void emitLoadAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
115 
116   // Helper to emit pseudo instruction "la.tls.ie" used in initial-exec TLS
117   // addressing.
118   void emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
119 
120   // Helper to emit pseudo instruction "la.tls.gd" used in global-dynamic TLS
121   // addressing.
122   void emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
123 
124   // Helper to emit pseudo load/store instruction with a symbol.
125   void emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode, SMLoc IDLoc,
126                            MCStreamer &Out, bool HasTmpReg);
127 
128   // Checks that a PseudoAddTPRel is using x4/tp in its second input operand.
129   // Enforcing this using a restricted register class for the second input
130   // operand of PseudoAddTPRel results in a poor diagnostic due to the fact
131   // 'add' is an overloaded mnemonic.
132   bool checkPseudoAddTPRel(MCInst &Inst, OperandVector &Operands);
133 
134   // Check instruction constraints.
135   bool validateInstruction(MCInst &Inst, OperandVector &Operands);
136 
137   /// Helper for processing MC instructions that have been successfully matched
138   /// by MatchAndEmitInstruction. Modifications to the emitted instructions,
139   /// like the expansion of pseudo instructions (e.g., "li"), can be performed
140   /// in this method.
141   bool processInstruction(MCInst &Inst, SMLoc IDLoc, OperandVector &Operands,
142                           MCStreamer &Out);
143 
144 // Auto-generated instruction matching functions
145 #define GET_ASSEMBLER_HEADER
146 #include "RISCVGenAsmMatcher.inc"
147 
148   OperandMatchResultTy parseCSRSystemRegister(OperandVector &Operands);
149   OperandMatchResultTy parseImmediate(OperandVector &Operands);
150   OperandMatchResultTy parseRegister(OperandVector &Operands,
151                                      bool AllowParens = false);
152   OperandMatchResultTy parseMemOpBaseReg(OperandVector &Operands);
153   OperandMatchResultTy parseAtomicMemOp(OperandVector &Operands);
154   OperandMatchResultTy parseOperandWithModifier(OperandVector &Operands);
155   OperandMatchResultTy parseBareSymbol(OperandVector &Operands);
156   OperandMatchResultTy parseCallSymbol(OperandVector &Operands);
157   OperandMatchResultTy parsePseudoJumpSymbol(OperandVector &Operands);
158   OperandMatchResultTy parseJALOffset(OperandVector &Operands);
159   OperandMatchResultTy parseVTypeI(OperandVector &Operands);
160   OperandMatchResultTy parseMaskReg(OperandVector &Operands);
161 
162   bool parseOperand(OperandVector &Operands, StringRef Mnemonic);
163 
164   bool parseDirectiveOption();
165   bool parseDirectiveAttribute();
166 
setFeatureBits(uint64_t Feature,StringRef FeatureString)167   void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
168     if (!(getSTI().getFeatureBits()[Feature])) {
169       MCSubtargetInfo &STI = copySTI();
170       setAvailableFeatures(
171           ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
172     }
173   }
174 
getFeatureBits(uint64_t Feature)175   bool getFeatureBits(uint64_t Feature) {
176     return getSTI().getFeatureBits()[Feature];
177   }
178 
clearFeatureBits(uint64_t Feature,StringRef FeatureString)179   void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
180     if (getSTI().getFeatureBits()[Feature]) {
181       MCSubtargetInfo &STI = copySTI();
182       setAvailableFeatures(
183           ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
184     }
185   }
186 
pushFeatureBits()187   void pushFeatureBits() {
188     assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
189            "These two stacks must be kept synchronized");
190     FeatureBitStack.push_back(getSTI().getFeatureBits());
191     ParserOptionsStack.push_back(ParserOptions);
192   }
193 
popFeatureBits()194   bool popFeatureBits() {
195     assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
196            "These two stacks must be kept synchronized");
197     if (FeatureBitStack.empty())
198       return true;
199 
200     FeatureBitset FeatureBits = FeatureBitStack.pop_back_val();
201     copySTI().setFeatureBits(FeatureBits);
202     setAvailableFeatures(ComputeAvailableFeatures(FeatureBits));
203 
204     ParserOptions = ParserOptionsStack.pop_back_val();
205 
206     return false;
207   }
208 
209   std::unique_ptr<RISCVOperand> defaultMaskRegOp() const;
210 
211 public:
212   enum RISCVMatchResultTy {
213     Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
214 #define GET_OPERAND_DIAGNOSTIC_TYPES
215 #include "RISCVGenAsmMatcher.inc"
216 #undef GET_OPERAND_DIAGNOSTIC_TYPES
217   };
218 
219   static bool classifySymbolRef(const MCExpr *Expr,
220                                 RISCVMCExpr::VariantKind &Kind,
221                                 int64_t &Addend);
222 
RISCVAsmParser(const MCSubtargetInfo & STI,MCAsmParser & Parser,const MCInstrInfo & MII,const MCTargetOptions & Options)223   RISCVAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
224                  const MCInstrInfo &MII, const MCTargetOptions &Options)
225       : MCTargetAsmParser(Options, STI, MII) {
226     Parser.addAliasForDirective(".half", ".2byte");
227     Parser.addAliasForDirective(".hword", ".2byte");
228     Parser.addAliasForDirective(".word", ".4byte");
229     Parser.addAliasForDirective(".dword", ".8byte");
230     setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
231 
232     auto ABIName = StringRef(Options.ABIName);
233     if (ABIName.endswith("f") &&
234         !getSTI().getFeatureBits()[RISCV::FeatureStdExtF]) {
235       errs() << "Hard-float 'f' ABI can't be used for a target that "
236                 "doesn't support the F instruction set extension (ignoring "
237                 "target-abi)\n";
238     } else if (ABIName.endswith("d") &&
239                !getSTI().getFeatureBits()[RISCV::FeatureStdExtD]) {
240       errs() << "Hard-float 'd' ABI can't be used for a target that "
241                 "doesn't support the D instruction set extension (ignoring "
242                 "target-abi)\n";
243     }
244 
245     const MCObjectFileInfo *MOFI = Parser.getContext().getObjectFileInfo();
246     ParserOptions.IsPicEnabled = MOFI->isPositionIndependent();
247   }
248 };
249 
250 /// RISCVOperand - Instances of this class represent a parsed machine
251 /// instruction
252 struct RISCVOperand : public MCParsedAsmOperand {
253 
254   enum class KindTy {
255     Token,
256     Register,
257     Immediate,
258     SystemRegister,
259     VType,
260   } Kind;
261 
262   bool IsRV64;
263 
264   struct RegOp {
265     Register RegNum;
266   };
267 
268   struct ImmOp {
269     const MCExpr *Val;
270   };
271 
272   struct SysRegOp {
273     const char *Data;
274     unsigned Length;
275     unsigned Encoding;
276     // FIXME: Add the Encoding parsed fields as needed for checks,
277     // e.g.: read/write or user/supervisor/machine privileges.
278   };
279 
280   enum class VSEW {
281     SEW_8 = 0,
282     SEW_16,
283     SEW_32,
284     SEW_64,
285     SEW_128,
286     SEW_256,
287     SEW_512,
288     SEW_1024,
289   };
290 
291   enum class VLMUL {
292     LMUL_1 = 0,
293     LMUL_2,
294     LMUL_4,
295     LMUL_8,
296     LMUL_F8 = 5,
297     LMUL_F4,
298     LMUL_F2
299   };
300 
301   struct VTypeOp {
302     VSEW Sew;
303     VLMUL Lmul;
304     bool TailAgnostic;
305     bool MaskedoffAgnostic;
306     unsigned Encoding;
307   };
308 
309   SMLoc StartLoc, EndLoc;
310   union {
311     StringRef Tok;
312     RegOp Reg;
313     ImmOp Imm;
314     struct SysRegOp SysReg;
315     struct VTypeOp VType;
316   };
317 
RISCVOperand__anon82e192670111::RISCVOperand318   RISCVOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
319 
320 public:
RISCVOperand__anon82e192670111::RISCVOperand321   RISCVOperand(const RISCVOperand &o) : MCParsedAsmOperand() {
322     Kind = o.Kind;
323     IsRV64 = o.IsRV64;
324     StartLoc = o.StartLoc;
325     EndLoc = o.EndLoc;
326     switch (Kind) {
327     case KindTy::Register:
328       Reg = o.Reg;
329       break;
330     case KindTy::Immediate:
331       Imm = o.Imm;
332       break;
333     case KindTy::Token:
334       Tok = o.Tok;
335       break;
336     case KindTy::SystemRegister:
337       SysReg = o.SysReg;
338       break;
339     case KindTy::VType:
340       VType = o.VType;
341       break;
342     }
343   }
344 
isToken__anon82e192670111::RISCVOperand345   bool isToken() const override { return Kind == KindTy::Token; }
isReg__anon82e192670111::RISCVOperand346   bool isReg() const override { return Kind == KindTy::Register; }
isV0Reg__anon82e192670111::RISCVOperand347   bool isV0Reg() const {
348     return Kind == KindTy::Register && Reg.RegNum == RISCV::V0;
349   }
isImm__anon82e192670111::RISCVOperand350   bool isImm() const override { return Kind == KindTy::Immediate; }
isMem__anon82e192670111::RISCVOperand351   bool isMem() const override { return false; }
isSystemRegister__anon82e192670111::RISCVOperand352   bool isSystemRegister() const { return Kind == KindTy::SystemRegister; }
isVType__anon82e192670111::RISCVOperand353   bool isVType() const { return Kind == KindTy::VType; }
354 
isGPR__anon82e192670111::RISCVOperand355   bool isGPR() const {
356     return Kind == KindTy::Register &&
357            RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(Reg.RegNum);
358   }
359 
evaluateConstantImm__anon82e192670111::RISCVOperand360   static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm,
361                                   RISCVMCExpr::VariantKind &VK) {
362     if (auto *RE = dyn_cast<RISCVMCExpr>(Expr)) {
363       VK = RE->getKind();
364       return RE->evaluateAsConstant(Imm);
365     }
366 
367     if (auto CE = dyn_cast<MCConstantExpr>(Expr)) {
368       VK = RISCVMCExpr::VK_RISCV_None;
369       Imm = CE->getValue();
370       return true;
371     }
372 
373     return false;
374   }
375 
376   // True if operand is a symbol with no modifiers, or a constant with no
377   // modifiers and isShiftedInt<N-1, 1>(Op).
isBareSimmNLsb0__anon82e192670111::RISCVOperand378   template <int N> bool isBareSimmNLsb0() const {
379     int64_t Imm;
380     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
381     if (!isImm())
382       return false;
383     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
384     bool IsValid;
385     if (!IsConstantImm)
386       IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
387     else
388       IsValid = isShiftedInt<N - 1, 1>(Imm);
389     return IsValid && VK == RISCVMCExpr::VK_RISCV_None;
390   }
391 
392   // Predicate methods for AsmOperands defined in RISCVInstrInfo.td
393 
isBareSymbol__anon82e192670111::RISCVOperand394   bool isBareSymbol() const {
395     int64_t Imm;
396     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
397     // Must be of 'immediate' type but not a constant.
398     if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
399       return false;
400     return RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm) &&
401            VK == RISCVMCExpr::VK_RISCV_None;
402   }
403 
isCallSymbol__anon82e192670111::RISCVOperand404   bool isCallSymbol() const {
405     int64_t Imm;
406     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
407     // Must be of 'immediate' type but not a constant.
408     if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
409       return false;
410     return RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm) &&
411            (VK == RISCVMCExpr::VK_RISCV_CALL ||
412             VK == RISCVMCExpr::VK_RISCV_CALL_PLT);
413   }
414 
isPseudoJumpSymbol__anon82e192670111::RISCVOperand415   bool isPseudoJumpSymbol() const {
416     int64_t Imm;
417     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
418     // Must be of 'immediate' type but not a constant.
419     if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
420       return false;
421     return RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm) &&
422            VK == RISCVMCExpr::VK_RISCV_CALL;
423   }
424 
isTPRelAddSymbol__anon82e192670111::RISCVOperand425   bool isTPRelAddSymbol() const {
426     int64_t Imm;
427     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
428     // Must be of 'immediate' type but not a constant.
429     if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
430       return false;
431     return RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm) &&
432            VK == RISCVMCExpr::VK_RISCV_TPREL_ADD;
433   }
434 
isCSRSystemRegister__anon82e192670111::RISCVOperand435   bool isCSRSystemRegister() const { return isSystemRegister(); }
436 
isVTypeI__anon82e192670111::RISCVOperand437   bool isVTypeI() const { return isVType(); }
438 
439   /// Return true if the operand is a valid for the fence instruction e.g.
440   /// ('iorw').
isFenceArg__anon82e192670111::RISCVOperand441   bool isFenceArg() const {
442     if (!isImm())
443       return false;
444     const MCExpr *Val = getImm();
445     auto *SVal = dyn_cast<MCSymbolRefExpr>(Val);
446     if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None)
447       return false;
448 
449     StringRef Str = SVal->getSymbol().getName();
450     // Letters must be unique, taken from 'iorw', and in ascending order. This
451     // holds as long as each individual character is one of 'iorw' and is
452     // greater than the previous character.
453     char Prev = '\0';
454     for (char c : Str) {
455       if (c != 'i' && c != 'o' && c != 'r' && c != 'w')
456         return false;
457       if (c <= Prev)
458         return false;
459       Prev = c;
460     }
461     return true;
462   }
463 
464   /// Return true if the operand is a valid floating point rounding mode.
isFRMArg__anon82e192670111::RISCVOperand465   bool isFRMArg() const {
466     if (!isImm())
467       return false;
468     const MCExpr *Val = getImm();
469     auto *SVal = dyn_cast<MCSymbolRefExpr>(Val);
470     if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None)
471       return false;
472 
473     StringRef Str = SVal->getSymbol().getName();
474 
475     return RISCVFPRndMode::stringToRoundingMode(Str) != RISCVFPRndMode::Invalid;
476   }
477 
isImmXLenLI__anon82e192670111::RISCVOperand478   bool isImmXLenLI() const {
479     int64_t Imm;
480     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
481     if (!isImm())
482       return false;
483     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
484     if (VK == RISCVMCExpr::VK_RISCV_LO || VK == RISCVMCExpr::VK_RISCV_PCREL_LO)
485       return true;
486     // Given only Imm, ensuring that the actually specified constant is either
487     // a signed or unsigned 64-bit number is unfortunately impossible.
488     return IsConstantImm && VK == RISCVMCExpr::VK_RISCV_None &&
489            (isRV64() || (isInt<32>(Imm) || isUInt<32>(Imm)));
490   }
491 
isUImmLog2XLen__anon82e192670111::RISCVOperand492   bool isUImmLog2XLen() const {
493     int64_t Imm;
494     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
495     if (!isImm())
496       return false;
497     if (!evaluateConstantImm(getImm(), Imm, VK) ||
498         VK != RISCVMCExpr::VK_RISCV_None)
499       return false;
500     return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm);
501   }
502 
isUImmLog2XLenNonZero__anon82e192670111::RISCVOperand503   bool isUImmLog2XLenNonZero() const {
504     int64_t Imm;
505     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
506     if (!isImm())
507       return false;
508     if (!evaluateConstantImm(getImm(), Imm, VK) ||
509         VK != RISCVMCExpr::VK_RISCV_None)
510       return false;
511     if (Imm == 0)
512       return false;
513     return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm);
514   }
515 
isUImmLog2XLenHalf__anon82e192670111::RISCVOperand516   bool isUImmLog2XLenHalf() const {
517     int64_t Imm;
518     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
519     if (!isImm())
520       return false;
521     if (!evaluateConstantImm(getImm(), Imm, VK) ||
522         VK != RISCVMCExpr::VK_RISCV_None)
523       return false;
524     return (isRV64() && isUInt<5>(Imm)) || isUInt<4>(Imm);
525   }
526 
isUImm5__anon82e192670111::RISCVOperand527   bool isUImm5() const {
528     int64_t Imm;
529     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
530     if (!isImm())
531       return false;
532     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
533     return IsConstantImm && isUInt<5>(Imm) && VK == RISCVMCExpr::VK_RISCV_None;
534   }
535 
isUImm5NonZero__anon82e192670111::RISCVOperand536   bool isUImm5NonZero() const {
537     int64_t Imm;
538     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
539     if (!isImm())
540       return false;
541     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
542     return IsConstantImm && isUInt<5>(Imm) && (Imm != 0) &&
543            VK == RISCVMCExpr::VK_RISCV_None;
544   }
545 
isSImm5__anon82e192670111::RISCVOperand546   bool isSImm5() const {
547     if (!isImm())
548       return false;
549     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
550     int64_t Imm;
551     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
552     return IsConstantImm && isInt<5>(Imm) && VK == RISCVMCExpr::VK_RISCV_None;
553   }
554 
isSImm6__anon82e192670111::RISCVOperand555   bool isSImm6() const {
556     if (!isImm())
557       return false;
558     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
559     int64_t Imm;
560     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
561     return IsConstantImm && isInt<6>(Imm) &&
562 	    VK == RISCVMCExpr::VK_RISCV_None;
563   }
564 
isSImm6NonZero__anon82e192670111::RISCVOperand565   bool isSImm6NonZero() const {
566     if (!isImm())
567       return false;
568     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
569     int64_t Imm;
570     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
571     return IsConstantImm && isInt<6>(Imm) && (Imm != 0) &&
572            VK == RISCVMCExpr::VK_RISCV_None;
573   }
574 
isCLUIImm__anon82e192670111::RISCVOperand575   bool isCLUIImm() const {
576     if (!isImm())
577       return false;
578     int64_t Imm;
579     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
580     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
581     return IsConstantImm && (Imm != 0) &&
582            (isUInt<5>(Imm) || (Imm >= 0xfffe0 && Imm <= 0xfffff)) &&
583            VK == RISCVMCExpr::VK_RISCV_None;
584   }
585 
isUImm7Lsb00__anon82e192670111::RISCVOperand586   bool isUImm7Lsb00() const {
587     if (!isImm())
588       return false;
589     int64_t Imm;
590     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
591     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
592     return IsConstantImm && isShiftedUInt<5, 2>(Imm) &&
593            VK == RISCVMCExpr::VK_RISCV_None;
594   }
595 
isUImm8Lsb00__anon82e192670111::RISCVOperand596   bool isUImm8Lsb00() const {
597     if (!isImm())
598       return false;
599     int64_t Imm;
600     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
601     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
602     return IsConstantImm && isShiftedUInt<6, 2>(Imm) &&
603            VK == RISCVMCExpr::VK_RISCV_None;
604   }
605 
isUImm8Lsb000__anon82e192670111::RISCVOperand606   bool isUImm8Lsb000() const {
607     if (!isImm())
608       return false;
609     int64_t Imm;
610     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
611     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
612     return IsConstantImm && isShiftedUInt<5, 3>(Imm) &&
613            VK == RISCVMCExpr::VK_RISCV_None;
614   }
615 
isSImm9Lsb0__anon82e192670111::RISCVOperand616   bool isSImm9Lsb0() const { return isBareSimmNLsb0<9>(); }
617 
isUImm9Lsb000__anon82e192670111::RISCVOperand618   bool isUImm9Lsb000() const {
619     if (!isImm())
620       return false;
621     int64_t Imm;
622     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
623     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
624     return IsConstantImm && isShiftedUInt<6, 3>(Imm) &&
625            VK == RISCVMCExpr::VK_RISCV_None;
626   }
627 
isUImm10Lsb00NonZero__anon82e192670111::RISCVOperand628   bool isUImm10Lsb00NonZero() const {
629     if (!isImm())
630       return false;
631     int64_t Imm;
632     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
633     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
634     return IsConstantImm && isShiftedUInt<8, 2>(Imm) && (Imm != 0) &&
635            VK == RISCVMCExpr::VK_RISCV_None;
636   }
637 
isSImm12__anon82e192670111::RISCVOperand638   bool isSImm12() const {
639     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
640     int64_t Imm;
641     bool IsValid;
642     if (!isImm())
643       return false;
644     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
645     if (!IsConstantImm)
646       IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
647     else
648       IsValid = isInt<12>(Imm);
649     return IsValid && ((IsConstantImm && VK == RISCVMCExpr::VK_RISCV_None) ||
650                        VK == RISCVMCExpr::VK_RISCV_LO ||
651                        VK == RISCVMCExpr::VK_RISCV_PCREL_LO ||
652                        VK == RISCVMCExpr::VK_RISCV_TPREL_LO);
653   }
654 
isSImm12Lsb0__anon82e192670111::RISCVOperand655   bool isSImm12Lsb0() const { return isBareSimmNLsb0<12>(); }
656 
isSImm13Lsb0__anon82e192670111::RISCVOperand657   bool isSImm13Lsb0() const { return isBareSimmNLsb0<13>(); }
658 
isSImm10Lsb0000NonZero__anon82e192670111::RISCVOperand659   bool isSImm10Lsb0000NonZero() const {
660     if (!isImm())
661       return false;
662     int64_t Imm;
663     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
664     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
665     return IsConstantImm && (Imm != 0) && isShiftedInt<6, 4>(Imm) &&
666            VK == RISCVMCExpr::VK_RISCV_None;
667   }
668 
isUImm20LUI__anon82e192670111::RISCVOperand669   bool isUImm20LUI() const {
670     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
671     int64_t Imm;
672     bool IsValid;
673     if (!isImm())
674       return false;
675     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
676     if (!IsConstantImm) {
677       IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
678       return IsValid && (VK == RISCVMCExpr::VK_RISCV_HI ||
679                          VK == RISCVMCExpr::VK_RISCV_TPREL_HI);
680     } else {
681       return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None ||
682                                  VK == RISCVMCExpr::VK_RISCV_HI ||
683                                  VK == RISCVMCExpr::VK_RISCV_TPREL_HI);
684     }
685   }
686 
isUImm20AUIPC__anon82e192670111::RISCVOperand687   bool isUImm20AUIPC() const {
688     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
689     int64_t Imm;
690     bool IsValid;
691     if (!isImm())
692       return false;
693     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
694     if (!IsConstantImm) {
695       IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
696       return IsValid && (VK == RISCVMCExpr::VK_RISCV_PCREL_HI ||
697                          VK == RISCVMCExpr::VK_RISCV_GOT_HI ||
698                          VK == RISCVMCExpr::VK_RISCV_TLS_GOT_HI ||
699                          VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI);
700     } else {
701       return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None ||
702                                  VK == RISCVMCExpr::VK_RISCV_PCREL_HI ||
703                                  VK == RISCVMCExpr::VK_RISCV_GOT_HI ||
704                                  VK == RISCVMCExpr::VK_RISCV_TLS_GOT_HI ||
705                                  VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI);
706     }
707   }
708 
isSImm21Lsb0JAL__anon82e192670111::RISCVOperand709   bool isSImm21Lsb0JAL() const { return isBareSimmNLsb0<21>(); }
710 
isImmZero__anon82e192670111::RISCVOperand711   bool isImmZero() const {
712     if (!isImm())
713       return false;
714     int64_t Imm;
715     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
716     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
717     return IsConstantImm && (Imm == 0) && VK == RISCVMCExpr::VK_RISCV_None;
718   }
719 
isSImm5Plus1__anon82e192670111::RISCVOperand720   bool isSImm5Plus1() const {
721     if (!isImm())
722       return false;
723     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
724     int64_t Imm;
725     bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
726     return IsConstantImm && isInt<5>(Imm - 1) &&
727            VK == RISCVMCExpr::VK_RISCV_None;
728   }
729 
730   /// getStartLoc - Gets location of the first token of this operand
getStartLoc__anon82e192670111::RISCVOperand731   SMLoc getStartLoc() const override { return StartLoc; }
732   /// getEndLoc - Gets location of the last token of this operand
getEndLoc__anon82e192670111::RISCVOperand733   SMLoc getEndLoc() const override { return EndLoc; }
734   /// True if this operand is for an RV64 instruction
isRV64__anon82e192670111::RISCVOperand735   bool isRV64() const { return IsRV64; }
736 
getReg__anon82e192670111::RISCVOperand737   unsigned getReg() const override {
738     assert(Kind == KindTy::Register && "Invalid type access!");
739     return Reg.RegNum.id();
740   }
741 
getSysReg__anon82e192670111::RISCVOperand742   StringRef getSysReg() const {
743     assert(Kind == KindTy::SystemRegister && "Invalid access!");
744     return StringRef(SysReg.Data, SysReg.Length);
745   }
746 
getImm__anon82e192670111::RISCVOperand747   const MCExpr *getImm() const {
748     assert(Kind == KindTy::Immediate && "Invalid type access!");
749     return Imm.Val;
750   }
751 
getToken__anon82e192670111::RISCVOperand752   StringRef getToken() const {
753     assert(Kind == KindTy::Token && "Invalid type access!");
754     return Tok;
755   }
756 
getSEWStr__anon82e192670111::RISCVOperand757   static StringRef getSEWStr(VSEW Sew) {
758     switch (Sew) {
759     case VSEW::SEW_8:
760       return "e8";
761     case VSEW::SEW_16:
762       return "e16";
763     case VSEW::SEW_32:
764       return "e32";
765     case VSEW::SEW_64:
766       return "e64";
767     case VSEW::SEW_128:
768       return "e128";
769     case VSEW::SEW_256:
770       return "e256";
771     case VSEW::SEW_512:
772       return "e512";
773     case VSEW::SEW_1024:
774       return "e1024";
775     }
776     llvm_unreachable("Unknown SEW.");
777   }
778 
getLMULStr__anon82e192670111::RISCVOperand779   static StringRef getLMULStr(VLMUL Lmul) {
780     switch (Lmul) {
781     case VLMUL::LMUL_1:
782       return "m1";
783     case VLMUL::LMUL_2:
784       return "m2";
785     case VLMUL::LMUL_4:
786       return "m4";
787     case VLMUL::LMUL_8:
788       return "m8";
789     case VLMUL::LMUL_F2:
790       return "mf2";
791     case VLMUL::LMUL_F4:
792       return "mf4";
793     case VLMUL::LMUL_F8:
794       return "mf8";
795     }
796     llvm_unreachable("Unknown LMUL.");
797   }
798 
getVType__anon82e192670111::RISCVOperand799   StringRef getVType(SmallString<32> &Buf) const {
800     assert(Kind == KindTy::VType && "Invalid access!");
801     Buf.append(getSEWStr(VType.Sew));
802     Buf.append(",");
803     Buf.append(getLMULStr(VType.Lmul));
804 
805     return Buf.str();
806   }
807 
print__anon82e192670111::RISCVOperand808   void print(raw_ostream &OS) const override {
809     switch (Kind) {
810     case KindTy::Immediate:
811       OS << *getImm();
812       break;
813     case KindTy::Register:
814       OS << "<register x";
815       OS << getReg() << ">";
816       break;
817     case KindTy::Token:
818       OS << "'" << getToken() << "'";
819       break;
820     case KindTy::SystemRegister:
821       OS << "<sysreg: " << getSysReg() << '>';
822       break;
823     case KindTy::VType:
824       SmallString<32> VTypeBuf;
825       OS << "<vtype: " << getVType(VTypeBuf) << '>';
826       break;
827     }
828   }
829 
createToken__anon82e192670111::RISCVOperand830   static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S,
831                                                    bool IsRV64) {
832     auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
833     Op->Tok = Str;
834     Op->StartLoc = S;
835     Op->EndLoc = S;
836     Op->IsRV64 = IsRV64;
837     return Op;
838   }
839 
createReg__anon82e192670111::RISCVOperand840   static std::unique_ptr<RISCVOperand> createReg(unsigned RegNo, SMLoc S,
841                                                  SMLoc E, bool IsRV64) {
842     auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
843     Op->Reg.RegNum = RegNo;
844     Op->StartLoc = S;
845     Op->EndLoc = E;
846     Op->IsRV64 = IsRV64;
847     return Op;
848   }
849 
createImm__anon82e192670111::RISCVOperand850   static std::unique_ptr<RISCVOperand> createImm(const MCExpr *Val, SMLoc S,
851                                                  SMLoc E, bool IsRV64) {
852     auto Op = std::make_unique<RISCVOperand>(KindTy::Immediate);
853     Op->Imm.Val = Val;
854     Op->StartLoc = S;
855     Op->EndLoc = E;
856     Op->IsRV64 = IsRV64;
857     return Op;
858   }
859 
860   static std::unique_ptr<RISCVOperand>
createSysReg__anon82e192670111::RISCVOperand861   createSysReg(StringRef Str, SMLoc S, unsigned Encoding, bool IsRV64) {
862     auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
863     Op->SysReg.Data = Str.data();
864     Op->SysReg.Length = Str.size();
865     Op->SysReg.Encoding = Encoding;
866     Op->StartLoc = S;
867     Op->IsRV64 = IsRV64;
868     return Op;
869   }
870 
871   static std::unique_ptr<RISCVOperand>
createVType__anon82e192670111::RISCVOperand872   createVType(APInt Sew, APInt Lmul, bool Fractional, bool TailAgnostic,
873               bool MaskedoffAgnostic, SMLoc S, bool IsRV64) {
874     auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
875     Sew.ashrInPlace(3);
876     unsigned SewLog2 = Sew.logBase2();
877     unsigned LmulLog2 = Lmul.logBase2();
878     Op->VType.Sew = static_cast<VSEW>(SewLog2);
879     if (Fractional) {
880       unsigned Flmul = 8 - LmulLog2;
881       Op->VType.Lmul = static_cast<VLMUL>(Flmul);
882       Op->VType.Encoding =
883           ((Flmul & 0x4) << 3) | ((SewLog2 & 0x7) << 2) | (Flmul & 0x3);
884     } else {
885       Op->VType.Lmul = static_cast<VLMUL>(LmulLog2);
886       Op->VType.Encoding = (SewLog2 << 2) | LmulLog2;
887     }
888     if (TailAgnostic) {
889       Op->VType.Encoding |= 0x40;
890     }
891     if (MaskedoffAgnostic) {
892       Op->VType.Encoding |= 0x80;
893     }
894     Op->VType.TailAgnostic = TailAgnostic;
895     Op->VType.MaskedoffAgnostic = MaskedoffAgnostic;
896     Op->StartLoc = S;
897     Op->IsRV64 = IsRV64;
898     return Op;
899   }
900 
addExpr__anon82e192670111::RISCVOperand901   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
902     assert(Expr && "Expr shouldn't be null!");
903     int64_t Imm = 0;
904     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
905     bool IsConstant = evaluateConstantImm(Expr, Imm, VK);
906 
907     if (IsConstant)
908       Inst.addOperand(MCOperand::createImm(Imm));
909     else
910       Inst.addOperand(MCOperand::createExpr(Expr));
911   }
912 
913   // Used by the TableGen Code
addRegOperands__anon82e192670111::RISCVOperand914   void addRegOperands(MCInst &Inst, unsigned N) const {
915     assert(N == 1 && "Invalid number of operands!");
916     Inst.addOperand(MCOperand::createReg(getReg()));
917   }
918 
addImmOperands__anon82e192670111::RISCVOperand919   void addImmOperands(MCInst &Inst, unsigned N) const {
920     assert(N == 1 && "Invalid number of operands!");
921     addExpr(Inst, getImm());
922   }
923 
addSImm5Plus1Operands__anon82e192670111::RISCVOperand924   void addSImm5Plus1Operands(MCInst &Inst, unsigned N) const {
925     assert(N == 1 && "Invalid number of operands!");
926     int64_t Imm = 0;
927     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
928     bool IsConstant = evaluateConstantImm(getImm(), Imm, VK);
929     assert(IsConstant && "Expect constant value!");
930     (void)IsConstant;
931     Inst.addOperand(MCOperand::createImm(Imm - 1));
932   }
933 
addFenceArgOperands__anon82e192670111::RISCVOperand934   void addFenceArgOperands(MCInst &Inst, unsigned N) const {
935     assert(N == 1 && "Invalid number of operands!");
936     // isFenceArg has validated the operand, meaning this cast is safe
937     auto SE = cast<MCSymbolRefExpr>(getImm());
938 
939     unsigned Imm = 0;
940     for (char c : SE->getSymbol().getName()) {
941       switch (c) {
942       default:
943         llvm_unreachable("FenceArg must contain only [iorw]");
944       case 'i': Imm |= RISCVFenceField::I; break;
945       case 'o': Imm |= RISCVFenceField::O; break;
946       case 'r': Imm |= RISCVFenceField::R; break;
947       case 'w': Imm |= RISCVFenceField::W; break;
948       }
949     }
950     Inst.addOperand(MCOperand::createImm(Imm));
951   }
952 
addCSRSystemRegisterOperands__anon82e192670111::RISCVOperand953   void addCSRSystemRegisterOperands(MCInst &Inst, unsigned N) const {
954     assert(N == 1 && "Invalid number of operands!");
955     Inst.addOperand(MCOperand::createImm(SysReg.Encoding));
956   }
957 
addVTypeIOperands__anon82e192670111::RISCVOperand958   void addVTypeIOperands(MCInst &Inst, unsigned N) const {
959     assert(N == 1 && "Invalid number of operands!");
960     Inst.addOperand(MCOperand::createImm(VType.Encoding));
961   }
962 
963   // Returns the rounding mode represented by this RISCVOperand. Should only
964   // be called after checking isFRMArg.
getRoundingMode__anon82e192670111::RISCVOperand965   RISCVFPRndMode::RoundingMode getRoundingMode() const {
966     // isFRMArg has validated the operand, meaning this cast is safe.
967     auto SE = cast<MCSymbolRefExpr>(getImm());
968     RISCVFPRndMode::RoundingMode FRM =
969         RISCVFPRndMode::stringToRoundingMode(SE->getSymbol().getName());
970     assert(FRM != RISCVFPRndMode::Invalid && "Invalid rounding mode");
971     return FRM;
972   }
973 
addFRMArgOperands__anon82e192670111::RISCVOperand974   void addFRMArgOperands(MCInst &Inst, unsigned N) const {
975     assert(N == 1 && "Invalid number of operands!");
976     Inst.addOperand(MCOperand::createImm(getRoundingMode()));
977   }
978 };
979 } // end anonymous namespace.
980 
981 #define GET_REGISTER_MATCHER
982 #define GET_SUBTARGET_FEATURE_NAME
983 #define GET_MATCHER_IMPLEMENTATION
984 #define GET_MNEMONIC_SPELL_CHECKER
985 #include "RISCVGenAsmMatcher.inc"
986 
convertFPR64ToFPR32(Register Reg)987 static Register convertFPR64ToFPR32(Register Reg) {
988   assert(Reg >= RISCV::F0_D && Reg <= RISCV::F31_D && "Invalid register");
989   return Reg - RISCV::F0_D + RISCV::F0_F;
990 }
991 
validateTargetOperandClass(MCParsedAsmOperand & AsmOp,unsigned Kind)992 unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
993                                                     unsigned Kind) {
994   RISCVOperand &Op = static_cast<RISCVOperand &>(AsmOp);
995   if (!Op.isReg())
996     return Match_InvalidOperand;
997 
998   Register Reg = Op.getReg();
999   bool IsRegFPR64 =
1000       RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(Reg);
1001   bool IsRegFPR64C =
1002       RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(Reg);
1003 
1004   // As the parser couldn't differentiate an FPR32 from an FPR64, coerce the
1005   // register from FPR64 to FPR32 or FPR64C to FPR32C if necessary.
1006   if ((IsRegFPR64 && Kind == MCK_FPR32) ||
1007       (IsRegFPR64C && Kind == MCK_FPR32C)) {
1008     Op.Reg.RegNum = convertFPR64ToFPR32(Reg);
1009     return Match_Success;
1010   }
1011   return Match_InvalidOperand;
1012 }
1013 
generateImmOutOfRangeError(OperandVector & Operands,uint64_t ErrorInfo,int64_t Lower,int64_t Upper,Twine Msg="immediate must be an integer in the range")1014 bool RISCVAsmParser::generateImmOutOfRangeError(
1015     OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper,
1016     Twine Msg = "immediate must be an integer in the range") {
1017   SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1018   return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]");
1019 }
1020 
1021 static std::string RISCVMnemonicSpellCheck(StringRef S,
1022                                           const FeatureBitset &FBS,
1023                                           unsigned VariantID = 0);
1024 
MatchAndEmitInstruction(SMLoc IDLoc,unsigned & Opcode,OperandVector & Operands,MCStreamer & Out,uint64_t & ErrorInfo,bool MatchingInlineAsm)1025 bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1026                                              OperandVector &Operands,
1027                                              MCStreamer &Out,
1028                                              uint64_t &ErrorInfo,
1029                                              bool MatchingInlineAsm) {
1030   MCInst Inst;
1031   FeatureBitset MissingFeatures;
1032 
1033   auto Result =
1034     MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
1035                          MatchingInlineAsm);
1036   switch (Result) {
1037   default:
1038     break;
1039   case Match_Success:
1040     if (validateInstruction(Inst, Operands))
1041       return true;
1042     return processInstruction(Inst, IDLoc, Operands, Out);
1043   case Match_MissingFeature: {
1044     assert(MissingFeatures.any() && "Unknown missing features!");
1045     bool FirstFeature = true;
1046     std::string Msg = "instruction requires the following:";
1047     for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) {
1048       if (MissingFeatures[i]) {
1049         Msg += FirstFeature ? " " : ", ";
1050         Msg += getSubtargetFeatureName(i);
1051         FirstFeature = false;
1052       }
1053     }
1054     return Error(IDLoc, Msg);
1055   }
1056   case Match_MnemonicFail: {
1057     FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1058     std::string Suggestion = RISCVMnemonicSpellCheck(
1059       ((RISCVOperand &)*Operands[0]).getToken(), FBS);
1060     return Error(IDLoc, "unrecognized instruction mnemonic" + Suggestion);
1061   }
1062   case Match_InvalidOperand: {
1063     SMLoc ErrorLoc = IDLoc;
1064     if (ErrorInfo != ~0U) {
1065       if (ErrorInfo >= Operands.size())
1066         return Error(ErrorLoc, "too few operands for instruction");
1067 
1068       ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1069       if (ErrorLoc == SMLoc())
1070         ErrorLoc = IDLoc;
1071     }
1072     return Error(ErrorLoc, "invalid operand for instruction");
1073   }
1074   }
1075 
1076   // Handle the case when the error message is of specific type
1077   // other than the generic Match_InvalidOperand, and the
1078   // corresponding operand is missing.
1079   if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1080     SMLoc ErrorLoc = IDLoc;
1081     if (ErrorInfo != ~0U && ErrorInfo >= Operands.size())
1082         return Error(ErrorLoc, "too few operands for instruction");
1083   }
1084 
1085   switch(Result) {
1086   default:
1087     break;
1088   case Match_InvalidImmXLenLI:
1089     if (isRV64()) {
1090       SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1091       return Error(ErrorLoc, "operand must be a constant 64-bit integer");
1092     }
1093     return generateImmOutOfRangeError(Operands, ErrorInfo,
1094                                       std::numeric_limits<int32_t>::min(),
1095                                       std::numeric_limits<uint32_t>::max());
1096   case Match_InvalidImmZero: {
1097     SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1098     return Error(ErrorLoc, "immediate must be zero");
1099   }
1100   case Match_InvalidUImmLog2XLen:
1101     if (isRV64())
1102       return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
1103     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1104   case Match_InvalidUImmLog2XLenNonZero:
1105     if (isRV64())
1106       return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1);
1107     return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
1108   case Match_InvalidUImmLog2XLenHalf:
1109     if (isRV64())
1110       return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1111     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);
1112   case Match_InvalidUImm5:
1113     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1114   case Match_InvalidSImm6:
1115     return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5),
1116                                       (1 << 5) - 1);
1117   case Match_InvalidSImm6NonZero:
1118     return generateImmOutOfRangeError(
1119         Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1,
1120         "immediate must be non-zero in the range");
1121   case Match_InvalidCLUIImm:
1122     return generateImmOutOfRangeError(
1123         Operands, ErrorInfo, 1, (1 << 5) - 1,
1124         "immediate must be in [0xfffe0, 0xfffff] or");
1125   case Match_InvalidUImm7Lsb00:
1126     return generateImmOutOfRangeError(
1127         Operands, ErrorInfo, 0, (1 << 7) - 4,
1128         "immediate must be a multiple of 4 bytes in the range");
1129   case Match_InvalidUImm8Lsb00:
1130     return generateImmOutOfRangeError(
1131         Operands, ErrorInfo, 0, (1 << 8) - 4,
1132         "immediate must be a multiple of 4 bytes in the range");
1133   case Match_InvalidUImm8Lsb000:
1134     return generateImmOutOfRangeError(
1135         Operands, ErrorInfo, 0, (1 << 8) - 8,
1136         "immediate must be a multiple of 8 bytes in the range");
1137   case Match_InvalidSImm9Lsb0:
1138     return generateImmOutOfRangeError(
1139         Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2,
1140         "immediate must be a multiple of 2 bytes in the range");
1141   case Match_InvalidUImm9Lsb000:
1142     return generateImmOutOfRangeError(
1143         Operands, ErrorInfo, 0, (1 << 9) - 8,
1144         "immediate must be a multiple of 8 bytes in the range");
1145   case Match_InvalidUImm10Lsb00NonZero:
1146     return generateImmOutOfRangeError(
1147         Operands, ErrorInfo, 4, (1 << 10) - 4,
1148         "immediate must be a multiple of 4 bytes in the range");
1149   case Match_InvalidSImm10Lsb0000NonZero:
1150     return generateImmOutOfRangeError(
1151         Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
1152         "immediate must be a multiple of 16 bytes and non-zero in the range");
1153   case Match_InvalidSImm12:
1154     return generateImmOutOfRangeError(
1155         Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1,
1156         "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an "
1157         "integer in the range");
1158   case Match_InvalidSImm12Lsb0:
1159     return generateImmOutOfRangeError(
1160         Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2,
1161         "immediate must be a multiple of 2 bytes in the range");
1162   case Match_InvalidSImm13Lsb0:
1163     return generateImmOutOfRangeError(
1164         Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2,
1165         "immediate must be a multiple of 2 bytes in the range");
1166   case Match_InvalidUImm20LUI:
1167     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1,
1168                                       "operand must be a symbol with "
1169                                       "%hi/%tprel_hi modifier or an integer in "
1170                                       "the range");
1171   case Match_InvalidUImm20AUIPC:
1172     return generateImmOutOfRangeError(
1173         Operands, ErrorInfo, 0, (1 << 20) - 1,
1174         "operand must be a symbol with a "
1175         "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or "
1176         "an integer in the range");
1177   case Match_InvalidSImm21Lsb0JAL:
1178     return generateImmOutOfRangeError(
1179         Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2,
1180         "immediate must be a multiple of 2 bytes in the range");
1181   case Match_InvalidCSRSystemRegister: {
1182     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1,
1183                                       "operand must be a valid system register "
1184                                       "name or an integer in the range");
1185   }
1186   case Match_InvalidFenceArg: {
1187     SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1188     return Error(
1189         ErrorLoc,
1190         "operand must be formed of letters selected in-order from 'iorw'");
1191   }
1192   case Match_InvalidFRMArg: {
1193     SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1194     return Error(
1195         ErrorLoc,
1196         "operand must be a valid floating point rounding mode mnemonic");
1197   }
1198   case Match_InvalidBareSymbol: {
1199     SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1200     return Error(ErrorLoc, "operand must be a bare symbol name");
1201   }
1202   case Match_InvalidPseudoJumpSymbol: {
1203     SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1204     return Error(ErrorLoc, "operand must be a valid jump target");
1205   }
1206   case Match_InvalidCallSymbol: {
1207     SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1208     return Error(ErrorLoc, "operand must be a bare symbol name");
1209   }
1210   case Match_InvalidTPRelAddSymbol: {
1211     SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1212     return Error(ErrorLoc, "operand must be a symbol with %tprel_add modifier");
1213   }
1214   case Match_InvalidVTypeI: {
1215     SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1216     return Error(
1217         ErrorLoc,
1218         "operand must be "
1219         "e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
1220   }
1221   case Match_InvalidVMaskRegister: {
1222     SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1223     return Error(ErrorLoc, "operand must be v0.t");
1224   }
1225   case Match_InvalidSImm5Plus1: {
1226     return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4) + 1,
1227                                       (1 << 4),
1228                                       "immediate must be in the range");
1229   }
1230   }
1231 
1232   llvm_unreachable("Unknown match type detected!");
1233 }
1234 
1235 // Attempts to match Name as a register (either using the default name or
1236 // alternative ABI names), setting RegNo to the matching register. Upon
1237 // failure, returns true and sets RegNo to 0. If IsRV32E then registers
1238 // x16-x31 will be rejected.
matchRegisterNameHelper(bool IsRV32E,Register & RegNo,StringRef Name)1239 static bool matchRegisterNameHelper(bool IsRV32E, Register &RegNo,
1240                                     StringRef Name) {
1241   RegNo = MatchRegisterName(Name);
1242   // The 32- and 64-bit FPRs have the same asm name. Check that the initial
1243   // match always matches the 64-bit variant, and not the 32-bit one.
1244   assert(!(RegNo >= RISCV::F0_F && RegNo <= RISCV::F31_F));
1245   // The default FPR register class is based on the tablegen enum ordering.
1246   static_assert(RISCV::F0_D < RISCV::F0_F, "FPR matching must be updated");
1247   if (RegNo == RISCV::NoRegister)
1248     RegNo = MatchRegisterAltName(Name);
1249   if (IsRV32E && RegNo >= RISCV::X16 && RegNo <= RISCV::X31)
1250     RegNo = RISCV::NoRegister;
1251   return RegNo == RISCV::NoRegister;
1252 }
1253 
ParseRegister(unsigned & RegNo,SMLoc & StartLoc,SMLoc & EndLoc)1254 bool RISCVAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1255                                    SMLoc &EndLoc) {
1256   if (tryParseRegister(RegNo, StartLoc, EndLoc) != MatchOperand_Success)
1257     return Error(StartLoc, "invalid register name");
1258   return false;
1259 }
1260 
tryParseRegister(unsigned & RegNo,SMLoc & StartLoc,SMLoc & EndLoc)1261 OperandMatchResultTy RISCVAsmParser::tryParseRegister(unsigned &RegNo,
1262                                                       SMLoc &StartLoc,
1263                                                       SMLoc &EndLoc) {
1264   const AsmToken &Tok = getParser().getTok();
1265   StartLoc = Tok.getLoc();
1266   EndLoc = Tok.getEndLoc();
1267   RegNo = 0;
1268   StringRef Name = getLexer().getTok().getIdentifier();
1269 
1270   if (matchRegisterNameHelper(isRV32E(), (Register &)RegNo, Name))
1271     return MatchOperand_NoMatch;
1272 
1273   getParser().Lex(); // Eat identifier token.
1274   return MatchOperand_Success;
1275 }
1276 
parseRegister(OperandVector & Operands,bool AllowParens)1277 OperandMatchResultTy RISCVAsmParser::parseRegister(OperandVector &Operands,
1278                                                    bool AllowParens) {
1279   SMLoc FirstS = getLoc();
1280   bool HadParens = false;
1281   AsmToken LParen;
1282 
1283   // If this is an LParen and a parenthesised register name is allowed, parse it
1284   // atomically.
1285   if (AllowParens && getLexer().is(AsmToken::LParen)) {
1286     AsmToken Buf[2];
1287     size_t ReadCount = getLexer().peekTokens(Buf);
1288     if (ReadCount == 2 && Buf[1].getKind() == AsmToken::RParen) {
1289       HadParens = true;
1290       LParen = getParser().getTok();
1291       getParser().Lex(); // Eat '('
1292     }
1293   }
1294 
1295   switch (getLexer().getKind()) {
1296   default:
1297     if (HadParens)
1298       getLexer().UnLex(LParen);
1299     return MatchOperand_NoMatch;
1300   case AsmToken::Identifier:
1301     StringRef Name = getLexer().getTok().getIdentifier();
1302     Register RegNo;
1303     matchRegisterNameHelper(isRV32E(), RegNo, Name);
1304 
1305     if (RegNo == RISCV::NoRegister) {
1306       if (HadParens)
1307         getLexer().UnLex(LParen);
1308       return MatchOperand_NoMatch;
1309     }
1310     if (HadParens)
1311       Operands.push_back(RISCVOperand::createToken("(", FirstS, isRV64()));
1312     SMLoc S = getLoc();
1313     SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1314     getLexer().Lex();
1315     Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64()));
1316   }
1317 
1318   if (HadParens) {
1319     getParser().Lex(); // Eat ')'
1320     Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64()));
1321   }
1322 
1323   return MatchOperand_Success;
1324 }
1325 
1326 OperandMatchResultTy
parseCSRSystemRegister(OperandVector & Operands)1327 RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) {
1328   SMLoc S = getLoc();
1329   const MCExpr *Res;
1330 
1331   switch (getLexer().getKind()) {
1332   default:
1333     return MatchOperand_NoMatch;
1334   case AsmToken::LParen:
1335   case AsmToken::Minus:
1336   case AsmToken::Plus:
1337   case AsmToken::Exclaim:
1338   case AsmToken::Tilde:
1339   case AsmToken::Integer:
1340   case AsmToken::String: {
1341     if (getParser().parseExpression(Res))
1342       return MatchOperand_ParseFail;
1343 
1344     auto *CE = dyn_cast<MCConstantExpr>(Res);
1345     if (CE) {
1346       int64_t Imm = CE->getValue();
1347       if (isUInt<12>(Imm)) {
1348         auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm);
1349         // Accept an immediate representing a named or un-named Sys Reg
1350         // if the range is valid, regardless of the required features.
1351         Operands.push_back(RISCVOperand::createSysReg(
1352             SysReg ? SysReg->Name : "", S, Imm, isRV64()));
1353         return MatchOperand_Success;
1354       }
1355     }
1356 
1357     Twine Msg = "immediate must be an integer in the range";
1358     Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]");
1359     return MatchOperand_ParseFail;
1360   }
1361   case AsmToken::Identifier: {
1362     StringRef Identifier;
1363     if (getParser().parseIdentifier(Identifier))
1364       return MatchOperand_ParseFail;
1365 
1366     auto SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
1367     if (!SysReg)
1368       SysReg = RISCVSysReg::lookupSysRegByAltName(Identifier);
1369     // Accept a named Sys Reg if the required features are present.
1370     if (SysReg) {
1371       if (!SysReg->haveRequiredFeatures(getSTI().getFeatureBits())) {
1372         Error(S, "system register use requires an option to be enabled");
1373         return MatchOperand_ParseFail;
1374       }
1375       Operands.push_back(RISCVOperand::createSysReg(
1376           Identifier, S, SysReg->Encoding, isRV64()));
1377       return MatchOperand_Success;
1378     }
1379 
1380     Twine Msg = "operand must be a valid system register name "
1381                 "or an integer in the range";
1382     Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]");
1383     return MatchOperand_ParseFail;
1384   }
1385   case AsmToken::Percent: {
1386     // Discard operand with modifier.
1387     Twine Msg = "immediate must be an integer in the range";
1388     Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]");
1389     return MatchOperand_ParseFail;
1390   }
1391   }
1392 
1393   return MatchOperand_NoMatch;
1394 }
1395 
parseImmediate(OperandVector & Operands)1396 OperandMatchResultTy RISCVAsmParser::parseImmediate(OperandVector &Operands) {
1397   SMLoc S = getLoc();
1398   SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1399   const MCExpr *Res;
1400 
1401   switch (getLexer().getKind()) {
1402   default:
1403     return MatchOperand_NoMatch;
1404   case AsmToken::LParen:
1405   case AsmToken::Dot:
1406   case AsmToken::Minus:
1407   case AsmToken::Plus:
1408   case AsmToken::Exclaim:
1409   case AsmToken::Tilde:
1410   case AsmToken::Integer:
1411   case AsmToken::String:
1412   case AsmToken::Identifier:
1413     if (getParser().parseExpression(Res))
1414       return MatchOperand_ParseFail;
1415     break;
1416   case AsmToken::Percent:
1417     return parseOperandWithModifier(Operands);
1418   }
1419 
1420   Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1421   return MatchOperand_Success;
1422 }
1423 
1424 OperandMatchResultTy
parseOperandWithModifier(OperandVector & Operands)1425 RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) {
1426   SMLoc S = getLoc();
1427   SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1428 
1429   if (getLexer().getKind() != AsmToken::Percent) {
1430     Error(getLoc(), "expected '%' for operand modifier");
1431     return MatchOperand_ParseFail;
1432   }
1433 
1434   getParser().Lex(); // Eat '%'
1435 
1436   if (getLexer().getKind() != AsmToken::Identifier) {
1437     Error(getLoc(), "expected valid identifier for operand modifier");
1438     return MatchOperand_ParseFail;
1439   }
1440   StringRef Identifier = getParser().getTok().getIdentifier();
1441   RISCVMCExpr::VariantKind VK = RISCVMCExpr::getVariantKindForName(Identifier);
1442   if (VK == RISCVMCExpr::VK_RISCV_Invalid) {
1443     Error(getLoc(), "unrecognized operand modifier");
1444     return MatchOperand_ParseFail;
1445   }
1446 
1447   getParser().Lex(); // Eat the identifier
1448   if (getLexer().getKind() != AsmToken::LParen) {
1449     Error(getLoc(), "expected '('");
1450     return MatchOperand_ParseFail;
1451   }
1452   getParser().Lex(); // Eat '('
1453 
1454   const MCExpr *SubExpr;
1455   if (getParser().parseParenExpression(SubExpr, E)) {
1456     return MatchOperand_ParseFail;
1457   }
1458 
1459   const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, VK, getContext());
1460   Operands.push_back(RISCVOperand::createImm(ModExpr, S, E, isRV64()));
1461   return MatchOperand_Success;
1462 }
1463 
parseBareSymbol(OperandVector & Operands)1464 OperandMatchResultTy RISCVAsmParser::parseBareSymbol(OperandVector &Operands) {
1465   SMLoc S = getLoc();
1466   SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1467   const MCExpr *Res;
1468 
1469   if (getLexer().getKind() != AsmToken::Identifier)
1470     return MatchOperand_NoMatch;
1471 
1472   StringRef Identifier;
1473   AsmToken Tok = getLexer().getTok();
1474 
1475   if (getParser().parseIdentifier(Identifier))
1476     return MatchOperand_ParseFail;
1477 
1478   if (Identifier.consume_back("@plt")) {
1479     Error(getLoc(), "'@plt' operand not valid for instruction");
1480     return MatchOperand_ParseFail;
1481   }
1482 
1483   MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1484 
1485   if (Sym->isVariable()) {
1486     const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false);
1487     if (!isa<MCSymbolRefExpr>(V)) {
1488       getLexer().UnLex(Tok); // Put back if it's not a bare symbol.
1489       return MatchOperand_NoMatch;
1490     }
1491     Res = V;
1492   } else
1493     Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1494 
1495   MCBinaryExpr::Opcode Opcode;
1496   switch (getLexer().getKind()) {
1497   default:
1498     Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1499     return MatchOperand_Success;
1500   case AsmToken::Plus:
1501     Opcode = MCBinaryExpr::Add;
1502     break;
1503   case AsmToken::Minus:
1504     Opcode = MCBinaryExpr::Sub;
1505     break;
1506   }
1507 
1508   const MCExpr *Expr;
1509   if (getParser().parseExpression(Expr))
1510     return MatchOperand_ParseFail;
1511   Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext());
1512   Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1513   return MatchOperand_Success;
1514 }
1515 
parseCallSymbol(OperandVector & Operands)1516 OperandMatchResultTy RISCVAsmParser::parseCallSymbol(OperandVector &Operands) {
1517   SMLoc S = getLoc();
1518   SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1519   const MCExpr *Res;
1520 
1521   if (getLexer().getKind() != AsmToken::Identifier)
1522     return MatchOperand_NoMatch;
1523 
1524   // Avoid parsing the register in `call rd, foo` as a call symbol.
1525   if (getLexer().peekTok().getKind() != AsmToken::EndOfStatement)
1526     return MatchOperand_NoMatch;
1527 
1528   StringRef Identifier;
1529   if (getParser().parseIdentifier(Identifier))
1530     return MatchOperand_ParseFail;
1531 
1532   RISCVMCExpr::VariantKind Kind = RISCVMCExpr::VK_RISCV_CALL;
1533   if (Identifier.consume_back("@plt"))
1534     Kind = RISCVMCExpr::VK_RISCV_CALL_PLT;
1535 
1536   MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1537   Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1538   Res = RISCVMCExpr::create(Res, Kind, getContext());
1539   Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1540   return MatchOperand_Success;
1541 }
1542 
1543 OperandMatchResultTy
parsePseudoJumpSymbol(OperandVector & Operands)1544 RISCVAsmParser::parsePseudoJumpSymbol(OperandVector &Operands) {
1545   SMLoc S = getLoc();
1546   SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1547   const MCExpr *Res;
1548 
1549   if (getParser().parseExpression(Res))
1550     return MatchOperand_ParseFail;
1551 
1552   if (Res->getKind() != MCExpr::ExprKind::SymbolRef ||
1553       cast<MCSymbolRefExpr>(Res)->getKind() ==
1554           MCSymbolRefExpr::VariantKind::VK_PLT) {
1555     Error(S, "operand must be a valid jump target");
1556     return MatchOperand_ParseFail;
1557   }
1558 
1559   Res = RISCVMCExpr::create(Res, RISCVMCExpr::VK_RISCV_CALL, getContext());
1560   Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1561   return MatchOperand_Success;
1562 }
1563 
parseJALOffset(OperandVector & Operands)1564 OperandMatchResultTy RISCVAsmParser::parseJALOffset(OperandVector &Operands) {
1565   // Parsing jal operands is fiddly due to the `jal foo` and `jal ra, foo`
1566   // both being acceptable forms. When parsing `jal ra, foo` this function
1567   // will be called for the `ra` register operand in an attempt to match the
1568   // single-operand alias. parseJALOffset must fail for this case. It would
1569   // seem logical to try parse the operand using parseImmediate and return
1570   // NoMatch if the next token is a comma (meaning we must be parsing a jal in
1571   // the second form rather than the first). We can't do this as there's no
1572   // way of rewinding the lexer state. Instead, return NoMatch if this operand
1573   // is an identifier and is followed by a comma.
1574   if (getLexer().is(AsmToken::Identifier) &&
1575       getLexer().peekTok().is(AsmToken::Comma))
1576     return MatchOperand_NoMatch;
1577 
1578   return parseImmediate(Operands);
1579 }
1580 
parseVTypeI(OperandVector & Operands)1581 OperandMatchResultTy RISCVAsmParser::parseVTypeI(OperandVector &Operands) {
1582   SMLoc S = getLoc();
1583   if (getLexer().getKind() != AsmToken::Identifier)
1584     return MatchOperand_NoMatch;
1585 
1586   // Parse "e8,m1,t[a|u],m[a|u]"
1587   StringRef Name = getLexer().getTok().getIdentifier();
1588   if (!Name.consume_front("e"))
1589     return MatchOperand_NoMatch;
1590   APInt Sew(16, Name, 10);
1591   if (Sew != 8 && Sew != 16 && Sew != 32 && Sew != 64 && Sew != 128 &&
1592       Sew != 256 && Sew != 512 && Sew != 1024)
1593     return MatchOperand_NoMatch;
1594   getLexer().Lex();
1595 
1596   if (!getLexer().is(AsmToken::Comma))
1597     return MatchOperand_NoMatch;
1598   getLexer().Lex();
1599 
1600   Name = getLexer().getTok().getIdentifier();
1601   if (!Name.consume_front("m"))
1602     return MatchOperand_NoMatch;
1603   // "m" or "mf"
1604   bool Fractional = false;
1605   if (Name.consume_front("f")) {
1606     Fractional = true;
1607   }
1608   APInt Lmul(16, Name, 10);
1609   if (Lmul != 1 && Lmul != 2 && Lmul != 4 && Lmul != 8)
1610     return MatchOperand_NoMatch;
1611   getLexer().Lex();
1612 
1613   if (!getLexer().is(AsmToken::Comma))
1614     return MatchOperand_NoMatch;
1615   getLexer().Lex();
1616 
1617   Name = getLexer().getTok().getIdentifier();
1618   // ta or tu
1619   bool TailAgnostic;
1620   if (Name.consume_front("ta"))
1621     TailAgnostic = true;
1622   else if (Name.consume_front("tu"))
1623     TailAgnostic = false;
1624   else
1625     return MatchOperand_NoMatch;
1626   getLexer().Lex();
1627 
1628   if (!getLexer().is(AsmToken::Comma))
1629     return MatchOperand_NoMatch;
1630   getLexer().Lex();
1631 
1632   Name = getLexer().getTok().getIdentifier();
1633   // ma or mu
1634   bool MaskedoffAgnostic;
1635   if (Name.consume_front("ma"))
1636     MaskedoffAgnostic = true;
1637   else if (Name.consume_front("mu"))
1638     MaskedoffAgnostic = false;
1639   else
1640     return MatchOperand_NoMatch;
1641   getLexer().Lex();
1642 
1643   if (getLexer().getKind() != AsmToken::EndOfStatement)
1644     return MatchOperand_NoMatch;
1645 
1646   Operands.push_back(RISCVOperand::createVType(
1647       Sew, Lmul, Fractional, TailAgnostic, MaskedoffAgnostic, S, isRV64()));
1648 
1649   return MatchOperand_Success;
1650 }
1651 
parseMaskReg(OperandVector & Operands)1652 OperandMatchResultTy RISCVAsmParser::parseMaskReg(OperandVector &Operands) {
1653   switch (getLexer().getKind()) {
1654   default:
1655     return MatchOperand_NoMatch;
1656   case AsmToken::Identifier:
1657     StringRef Name = getLexer().getTok().getIdentifier();
1658     if (!Name.consume_back(".t")) {
1659       Error(getLoc(), "expected '.t' suffix");
1660       return MatchOperand_ParseFail;
1661     }
1662     Register RegNo;
1663     matchRegisterNameHelper(isRV32E(), RegNo, Name);
1664 
1665     if (RegNo == RISCV::NoRegister)
1666       return MatchOperand_NoMatch;
1667     if (RegNo != RISCV::V0)
1668       return MatchOperand_NoMatch;
1669     SMLoc S = getLoc();
1670     SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1671     getLexer().Lex();
1672     Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64()));
1673   }
1674 
1675   return MatchOperand_Success;
1676 }
1677 
1678 OperandMatchResultTy
parseMemOpBaseReg(OperandVector & Operands)1679 RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) {
1680   if (getLexer().isNot(AsmToken::LParen)) {
1681     Error(getLoc(), "expected '('");
1682     return MatchOperand_ParseFail;
1683   }
1684 
1685   getParser().Lex(); // Eat '('
1686   Operands.push_back(RISCVOperand::createToken("(", getLoc(), isRV64()));
1687 
1688   if (parseRegister(Operands) != MatchOperand_Success) {
1689     Error(getLoc(), "expected register");
1690     return MatchOperand_ParseFail;
1691   }
1692 
1693   if (getLexer().isNot(AsmToken::RParen)) {
1694     Error(getLoc(), "expected ')'");
1695     return MatchOperand_ParseFail;
1696   }
1697 
1698   getParser().Lex(); // Eat ')'
1699   Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64()));
1700 
1701   return MatchOperand_Success;
1702 }
1703 
parseAtomicMemOp(OperandVector & Operands)1704 OperandMatchResultTy RISCVAsmParser::parseAtomicMemOp(OperandVector &Operands) {
1705   // Atomic operations such as lr.w, sc.w, and amo*.w accept a "memory operand"
1706   // as one of their register operands, such as `(a0)`. This just denotes that
1707   // the register (in this case `a0`) contains a memory address.
1708   //
1709   // Normally, we would be able to parse these by putting the parens into the
1710   // instruction string. However, GNU as also accepts a zero-offset memory
1711   // operand (such as `0(a0)`), and ignores the 0. Normally this would be parsed
1712   // with parseImmediate followed by parseMemOpBaseReg, but these instructions
1713   // do not accept an immediate operand, and we do not want to add a "dummy"
1714   // operand that is silently dropped.
1715   //
1716   // Instead, we use this custom parser. This will: allow (and discard) an
1717   // offset if it is zero; require (and discard) parentheses; and add only the
1718   // parsed register operand to `Operands`.
1719   //
1720   // These operands are printed with RISCVInstPrinter::printAtomicMemOp, which
1721   // will only print the register surrounded by parentheses (which GNU as also
1722   // uses as its canonical representation for these operands).
1723   std::unique_ptr<RISCVOperand> OptionalImmOp;
1724 
1725   if (getLexer().isNot(AsmToken::LParen)) {
1726     // Parse an Integer token. We do not accept arbritrary constant expressions
1727     // in the offset field (because they may include parens, which complicates
1728     // parsing a lot).
1729     int64_t ImmVal;
1730     SMLoc ImmStart = getLoc();
1731     if (getParser().parseIntToken(ImmVal,
1732                                   "expected '(' or optional integer offset"))
1733       return MatchOperand_ParseFail;
1734 
1735     // Create a RISCVOperand for checking later (so the error messages are
1736     // nicer), but we don't add it to Operands.
1737     SMLoc ImmEnd = getLoc();
1738     OptionalImmOp =
1739         RISCVOperand::createImm(MCConstantExpr::create(ImmVal, getContext()),
1740                                 ImmStart, ImmEnd, isRV64());
1741   }
1742 
1743   if (getLexer().isNot(AsmToken::LParen)) {
1744     Error(getLoc(), OptionalImmOp ? "expected '(' after optional integer offset"
1745                                   : "expected '(' or optional integer offset");
1746     return MatchOperand_ParseFail;
1747   }
1748   getParser().Lex(); // Eat '('
1749 
1750   if (parseRegister(Operands) != MatchOperand_Success) {
1751     Error(getLoc(), "expected register");
1752     return MatchOperand_ParseFail;
1753   }
1754 
1755   if (getLexer().isNot(AsmToken::RParen)) {
1756     Error(getLoc(), "expected ')'");
1757     return MatchOperand_ParseFail;
1758   }
1759   getParser().Lex(); // Eat ')'
1760 
1761   // Deferred Handling of non-zero offsets. This makes the error messages nicer.
1762   if (OptionalImmOp && !OptionalImmOp->isImmZero()) {
1763     Error(OptionalImmOp->getStartLoc(), "optional integer offset must be 0",
1764           SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
1765     return MatchOperand_ParseFail;
1766   }
1767 
1768   return MatchOperand_Success;
1769 }
1770 
1771 /// Looks at a token type and creates the relevant operand from this
1772 /// information, adding to Operands. If operand was parsed, returns false, else
1773 /// true.
parseOperand(OperandVector & Operands,StringRef Mnemonic)1774 bool RISCVAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
1775   // Check if the current operand has a custom associated parser, if so, try to
1776   // custom parse the operand, or fallback to the general approach.
1777   OperandMatchResultTy Result =
1778       MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true);
1779   if (Result == MatchOperand_Success)
1780     return false;
1781   if (Result == MatchOperand_ParseFail)
1782     return true;
1783 
1784   // Attempt to parse token as a register.
1785   if (parseRegister(Operands, true) == MatchOperand_Success)
1786     return false;
1787 
1788   // Attempt to parse token as an immediate
1789   if (parseImmediate(Operands) == MatchOperand_Success) {
1790     // Parse memory base register if present
1791     if (getLexer().is(AsmToken::LParen))
1792       return parseMemOpBaseReg(Operands) != MatchOperand_Success;
1793     return false;
1794   }
1795 
1796   // Finally we have exhausted all options and must declare defeat.
1797   Error(getLoc(), "unknown operand");
1798   return true;
1799 }
1800 
ParseInstruction(ParseInstructionInfo & Info,StringRef Name,SMLoc NameLoc,OperandVector & Operands)1801 bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info,
1802                                       StringRef Name, SMLoc NameLoc,
1803                                       OperandVector &Operands) {
1804   // Ensure that if the instruction occurs when relaxation is enabled,
1805   // relocations are forced for the file. Ideally this would be done when there
1806   // is enough information to reliably determine if the instruction itself may
1807   // cause relaxations. Unfortunately instruction processing stage occurs in the
1808   // same pass as relocation emission, so it's too late to set a 'sticky bit'
1809   // for the entire file.
1810   if (getSTI().getFeatureBits()[RISCV::FeatureRelax]) {
1811     auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr();
1812     if (Assembler != nullptr) {
1813       RISCVAsmBackend &MAB =
1814           static_cast<RISCVAsmBackend &>(Assembler->getBackend());
1815       MAB.setForceRelocs();
1816     }
1817   }
1818 
1819   // First operand is token for instruction
1820   Operands.push_back(RISCVOperand::createToken(Name, NameLoc, isRV64()));
1821 
1822   // If there are no more operands, then finish
1823   if (getLexer().is(AsmToken::EndOfStatement))
1824     return false;
1825 
1826   // Parse first operand
1827   if (parseOperand(Operands, Name))
1828     return true;
1829 
1830   // Parse until end of statement, consuming commas between operands
1831   unsigned OperandIdx = 1;
1832   while (getLexer().is(AsmToken::Comma)) {
1833     // Consume comma token
1834     getLexer().Lex();
1835 
1836     // Parse next operand
1837     if (parseOperand(Operands, Name))
1838       return true;
1839 
1840     ++OperandIdx;
1841   }
1842 
1843   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1844     SMLoc Loc = getLexer().getLoc();
1845     getParser().eatToEndOfStatement();
1846     return Error(Loc, "unexpected token");
1847   }
1848 
1849   getParser().Lex(); // Consume the EndOfStatement.
1850   return false;
1851 }
1852 
classifySymbolRef(const MCExpr * Expr,RISCVMCExpr::VariantKind & Kind,int64_t & Addend)1853 bool RISCVAsmParser::classifySymbolRef(const MCExpr *Expr,
1854                                        RISCVMCExpr::VariantKind &Kind,
1855                                        int64_t &Addend) {
1856   Kind = RISCVMCExpr::VK_RISCV_None;
1857   Addend = 0;
1858 
1859   if (const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) {
1860     Kind = RE->getKind();
1861     Expr = RE->getSubExpr();
1862   }
1863 
1864   // It's a simple symbol reference or constant with no addend.
1865   if (isa<MCConstantExpr>(Expr) || isa<MCSymbolRefExpr>(Expr))
1866     return true;
1867 
1868   const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr);
1869   if (!BE)
1870     return false;
1871 
1872   if (!isa<MCSymbolRefExpr>(BE->getLHS()))
1873     return false;
1874 
1875   if (BE->getOpcode() != MCBinaryExpr::Add &&
1876       BE->getOpcode() != MCBinaryExpr::Sub)
1877     return false;
1878 
1879   // We are able to support the subtraction of two symbol references
1880   if (BE->getOpcode() == MCBinaryExpr::Sub &&
1881       isa<MCSymbolRefExpr>(BE->getRHS()))
1882     return true;
1883 
1884   // See if the addend is a constant, otherwise there's more going
1885   // on here than we can deal with.
1886   auto AddendExpr = dyn_cast<MCConstantExpr>(BE->getRHS());
1887   if (!AddendExpr)
1888     return false;
1889 
1890   Addend = AddendExpr->getValue();
1891   if (BE->getOpcode() == MCBinaryExpr::Sub)
1892     Addend = -Addend;
1893 
1894   // It's some symbol reference + a constant addend
1895   return Kind != RISCVMCExpr::VK_RISCV_Invalid;
1896 }
1897 
ParseDirective(AsmToken DirectiveID)1898 bool RISCVAsmParser::ParseDirective(AsmToken DirectiveID) {
1899   // This returns false if this function recognizes the directive
1900   // regardless of whether it is successfully handles or reports an
1901   // error. Otherwise it returns true to give the generic parser a
1902   // chance at recognizing it.
1903   StringRef IDVal = DirectiveID.getString();
1904 
1905   if (IDVal == ".option")
1906     return parseDirectiveOption();
1907   else if (IDVal == ".attribute")
1908     return parseDirectiveAttribute();
1909 
1910   return true;
1911 }
1912 
parseDirectiveOption()1913 bool RISCVAsmParser::parseDirectiveOption() {
1914   MCAsmParser &Parser = getParser();
1915   // Get the option token.
1916   AsmToken Tok = Parser.getTok();
1917   // At the moment only identifiers are supported.
1918   if (Tok.isNot(AsmToken::Identifier))
1919     return Error(Parser.getTok().getLoc(),
1920                  "unexpected token, expected identifier");
1921 
1922   StringRef Option = Tok.getIdentifier();
1923 
1924   if (Option == "push") {
1925     getTargetStreamer().emitDirectiveOptionPush();
1926 
1927     Parser.Lex();
1928     if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1929       return Error(Parser.getTok().getLoc(),
1930                    "unexpected token, expected end of statement");
1931 
1932     pushFeatureBits();
1933     return false;
1934   }
1935 
1936   if (Option == "pop") {
1937     SMLoc StartLoc = Parser.getTok().getLoc();
1938     getTargetStreamer().emitDirectiveOptionPop();
1939 
1940     Parser.Lex();
1941     if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1942       return Error(Parser.getTok().getLoc(),
1943                    "unexpected token, expected end of statement");
1944 
1945     if (popFeatureBits())
1946       return Error(StartLoc, ".option pop with no .option push");
1947 
1948     return false;
1949   }
1950 
1951   if (Option == "rvc") {
1952     getTargetStreamer().emitDirectiveOptionRVC();
1953 
1954     Parser.Lex();
1955     if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1956       return Error(Parser.getTok().getLoc(),
1957                    "unexpected token, expected end of statement");
1958 
1959     setFeatureBits(RISCV::FeatureStdExtC, "c");
1960     return false;
1961   }
1962 
1963   if (Option == "norvc") {
1964     getTargetStreamer().emitDirectiveOptionNoRVC();
1965 
1966     Parser.Lex();
1967     if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1968       return Error(Parser.getTok().getLoc(),
1969                    "unexpected token, expected end of statement");
1970 
1971     clearFeatureBits(RISCV::FeatureStdExtC, "c");
1972     return false;
1973   }
1974 
1975   if (Option == "pic") {
1976     getTargetStreamer().emitDirectiveOptionPIC();
1977 
1978     Parser.Lex();
1979     if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1980       return Error(Parser.getTok().getLoc(),
1981                    "unexpected token, expected end of statement");
1982 
1983     ParserOptions.IsPicEnabled = true;
1984     return false;
1985   }
1986 
1987   if (Option == "nopic") {
1988     getTargetStreamer().emitDirectiveOptionNoPIC();
1989 
1990     Parser.Lex();
1991     if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1992       return Error(Parser.getTok().getLoc(),
1993                    "unexpected token, expected end of statement");
1994 
1995     ParserOptions.IsPicEnabled = false;
1996     return false;
1997   }
1998 
1999   if (Option == "relax") {
2000     getTargetStreamer().emitDirectiveOptionRelax();
2001 
2002     Parser.Lex();
2003     if (Parser.getTok().isNot(AsmToken::EndOfStatement))
2004       return Error(Parser.getTok().getLoc(),
2005                    "unexpected token, expected end of statement");
2006 
2007     setFeatureBits(RISCV::FeatureRelax, "relax");
2008     return false;
2009   }
2010 
2011   if (Option == "norelax") {
2012     getTargetStreamer().emitDirectiveOptionNoRelax();
2013 
2014     Parser.Lex();
2015     if (Parser.getTok().isNot(AsmToken::EndOfStatement))
2016       return Error(Parser.getTok().getLoc(),
2017                    "unexpected token, expected end of statement");
2018 
2019     clearFeatureBits(RISCV::FeatureRelax, "relax");
2020     return false;
2021   }
2022 
2023   // Unknown option.
2024   Warning(Parser.getTok().getLoc(),
2025           "unknown option, expected 'push', 'pop', 'rvc', 'norvc', 'relax' or "
2026           "'norelax'");
2027   Parser.eatToEndOfStatement();
2028   return false;
2029 }
2030 
2031 /// parseDirectiveAttribute
2032 ///  ::= .attribute expression ',' ( expression | "string" )
2033 ///  ::= .attribute identifier ',' ( expression | "string" )
parseDirectiveAttribute()2034 bool RISCVAsmParser::parseDirectiveAttribute() {
2035   MCAsmParser &Parser = getParser();
2036   int64_t Tag;
2037   SMLoc TagLoc;
2038   TagLoc = Parser.getTok().getLoc();
2039   if (Parser.getTok().is(AsmToken::Identifier)) {
2040     StringRef Name = Parser.getTok().getIdentifier();
2041     Optional<unsigned> Ret =
2042         ELFAttrs::attrTypeFromString(Name, RISCVAttrs::RISCVAttributeTags);
2043     if (!Ret.hasValue()) {
2044       Error(TagLoc, "attribute name not recognised: " + Name);
2045       return false;
2046     }
2047     Tag = Ret.getValue();
2048     Parser.Lex();
2049   } else {
2050     const MCExpr *AttrExpr;
2051 
2052     TagLoc = Parser.getTok().getLoc();
2053     if (Parser.parseExpression(AttrExpr))
2054       return true;
2055 
2056     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr);
2057     if (check(!CE, TagLoc, "expected numeric constant"))
2058       return true;
2059 
2060     Tag = CE->getValue();
2061   }
2062 
2063   if (Parser.parseToken(AsmToken::Comma, "comma expected"))
2064     return true;
2065 
2066   StringRef StringValue;
2067   int64_t IntegerValue = 0;
2068   bool IsIntegerValue = true;
2069 
2070   // RISC-V attributes have a string value if the tag number is odd
2071   // and an integer value if the tag number is even.
2072   if (Tag % 2)
2073     IsIntegerValue = false;
2074 
2075   SMLoc ValueExprLoc = Parser.getTok().getLoc();
2076   if (IsIntegerValue) {
2077     const MCExpr *ValueExpr;
2078     if (Parser.parseExpression(ValueExpr))
2079       return true;
2080 
2081     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr);
2082     if (!CE)
2083       return Error(ValueExprLoc, "expected numeric constant");
2084     IntegerValue = CE->getValue();
2085   } else {
2086     if (Parser.getTok().isNot(AsmToken::String))
2087       return Error(Parser.getTok().getLoc(), "expected string constant");
2088 
2089     StringValue = Parser.getTok().getStringContents();
2090     Parser.Lex();
2091   }
2092 
2093   if (Parser.parseToken(AsmToken::EndOfStatement,
2094                         "unexpected token in '.attribute' directive"))
2095     return true;
2096 
2097   if (Tag == RISCVAttrs::ARCH) {
2098     StringRef Arch = StringValue;
2099     if (Arch.consume_front("rv32"))
2100       clearFeatureBits(RISCV::Feature64Bit, "64bit");
2101     else if (Arch.consume_front("rv64"))
2102       setFeatureBits(RISCV::Feature64Bit, "64bit");
2103     else
2104       return Error(ValueExprLoc, "bad arch string " + Arch);
2105 
2106     while (!Arch.empty()) {
2107       if (Arch[0] == 'i')
2108         clearFeatureBits(RISCV::FeatureRV32E, "e");
2109       else if (Arch[0] == 'e')
2110         setFeatureBits(RISCV::FeatureRV32E, "e");
2111       else if (Arch[0] == 'g') {
2112         clearFeatureBits(RISCV::FeatureRV32E, "e");
2113         setFeatureBits(RISCV::FeatureStdExtM, "m");
2114         setFeatureBits(RISCV::FeatureStdExtA, "a");
2115         setFeatureBits(RISCV::FeatureStdExtF, "f");
2116         setFeatureBits(RISCV::FeatureStdExtD, "d");
2117       } else if (Arch[0] == 'm')
2118         setFeatureBits(RISCV::FeatureStdExtM, "m");
2119       else if (Arch[0] == 'a')
2120         setFeatureBits(RISCV::FeatureStdExtA, "a");
2121       else if (Arch[0] == 'f')
2122         setFeatureBits(RISCV::FeatureStdExtF, "f");
2123       else if (Arch[0] == 'd') {
2124         setFeatureBits(RISCV::FeatureStdExtF, "f");
2125         setFeatureBits(RISCV::FeatureStdExtD, "d");
2126       } else if (Arch[0] == 'c') {
2127         setFeatureBits(RISCV::FeatureStdExtC, "c");
2128       } else
2129         return Error(ValueExprLoc, "bad arch string " + Arch);
2130 
2131       Arch = Arch.drop_front(1);
2132       int major = 0;
2133       int minor = 0;
2134       Arch.consumeInteger(10, major);
2135       Arch.consume_front("p");
2136       Arch.consumeInteger(10, minor);
2137       if (major != 0 || minor != 0) {
2138         Arch = Arch.drop_until([](char c) { return c == '_' || c == '"'; });
2139         Arch = Arch.drop_while([](char c) { return c == '_'; });
2140       }
2141     }
2142   }
2143 
2144   if (IsIntegerValue)
2145     getTargetStreamer().emitAttribute(Tag, IntegerValue);
2146   else {
2147     if (Tag != RISCVAttrs::ARCH) {
2148       getTargetStreamer().emitTextAttribute(Tag, StringValue);
2149     } else {
2150       std::string formalArchStr = "rv32";
2151       if (getFeatureBits(RISCV::Feature64Bit))
2152         formalArchStr = "rv64";
2153       if (getFeatureBits(RISCV::FeatureRV32E))
2154         formalArchStr = (Twine(formalArchStr) + "e1p9").str();
2155       else
2156         formalArchStr = (Twine(formalArchStr) + "i2p0").str();
2157 
2158       if (getFeatureBits(RISCV::FeatureStdExtM))
2159         formalArchStr = (Twine(formalArchStr) + "_m2p0").str();
2160       if (getFeatureBits(RISCV::FeatureStdExtA))
2161         formalArchStr = (Twine(formalArchStr) + "_a2p0").str();
2162       if (getFeatureBits(RISCV::FeatureStdExtF))
2163         formalArchStr = (Twine(formalArchStr) + "_f2p0").str();
2164       if (getFeatureBits(RISCV::FeatureStdExtD))
2165         formalArchStr = (Twine(formalArchStr) + "_d2p0").str();
2166       if (getFeatureBits(RISCV::FeatureStdExtC))
2167         formalArchStr = (Twine(formalArchStr) + "_c2p0").str();
2168 
2169       getTargetStreamer().emitTextAttribute(Tag, formalArchStr);
2170     }
2171   }
2172 
2173   return false;
2174 }
2175 
emitToStreamer(MCStreamer & S,const MCInst & Inst)2176 void RISCVAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) {
2177   MCInst CInst;
2178   bool Res = compressInst(CInst, Inst, getSTI(), S.getContext());
2179   if (Res)
2180     ++RISCVNumInstrsCompressed;
2181   S.emitInstruction((Res ? CInst : Inst), getSTI());
2182 }
2183 
emitLoadImm(Register DestReg,int64_t Value,MCStreamer & Out)2184 void RISCVAsmParser::emitLoadImm(Register DestReg, int64_t Value,
2185                                  MCStreamer &Out) {
2186   RISCVMatInt::InstSeq Seq;
2187   RISCVMatInt::generateInstSeq(Value, isRV64(), Seq);
2188 
2189   Register SrcReg = RISCV::X0;
2190   for (RISCVMatInt::Inst &Inst : Seq) {
2191     if (Inst.Opc == RISCV::LUI) {
2192       emitToStreamer(
2193           Out, MCInstBuilder(RISCV::LUI).addReg(DestReg).addImm(Inst.Imm));
2194     } else {
2195       emitToStreamer(
2196           Out, MCInstBuilder(Inst.Opc).addReg(DestReg).addReg(SrcReg).addImm(
2197                    Inst.Imm));
2198     }
2199 
2200     // Only the first instruction has X0 as its source.
2201     SrcReg = DestReg;
2202   }
2203 }
2204 
emitAuipcInstPair(MCOperand DestReg,MCOperand TmpReg,const MCExpr * Symbol,RISCVMCExpr::VariantKind VKHi,unsigned SecondOpcode,SMLoc IDLoc,MCStreamer & Out)2205 void RISCVAsmParser::emitAuipcInstPair(MCOperand DestReg, MCOperand TmpReg,
2206                                        const MCExpr *Symbol,
2207                                        RISCVMCExpr::VariantKind VKHi,
2208                                        unsigned SecondOpcode, SMLoc IDLoc,
2209                                        MCStreamer &Out) {
2210   // A pair of instructions for PC-relative addressing; expands to
2211   //   TmpLabel: AUIPC TmpReg, VKHi(symbol)
2212   //             OP DestReg, TmpReg, %pcrel_lo(TmpLabel)
2213   MCContext &Ctx = getContext();
2214 
2215   MCSymbol *TmpLabel = Ctx.createTempSymbol(
2216       "pcrel_hi", /* AlwaysAddSuffix */ true, /* CanBeUnnamed */ false);
2217   Out.emitLabel(TmpLabel);
2218 
2219   const RISCVMCExpr *SymbolHi = RISCVMCExpr::create(Symbol, VKHi, Ctx);
2220   emitToStreamer(
2221       Out, MCInstBuilder(RISCV::AUIPC).addOperand(TmpReg).addExpr(SymbolHi));
2222 
2223   const MCExpr *RefToLinkTmpLabel =
2224       RISCVMCExpr::create(MCSymbolRefExpr::create(TmpLabel, Ctx),
2225                           RISCVMCExpr::VK_RISCV_PCREL_LO, Ctx);
2226 
2227   emitToStreamer(Out, MCInstBuilder(SecondOpcode)
2228                           .addOperand(DestReg)
2229                           .addOperand(TmpReg)
2230                           .addExpr(RefToLinkTmpLabel));
2231 }
2232 
emitLoadLocalAddress(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out)2233 void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
2234                                           MCStreamer &Out) {
2235   // The load local address pseudo-instruction "lla" is used in PC-relative
2236   // addressing of local symbols:
2237   //   lla rdest, symbol
2238   // expands to
2239   //   TmpLabel: AUIPC rdest, %pcrel_hi(symbol)
2240   //             ADDI rdest, rdest, %pcrel_lo(TmpLabel)
2241   MCOperand DestReg = Inst.getOperand(0);
2242   const MCExpr *Symbol = Inst.getOperand(1).getExpr();
2243   emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI,
2244                     RISCV::ADDI, IDLoc, Out);
2245 }
2246 
emitLoadAddress(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out)2247 void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc,
2248                                      MCStreamer &Out) {
2249   // The load address pseudo-instruction "la" is used in PC-relative and
2250   // GOT-indirect addressing of global symbols:
2251   //   la rdest, symbol
2252   // expands to either (for non-PIC)
2253   //   TmpLabel: AUIPC rdest, %pcrel_hi(symbol)
2254   //             ADDI rdest, rdest, %pcrel_lo(TmpLabel)
2255   // or (for PIC)
2256   //   TmpLabel: AUIPC rdest, %got_pcrel_hi(symbol)
2257   //             Lx rdest, %pcrel_lo(TmpLabel)(rdest)
2258   MCOperand DestReg = Inst.getOperand(0);
2259   const MCExpr *Symbol = Inst.getOperand(1).getExpr();
2260   unsigned SecondOpcode;
2261   RISCVMCExpr::VariantKind VKHi;
2262   if (ParserOptions.IsPicEnabled) {
2263     SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
2264     VKHi = RISCVMCExpr::VK_RISCV_GOT_HI;
2265   } else {
2266     SecondOpcode = RISCV::ADDI;
2267     VKHi = RISCVMCExpr::VK_RISCV_PCREL_HI;
2268   }
2269   emitAuipcInstPair(DestReg, DestReg, Symbol, VKHi, SecondOpcode, IDLoc, Out);
2270 }
2271 
emitLoadTLSIEAddress(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out)2272 void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc,
2273                                           MCStreamer &Out) {
2274   // The load TLS IE address pseudo-instruction "la.tls.ie" is used in
2275   // initial-exec TLS model addressing of global symbols:
2276   //   la.tls.ie rdest, symbol
2277   // expands to
2278   //   TmpLabel: AUIPC rdest, %tls_ie_pcrel_hi(symbol)
2279   //             Lx rdest, %pcrel_lo(TmpLabel)(rdest)
2280   MCOperand DestReg = Inst.getOperand(0);
2281   const MCExpr *Symbol = Inst.getOperand(1).getExpr();
2282   unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
2283   emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_TLS_GOT_HI,
2284                     SecondOpcode, IDLoc, Out);
2285 }
2286 
emitLoadTLSGDAddress(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out)2287 void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc,
2288                                           MCStreamer &Out) {
2289   // The load TLS GD address pseudo-instruction "la.tls.gd" is used in
2290   // global-dynamic TLS model addressing of global symbols:
2291   //   la.tls.gd rdest, symbol
2292   // expands to
2293   //   TmpLabel: AUIPC rdest, %tls_gd_pcrel_hi(symbol)
2294   //             ADDI rdest, rdest, %pcrel_lo(TmpLabel)
2295   MCOperand DestReg = Inst.getOperand(0);
2296   const MCExpr *Symbol = Inst.getOperand(1).getExpr();
2297   emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_TLS_GD_HI,
2298                     RISCV::ADDI, IDLoc, Out);
2299 }
2300 
emitLoadStoreSymbol(MCInst & Inst,unsigned Opcode,SMLoc IDLoc,MCStreamer & Out,bool HasTmpReg)2301 void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode,
2302                                          SMLoc IDLoc, MCStreamer &Out,
2303                                          bool HasTmpReg) {
2304   // The load/store pseudo-instruction does a pc-relative load with
2305   // a symbol.
2306   //
2307   // The expansion looks like this
2308   //
2309   //   TmpLabel: AUIPC tmp, %pcrel_hi(symbol)
2310   //             [S|L]X    rd, %pcrel_lo(TmpLabel)(tmp)
2311   MCOperand DestReg = Inst.getOperand(0);
2312   unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
2313   unsigned TmpRegOpIdx = HasTmpReg ? 1 : 0;
2314   MCOperand TmpReg = Inst.getOperand(TmpRegOpIdx);
2315   const MCExpr *Symbol = Inst.getOperand(SymbolOpIdx).getExpr();
2316   emitAuipcInstPair(DestReg, TmpReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI,
2317                     Opcode, IDLoc, Out);
2318 }
2319 
checkPseudoAddTPRel(MCInst & Inst,OperandVector & Operands)2320 bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
2321                                          OperandVector &Operands) {
2322   assert(Inst.getOpcode() == RISCV::PseudoAddTPRel && "Invalid instruction");
2323   assert(Inst.getOperand(2).isReg() && "Unexpected second operand kind");
2324   if (Inst.getOperand(2).getReg() != RISCV::X4) {
2325     SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();
2326     return Error(ErrorLoc, "the second input operand must be tp/x4 when using "
2327                            "%tprel_add modifier");
2328   }
2329 
2330   return false;
2331 }
2332 
defaultMaskRegOp() const2333 std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp() const {
2334   return RISCVOperand::createReg(RISCV::NoRegister, llvm::SMLoc(),
2335                                  llvm::SMLoc(), isRV64());
2336 }
2337 
validateInstruction(MCInst & Inst,OperandVector & Operands)2338 bool RISCVAsmParser::validateInstruction(MCInst &Inst,
2339                                          OperandVector &Operands) {
2340   const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
2341   unsigned TargetFlags =
2342       (MCID.TSFlags >> RISCV::ConstraintOffset) & RISCV::ConstraintMask;
2343   if (TargetFlags == RISCV::NoConstraint)
2344     return false;
2345 
2346   unsigned DestReg = Inst.getOperand(0).getReg();
2347   unsigned CheckReg;
2348   // Operands[1] will be the first operand, DestReg.
2349   SMLoc Loc = Operands[1]->getStartLoc();
2350   if (TargetFlags & RISCV::VS2Constraint) {
2351     CheckReg = Inst.getOperand(1).getReg();
2352     if (DestReg == CheckReg)
2353       return Error(Loc, "The destination vector register group cannot overlap"
2354                         " the source vector register group.");
2355   }
2356   if ((TargetFlags & RISCV::VS1Constraint) && (Inst.getOperand(2).isReg())) {
2357     CheckReg = Inst.getOperand(2).getReg();
2358     if (DestReg == CheckReg)
2359       return Error(Loc, "The destination vector register group cannot overlap"
2360                         " the source vector register group.");
2361   }
2362   if ((TargetFlags & RISCV::VMConstraint) && (DestReg == RISCV::V0)) {
2363     // vadc, vsbc are special cases. These instructions have no mask register.
2364     // The destination register could not be V0.
2365     unsigned Opcode = Inst.getOpcode();
2366     if (Opcode == RISCV::VADC_VVM || Opcode == RISCV::VADC_VXM ||
2367         Opcode == RISCV::VADC_VIM || Opcode == RISCV::VSBC_VVM ||
2368         Opcode == RISCV::VSBC_VXM)
2369       return Error(Loc, "The destination vector register group cannot be V0.");
2370 
2371     // Regardless masked or unmasked version, the number of operands is the
2372     // same. For example, "viota.m v0, v2" is "viota.m v0, v2, NoRegister"
2373     // actually. We need to check the last operand to ensure whether it is
2374     // masked or not.
2375     if ((TargetFlags & RISCV::OneInput) && (Inst.getNumOperands() == 3))
2376       CheckReg = Inst.getOperand(2).getReg();
2377     else if (Inst.getNumOperands() == 4)
2378       CheckReg = Inst.getOperand(3).getReg();
2379     if (DestReg == CheckReg)
2380       return Error(Loc, "The destination vector register group cannot overlap"
2381                         " the mask register.");
2382   }
2383   return false;
2384 }
2385 
processInstruction(MCInst & Inst,SMLoc IDLoc,OperandVector & Operands,MCStreamer & Out)2386 bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
2387                                         OperandVector &Operands,
2388                                         MCStreamer &Out) {
2389   Inst.setLoc(IDLoc);
2390 
2391   switch (Inst.getOpcode()) {
2392   default:
2393     break;
2394   case RISCV::PseudoLI: {
2395     Register Reg = Inst.getOperand(0).getReg();
2396     const MCOperand &Op1 = Inst.getOperand(1);
2397     if (Op1.isExpr()) {
2398       // We must have li reg, %lo(sym) or li reg, %pcrel_lo(sym) or similar.
2399       // Just convert to an addi. This allows compatibility with gas.
2400       emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
2401                               .addReg(Reg)
2402                               .addReg(RISCV::X0)
2403                               .addExpr(Op1.getExpr()));
2404       return false;
2405     }
2406     int64_t Imm = Inst.getOperand(1).getImm();
2407     // On RV32 the immediate here can either be a signed or an unsigned
2408     // 32-bit number. Sign extension has to be performed to ensure that Imm
2409     // represents the expected signed 64-bit number.
2410     if (!isRV64())
2411       Imm = SignExtend64<32>(Imm);
2412     emitLoadImm(Reg, Imm, Out);
2413     return false;
2414   }
2415   case RISCV::PseudoLLA:
2416     emitLoadLocalAddress(Inst, IDLoc, Out);
2417     return false;
2418   case RISCV::PseudoLA:
2419     emitLoadAddress(Inst, IDLoc, Out);
2420     return false;
2421   case RISCV::PseudoLA_TLS_IE:
2422     emitLoadTLSIEAddress(Inst, IDLoc, Out);
2423     return false;
2424   case RISCV::PseudoLA_TLS_GD:
2425     emitLoadTLSGDAddress(Inst, IDLoc, Out);
2426     return false;
2427   case RISCV::PseudoLB:
2428     emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out, /*HasTmpReg=*/false);
2429     return false;
2430   case RISCV::PseudoLBU:
2431     emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out, /*HasTmpReg=*/false);
2432     return false;
2433   case RISCV::PseudoLH:
2434     emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out, /*HasTmpReg=*/false);
2435     return false;
2436   case RISCV::PseudoLHU:
2437     emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out, /*HasTmpReg=*/false);
2438     return false;
2439   case RISCV::PseudoLW:
2440     emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out, /*HasTmpReg=*/false);
2441     return false;
2442   case RISCV::PseudoLWU:
2443     emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out, /*HasTmpReg=*/false);
2444     return false;
2445   case RISCV::PseudoLD:
2446     emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out, /*HasTmpReg=*/false);
2447     return false;
2448   case RISCV::PseudoFLW:
2449     emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out, /*HasTmpReg=*/true);
2450     return false;
2451   case RISCV::PseudoFLD:
2452     emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out, /*HasTmpReg=*/true);
2453     return false;
2454   case RISCV::PseudoSB:
2455     emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out, /*HasTmpReg=*/true);
2456     return false;
2457   case RISCV::PseudoSH:
2458     emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out, /*HasTmpReg=*/true);
2459     return false;
2460   case RISCV::PseudoSW:
2461     emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out, /*HasTmpReg=*/true);
2462     return false;
2463   case RISCV::PseudoSD:
2464     emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out, /*HasTmpReg=*/true);
2465     return false;
2466   case RISCV::PseudoFSW:
2467     emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out, /*HasTmpReg=*/true);
2468     return false;
2469   case RISCV::PseudoFSD:
2470     emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out, /*HasTmpReg=*/true);
2471     return false;
2472   case RISCV::PseudoAddTPRel:
2473     if (checkPseudoAddTPRel(Inst, Operands))
2474       return true;
2475     break;
2476   }
2477 
2478   emitToStreamer(Out, Inst);
2479   return false;
2480 }
2481 
LLVMInitializeRISCVAsmParser()2482 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVAsmParser() {
2483   RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target());
2484   RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target());
2485 }
2486