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