LLVM  7.0.0svn
RISCVAsmParser.cpp
Go to the documentation of this file.
1 //===-- RISCVAsmParser.cpp - Parse RISCV assembly to MCInst instructions --===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
14 #include "llvm/ADT/STLExtras.h"
15 #include "llvm/ADT/StringSwitch.h"
16 #include "llvm/MC/MCContext.h"
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/MC/MCInstBuilder.h"
23 #include "llvm/MC/MCRegisterInfo.h"
24 #include "llvm/MC/MCStreamer.h"
26 #include "llvm/Support/Casting.h"
29 
30 #include <limits>
31 
32 using namespace llvm;
33 
34 // Include the auto-generated portion of the compress emitter.
35 #define GEN_COMPRESS_INSTR
36 #include "RISCVGenCompressInstEmitter.inc"
37 
38 namespace {
39 struct RISCVOperand;
40 
41 class RISCVAsmParser : public MCTargetAsmParser {
42  SMLoc getLoc() const { return getParser().getTok().getLoc(); }
43  bool isRV64() const { return getSTI().hasFeature(RISCV::Feature64Bit); }
44 
45  RISCVTargetStreamer &getTargetStreamer() {
46  MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
47  return static_cast<RISCVTargetStreamer &>(TS);
48  }
49 
50  unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
51  unsigned Kind) override;
52 
53  bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo,
54  int64_t Lower, int64_t Upper, Twine Msg);
55 
56  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
57  OperandVector &Operands, MCStreamer &Out,
58  uint64_t &ErrorInfo,
59  bool MatchingInlineAsm) override;
60 
61  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
62 
63  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
64  SMLoc NameLoc, OperandVector &Operands) override;
65 
66  bool ParseDirective(AsmToken DirectiveID) override;
67 
68  // Helper to actually emit an instruction to the MCStreamer. Also, when
69  // possible, compression of the instruction is performed.
70  void emitToStreamer(MCStreamer &S, const MCInst &Inst);
71 
72  // Helper to emit a combination of LUI, ADDI(W), and SLLI instructions that
73  // synthesize the desired immedate value into the destination register.
74  void emitLoadImm(unsigned DestReg, int64_t Value, MCStreamer &Out);
75 
76  /// Helper for processing MC instructions that have been successfully matched
77  /// by MatchAndEmitInstruction. Modifications to the emitted instructions,
78  /// like the expansion of pseudo instructions (e.g., "li"), can be performed
79  /// in this method.
80  bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
81 
82 // Auto-generated instruction matching functions
83 #define GET_ASSEMBLER_HEADER
84 #include "RISCVGenAsmMatcher.inc"
85 
86  OperandMatchResultTy parseImmediate(OperandVector &Operands);
87  OperandMatchResultTy parseRegister(OperandVector &Operands,
88  bool AllowParens = false);
89  OperandMatchResultTy parseMemOpBaseReg(OperandVector &Operands);
90  OperandMatchResultTy parseOperandWithModifier(OperandVector &Operands);
91 
92  bool parseOperand(OperandVector &Operands, bool ForceImmediate);
93 
94  bool parseDirectiveOption();
95 
96  void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
97  if (!(getSTI().getFeatureBits()[Feature])) {
98  MCSubtargetInfo &STI = copySTI();
99  setAvailableFeatures(
100  ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
101  }
102  }
103 
104  void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
105  if (getSTI().getFeatureBits()[Feature]) {
106  MCSubtargetInfo &STI = copySTI();
107  setAvailableFeatures(
108  ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
109  }
110  }
111 public:
112  enum RISCVMatchResultTy {
113  Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
114 #define GET_OPERAND_DIAGNOSTIC_TYPES
115 #include "RISCVGenAsmMatcher.inc"
116 #undef GET_OPERAND_DIAGNOSTIC_TYPES
117  };
118 
119  static bool classifySymbolRef(const MCExpr *Expr,
121  int64_t &Addend);
122 
123  RISCVAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
124  const MCInstrInfo &MII, const MCTargetOptions &Options)
125  : MCTargetAsmParser(Options, STI, MII) {
126  Parser.addAliasForDirective(".half", ".2byte");
127  Parser.addAliasForDirective(".hword", ".2byte");
128  Parser.addAliasForDirective(".word", ".4byte");
129  Parser.addAliasForDirective(".dword", ".8byte");
130  setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
131  }
132 };
133 
134 /// RISCVOperand - Instances of this class represent a parsed machine
135 /// instruction
136 struct RISCVOperand : public MCParsedAsmOperand {
137 
138  enum KindTy {
139  Token,
140  Register,
141  Immediate,
142  } Kind;
143 
144  bool IsRV64;
145 
146  struct RegOp {
147  unsigned RegNum;
148  };
149 
150  struct ImmOp {
151  const MCExpr *Val;
152  };
153 
154  SMLoc StartLoc, EndLoc;
155  union {
156  StringRef Tok;
157  RegOp Reg;
158  ImmOp Imm;
159  };
160 
161  RISCVOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
162 
163 public:
164  RISCVOperand(const RISCVOperand &o) : MCParsedAsmOperand() {
165  Kind = o.Kind;
166  IsRV64 = o.IsRV64;
167  StartLoc = o.StartLoc;
168  EndLoc = o.EndLoc;
169  switch (Kind) {
170  case Register:
171  Reg = o.Reg;
172  break;
173  case Immediate:
174  Imm = o.Imm;
175  break;
176  case Token:
177  Tok = o.Tok;
178  break;
179  }
180  }
181 
182  bool isToken() const override { return Kind == Token; }
183  bool isReg() const override { return Kind == Register; }
184  bool isImm() const override { return Kind == Immediate; }
185  bool isMem() const override { return false; }
186 
187  bool evaluateConstantImm(int64_t &Imm, RISCVMCExpr::VariantKind &VK) const {
188  const MCExpr *Val = getImm();
189  bool Ret = false;
190  if (auto *RE = dyn_cast<RISCVMCExpr>(Val)) {
191  Ret = RE->evaluateAsConstant(Imm);
192  VK = RE->getKind();
193  } else if (auto CE = dyn_cast<MCConstantExpr>(Val)) {
194  Ret = true;
196  Imm = CE->getValue();
197  }
198  return Ret;
199  }
200 
201  // True if operand is a symbol with no modifiers, or a constant with no
202  // modifiers and isShiftedInt<N-1, 1>(Op).
203  template <int N> bool isBareSimmNLsb0() const {
204  int64_t Imm;
206  if (!isImm())
207  return false;
208  bool IsConstantImm = evaluateConstantImm(Imm, VK);
209  bool IsValid;
210  if (!IsConstantImm)
211  IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
212  else
213  IsValid = isShiftedInt<N - 1, 1>(Imm);
214  return IsValid && VK == RISCVMCExpr::VK_RISCV_None;
215  }
216 
217  // Predicate methods for AsmOperands defined in RISCVInstrInfo.td
218 
219  bool isBareSymbol() const {
220  int64_t Imm;
222  // Must be of 'immediate' type but not a constant.
223  if (!isImm() || evaluateConstantImm(Imm, VK))
224  return false;
225  return RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm) &&
227  }
228 
229  /// Return true if the operand is a valid for the fence instruction e.g.
230  /// ('iorw').
231  bool isFenceArg() const {
232  if (!isImm())
233  return false;
234  const MCExpr *Val = getImm();
235  auto *SVal = dyn_cast<MCSymbolRefExpr>(Val);
236  if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None)
237  return false;
238 
239  StringRef Str = SVal->getSymbol().getName();
240  // Letters must be unique, taken from 'iorw', and in ascending order. This
241  // holds as long as each individual character is one of 'iorw' and is
242  // greater than the previous character.
243  char Prev = '\0';
244  for (char c : Str) {
245  if (c != 'i' && c != 'o' && c != 'r' && c != 'w')
246  return false;
247  if (c <= Prev)
248  return false;
249  Prev = c;
250  }
251  return true;
252  }
253 
254  /// Return true if the operand is a valid floating point rounding mode.
255  bool isFRMArg() const {
256  if (!isImm())
257  return false;
258  const MCExpr *Val = getImm();
259  auto *SVal = dyn_cast<MCSymbolRefExpr>(Val);
260  if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None)
261  return false;
262 
263  StringRef Str = SVal->getSymbol().getName();
264 
266  }
267 
268  bool isImmXLen() const {
269  int64_t Imm;
271  if (!isImm())
272  return false;
273  bool IsConstantImm = evaluateConstantImm(Imm, VK);
274  // Given only Imm, ensuring that the actually specified constant is either
275  // a signed or unsigned 64-bit number is unfortunately impossible.
276  bool IsInRange = isRV64() ? true : isInt<32>(Imm) || isUInt<32>(Imm);
277  return IsConstantImm && IsInRange && VK == RISCVMCExpr::VK_RISCV_None;
278  }
279 
280  bool isUImmLog2XLen() const {
281  int64_t Imm;
283  if (!isImm())
284  return false;
285  if (!evaluateConstantImm(Imm, VK) || VK != RISCVMCExpr::VK_RISCV_None)
286  return false;
287  return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm);
288  }
289 
290  bool isUImmLog2XLenNonZero() const {
291  int64_t Imm;
293  if (!isImm())
294  return false;
295  if (!evaluateConstantImm(Imm, VK) || VK != RISCVMCExpr::VK_RISCV_None)
296  return false;
297  if (Imm == 0)
298  return false;
299  return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm);
300  }
301 
302  bool isUImm5() const {
303  int64_t Imm;
305  if (!isImm())
306  return false;
307  bool IsConstantImm = evaluateConstantImm(Imm, VK);
308  return IsConstantImm && isUInt<5>(Imm) && VK == RISCVMCExpr::VK_RISCV_None;
309  }
310 
311  bool isUImm5NonZero() const {
312  int64_t Imm;
314  if (!isImm())
315  return false;
316  bool IsConstantImm = evaluateConstantImm(Imm, VK);
317  return IsConstantImm && isUInt<5>(Imm) && (Imm != 0) &&
319  }
320 
321  bool isSImm6() const {
323  int64_t Imm;
324  bool IsValid;
325  bool IsConstantImm = evaluateConstantImm(Imm, VK);
326  if (!IsConstantImm)
327  IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
328  else
329  IsValid = isInt<6>(Imm);
330  return IsValid &&
332  }
333 
334  bool isSImm6NonZero() const {
336  int64_t Imm;
337  bool IsValid;
338  bool IsConstantImm = evaluateConstantImm(Imm, VK);
339  if (!IsConstantImm)
340  IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
341  else
342  IsValid = ((Imm != 0) && isInt<6>(Imm));
343  return IsValid &&
345  }
346 
347  bool isCLUIImm() const {
348  int64_t Imm;
350  bool IsConstantImm = evaluateConstantImm(Imm, VK);
351  return IsConstantImm && (Imm != 0) &&
352  (isUInt<5>(Imm) || (Imm >= 0xfffe0 && Imm <= 0xfffff)) &&
354  }
355 
356  bool isUImm7Lsb00() const {
357  int64_t Imm;
359  bool IsConstantImm = evaluateConstantImm(Imm, VK);
360  return IsConstantImm && isShiftedUInt<5, 2>(Imm) &&
362  }
363 
364  bool isUImm8Lsb00() const {
365  int64_t Imm;
367  bool IsConstantImm = evaluateConstantImm(Imm, VK);
368  return IsConstantImm && isShiftedUInt<6, 2>(Imm) &&
370  }
371 
372  bool isUImm8Lsb000() const {
373  int64_t Imm;
375  bool IsConstantImm = evaluateConstantImm(Imm, VK);
376  return IsConstantImm && isShiftedUInt<5, 3>(Imm) &&
378  }
379 
380  bool isSImm9Lsb0() const { return isBareSimmNLsb0<9>(); }
381 
382  bool isUImm9Lsb000() const {
383  int64_t Imm;
385  bool IsConstantImm = evaluateConstantImm(Imm, VK);
386  return IsConstantImm && isShiftedUInt<6, 3>(Imm) &&
388  }
389 
390  bool isUImm10Lsb00NonZero() const {
391  int64_t Imm;
393  bool IsConstantImm = evaluateConstantImm(Imm, VK);
394  return IsConstantImm && isShiftedUInt<8, 2>(Imm) && (Imm != 0) &&
396  }
397 
398  bool isSImm12() const {
400  int64_t Imm;
401  bool IsValid;
402  if (!isImm())
403  return false;
404  bool IsConstantImm = evaluateConstantImm(Imm, VK);
405  if (!IsConstantImm)
406  IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
407  else
408  IsValid = isInt<12>(Imm);
409  return IsValid && (VK == RISCVMCExpr::VK_RISCV_None ||
410  VK == RISCVMCExpr::VK_RISCV_LO ||
412  }
413 
414  bool isSImm12Lsb0() const { return isBareSimmNLsb0<12>(); }
415 
416  bool isUImm12() const {
417  int64_t Imm;
419  if (!isImm())
420  return false;
421  bool IsConstantImm = evaluateConstantImm(Imm, VK);
422  return IsConstantImm && isUInt<12>(Imm) && VK == RISCVMCExpr::VK_RISCV_None;
423  }
424 
425  bool isSImm13Lsb0() const { return isBareSimmNLsb0<13>(); }
426 
427  bool isSImm10Lsb0000NonZero() const {
428  int64_t Imm;
430  bool IsConstantImm = evaluateConstantImm(Imm, VK);
431  return IsConstantImm && (Imm != 0) && isShiftedInt<6, 4>(Imm) &&
433  }
434 
435  bool isUImm20() const {
437  int64_t Imm;
438  bool IsValid;
439  if (!isImm())
440  return false;
441  bool IsConstantImm = evaluateConstantImm(Imm, VK);
442  if (!IsConstantImm)
443  IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
444  else
445  IsValid = isUInt<20>(Imm);
446  return IsValid && (VK == RISCVMCExpr::VK_RISCV_None ||
447  VK == RISCVMCExpr::VK_RISCV_HI ||
449  }
450 
451  bool isSImm21Lsb0() const { return isBareSimmNLsb0<21>(); }
452 
453  /// getStartLoc - Gets location of the first token of this operand
454  SMLoc getStartLoc() const override { return StartLoc; }
455  /// getEndLoc - Gets location of the last token of this operand
456  SMLoc getEndLoc() const override { return EndLoc; }
457  /// True if this operand is for an RV64 instruction
458  bool isRV64() const { return IsRV64; }
459 
460  unsigned getReg() const override {
461  assert(Kind == Register && "Invalid type access!");
462  return Reg.RegNum;
463  }
464 
465  const MCExpr *getImm() const {
466  assert(Kind == Immediate && "Invalid type access!");
467  return Imm.Val;
468  }
469 
470  StringRef getToken() const {
471  assert(Kind == Token && "Invalid type access!");
472  return Tok;
473  }
474 
475  void print(raw_ostream &OS) const override {
476  switch (Kind) {
477  case Immediate:
478  OS << *getImm();
479  break;
480  case Register:
481  OS << "<register x";
482  OS << getReg() << ">";
483  break;
484  case Token:
485  OS << "'" << getToken() << "'";
486  break;
487  }
488  }
489 
490  static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S,
491  bool IsRV64) {
492  auto Op = make_unique<RISCVOperand>(Token);
493  Op->Tok = Str;
494  Op->StartLoc = S;
495  Op->EndLoc = S;
496  Op->IsRV64 = IsRV64;
497  return Op;
498  }
499 
500  static std::unique_ptr<RISCVOperand> createReg(unsigned RegNo, SMLoc S,
501  SMLoc E, bool IsRV64) {
502  auto Op = make_unique<RISCVOperand>(Register);
503  Op->Reg.RegNum = RegNo;
504  Op->StartLoc = S;
505  Op->EndLoc = E;
506  Op->IsRV64 = IsRV64;
507  return Op;
508  }
509 
510  static std::unique_ptr<RISCVOperand> createImm(const MCExpr *Val, SMLoc S,
511  SMLoc E, bool IsRV64) {
512  auto Op = make_unique<RISCVOperand>(Immediate);
513  Op->Imm.Val = Val;
514  Op->StartLoc = S;
515  Op->EndLoc = E;
516  Op->IsRV64 = IsRV64;
517  return Op;
518  }
519 
520  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
521  assert(Expr && "Expr shouldn't be null!");
522  int64_t Imm = 0;
523  bool IsConstant = false;
524  if (auto *RE = dyn_cast<RISCVMCExpr>(Expr)) {
525  IsConstant = RE->evaluateAsConstant(Imm);
526  } else if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) {
527  IsConstant = true;
528  Imm = CE->getValue();
529  }
530 
531  if (IsConstant)
532  Inst.addOperand(MCOperand::createImm(Imm));
533  else
534  Inst.addOperand(MCOperand::createExpr(Expr));
535  }
536 
537  // Used by the TableGen Code
538  void addRegOperands(MCInst &Inst, unsigned N) const {
539  assert(N == 1 && "Invalid number of operands!");
541  }
542 
543  void addImmOperands(MCInst &Inst, unsigned N) const {
544  assert(N == 1 && "Invalid number of operands!");
545  addExpr(Inst, getImm());
546  }
547 
548  void addFenceArgOperands(MCInst &Inst, unsigned N) const {
549  assert(N == 1 && "Invalid number of operands!");
550  // isFenceArg has validated the operand, meaning this cast is safe
551  auto SE = cast<MCSymbolRefExpr>(getImm());
552 
553  unsigned Imm = 0;
554  for (char c : SE->getSymbol().getName()) {
555  switch (c) {
556  default: llvm_unreachable("FenceArg must contain only [iorw]");
557  case 'i': Imm |= RISCVFenceField::I; break;
558  case 'o': Imm |= RISCVFenceField::O; break;
559  case 'r': Imm |= RISCVFenceField::R; break;
560  case 'w': Imm |= RISCVFenceField::W; break;
561  }
562  }
563  Inst.addOperand(MCOperand::createImm(Imm));
564  }
565 
566  // Returns the rounding mode represented by this RISCVOperand. Should only
567  // be called after checking isFRMArg.
568  RISCVFPRndMode::RoundingMode getRoundingMode() const {
569  // isFRMArg has validated the operand, meaning this cast is safe.
570  auto SE = cast<MCSymbolRefExpr>(getImm());
572  RISCVFPRndMode::stringToRoundingMode(SE->getSymbol().getName());
573  assert(FRM != RISCVFPRndMode::Invalid && "Invalid rounding mode");
574  return FRM;
575  }
576 
577  void addFRMArgOperands(MCInst &Inst, unsigned N) const {
578  assert(N == 1 && "Invalid number of operands!");
579  Inst.addOperand(MCOperand::createImm(getRoundingMode()));
580  }
581 };
582 } // end anonymous namespace.
583 
584 #define GET_REGISTER_MATCHER
585 #define GET_MATCHER_IMPLEMENTATION
586 #include "RISCVGenAsmMatcher.inc"
587 
588 // Return the matching FPR64 register for the given FPR32.
589 // FIXME: Ideally this function could be removed in favour of using
590 // information from TableGen.
591 unsigned convertFPR32ToFPR64(unsigned Reg) {
592  switch (Reg) {
593  default:
594  llvm_unreachable("Not a recognised FPR32 register");
595  case RISCV::F0_32: return RISCV::F0_64;
596  case RISCV::F1_32: return RISCV::F1_64;
597  case RISCV::F2_32: return RISCV::F2_64;
598  case RISCV::F3_32: return RISCV::F3_64;
599  case RISCV::F4_32: return RISCV::F4_64;
600  case RISCV::F5_32: return RISCV::F5_64;
601  case RISCV::F6_32: return RISCV::F6_64;
602  case RISCV::F7_32: return RISCV::F7_64;
603  case RISCV::F8_32: return RISCV::F8_64;
604  case RISCV::F9_32: return RISCV::F9_64;
605  case RISCV::F10_32: return RISCV::F10_64;
606  case RISCV::F11_32: return RISCV::F11_64;
607  case RISCV::F12_32: return RISCV::F12_64;
608  case RISCV::F13_32: return RISCV::F13_64;
609  case RISCV::F14_32: return RISCV::F14_64;
610  case RISCV::F15_32: return RISCV::F15_64;
611  case RISCV::F16_32: return RISCV::F16_64;
612  case RISCV::F17_32: return RISCV::F17_64;
613  case RISCV::F18_32: return RISCV::F18_64;
614  case RISCV::F19_32: return RISCV::F19_64;
615  case RISCV::F20_32: return RISCV::F20_64;
616  case RISCV::F21_32: return RISCV::F21_64;
617  case RISCV::F22_32: return RISCV::F22_64;
618  case RISCV::F23_32: return RISCV::F23_64;
619  case RISCV::F24_32: return RISCV::F24_64;
620  case RISCV::F25_32: return RISCV::F25_64;
621  case RISCV::F26_32: return RISCV::F26_64;
622  case RISCV::F27_32: return RISCV::F27_64;
623  case RISCV::F28_32: return RISCV::F28_64;
624  case RISCV::F29_32: return RISCV::F29_64;
625  case RISCV::F30_32: return RISCV::F30_64;
626  case RISCV::F31_32: return RISCV::F31_64;
627  }
628 }
629 
630 unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
631  unsigned Kind) {
632  RISCVOperand &Op = static_cast<RISCVOperand &>(AsmOp);
633  if (!Op.isReg())
634  return Match_InvalidOperand;
635 
636  unsigned Reg = Op.getReg();
637  bool IsRegFPR32 =
638  RISCVMCRegisterClasses[RISCV::FPR32RegClassID].contains(Reg);
639  bool IsRegFPR32C =
640  RISCVMCRegisterClasses[RISCV::FPR32CRegClassID].contains(Reg);
641 
642  // As the parser couldn't differentiate an FPR32 from an FPR64, coerce the
643  // register from FPR32 to FPR64 or FPR32C to FPR64C if necessary.
644  if ((IsRegFPR32 && Kind == MCK_FPR64) ||
645  (IsRegFPR32C && Kind == MCK_FPR64C)) {
646  Op.Reg.RegNum = convertFPR32ToFPR64(Reg);
647  return Match_Success;
648  }
649  return Match_InvalidOperand;
650 }
651 
652 bool RISCVAsmParser::generateImmOutOfRangeError(
653  OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper,
654  Twine Msg = "immediate must be an integer in the range") {
655  SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
656  return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]");
657 }
658 
659 bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
660  OperandVector &Operands,
661  MCStreamer &Out,
662  uint64_t &ErrorInfo,
663  bool MatchingInlineAsm) {
664  MCInst Inst;
665 
666  switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
667  default:
668  break;
669  case Match_Success:
670  return processInstruction(Inst, IDLoc, Out);
671  case Match_MissingFeature:
672  return Error(IDLoc, "instruction use requires an option to be enabled");
673  case Match_MnemonicFail:
674  return Error(IDLoc, "unrecognized instruction mnemonic");
675  case Match_InvalidOperand: {
676  SMLoc ErrorLoc = IDLoc;
677  if (ErrorInfo != ~0U) {
678  if (ErrorInfo >= Operands.size())
679  return Error(ErrorLoc, "too few operands for instruction");
680 
681  ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
682  if (ErrorLoc == SMLoc())
683  ErrorLoc = IDLoc;
684  }
685  return Error(ErrorLoc, "invalid operand for instruction");
686  }
687  case Match_InvalidImmXLen:
688  if (isRV64()) {
689  SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
690  return Error(ErrorLoc, "operand must be a constant 64-bit integer");
691  }
692  return generateImmOutOfRangeError(Operands, ErrorInfo,
693  std::numeric_limits<int32_t>::min(),
695  case Match_InvalidUImmLog2XLen:
696  if (isRV64())
697  return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
698  return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
699  case Match_InvalidUImmLog2XLenNonZero:
700  if (isRV64())
701  return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1);
702  return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
703  case Match_InvalidUImm5:
704  return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
705  case Match_InvalidSImm6:
706  return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5),
707  (1 << 5) - 1);
708  case Match_InvalidSImm6NonZero:
709  return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5),
710  (1 << 5) - 1,
711  "immediate must be non-zero in the range");
712  case Match_InvalidCLUIImm:
713  return generateImmOutOfRangeError(
714  Operands, ErrorInfo, 1, (1 << 5) - 1,
715  "immediate must be in [0xfffe0, 0xfffff] or");
716  case Match_InvalidUImm7Lsb00:
717  return generateImmOutOfRangeError(
718  Operands, ErrorInfo, 0, (1 << 7) - 4,
719  "immediate must be a multiple of 4 bytes in the range");
720  case Match_InvalidUImm8Lsb00:
721  return generateImmOutOfRangeError(
722  Operands, ErrorInfo, 0, (1 << 8) - 4,
723  "immediate must be a multiple of 4 bytes in the range");
724  case Match_InvalidUImm8Lsb000:
725  return generateImmOutOfRangeError(
726  Operands, ErrorInfo, 0, (1 << 8) - 8,
727  "immediate must be a multiple of 8 bytes in the range");
728  case Match_InvalidSImm9Lsb0:
729  return generateImmOutOfRangeError(
730  Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2,
731  "immediate must be a multiple of 2 bytes in the range");
732  case Match_InvalidUImm9Lsb000:
733  return generateImmOutOfRangeError(
734  Operands, ErrorInfo, 0, (1 << 9) - 8,
735  "immediate must be a multiple of 8 bytes in the range");
736  case Match_InvalidUImm10Lsb00NonZero:
737  return generateImmOutOfRangeError(
738  Operands, ErrorInfo, 4, (1 << 10) - 4,
739  "immediate must be a multiple of 4 bytes in the range");
740  case Match_InvalidSImm10Lsb0000NonZero:
741  return generateImmOutOfRangeError(
742  Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
743  "immediate must be a multiple of 16 bytes and non-zero in the range");
744  case Match_InvalidSImm12:
745  return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 11),
746  (1 << 11) - 1);
747  case Match_InvalidSImm12Lsb0:
748  return generateImmOutOfRangeError(
749  Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2,
750  "immediate must be a multiple of 2 bytes in the range");
751  case Match_InvalidUImm12:
752  return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1);
753  case Match_InvalidSImm13Lsb0:
754  return generateImmOutOfRangeError(
755  Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2,
756  "immediate must be a multiple of 2 bytes in the range");
757  case Match_InvalidUImm20:
758  return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1);
759  case Match_InvalidSImm21Lsb0:
760  return generateImmOutOfRangeError(
761  Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2,
762  "immediate must be a multiple of 2 bytes in the range");
763  case Match_InvalidFenceArg: {
764  SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
765  return Error(
766  ErrorLoc,
767  "operand must be formed of letters selected in-order from 'iorw'");
768  }
769  case Match_InvalidFRMArg: {
770  SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
771  return Error(
772  ErrorLoc,
773  "operand must be a valid floating point rounding mode mnemonic");
774  }
775  case Match_InvalidBareSymbol: {
776  SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
777  return Error(ErrorLoc, "operand must be a bare symbol name");
778  }
779  }
780 
781  llvm_unreachable("Unknown match type detected!");
782 }
783 
784 bool RISCVAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
785  SMLoc &EndLoc) {
786  const AsmToken &Tok = getParser().getTok();
787  StartLoc = Tok.getLoc();
788  EndLoc = Tok.getEndLoc();
789  RegNo = 0;
790  StringRef Name = getLexer().getTok().getIdentifier();
791 
792  if (!MatchRegisterName(Name) || !MatchRegisterAltName(Name)) {
793  getParser().Lex(); // Eat identifier token.
794  return false;
795  }
796 
797  return Error(StartLoc, "invalid register name");
798 }
799 
800 OperandMatchResultTy RISCVAsmParser::parseRegister(OperandVector &Operands,
801  bool AllowParens) {
802  SMLoc FirstS = getLoc();
803  bool HadParens = false;
804  AsmToken Buf[2];
805 
806  // If this a parenthesised register name is allowed, parse it atomically
807  if (AllowParens && getLexer().is(AsmToken::LParen)) {
808  size_t ReadCount = getLexer().peekTokens(Buf);
809  if (ReadCount == 2 && Buf[1].getKind() == AsmToken::RParen) {
810  HadParens = true;
811  getParser().Lex(); // Eat '('
812  }
813  }
814 
815  switch (getLexer().getKind()) {
816  default:
817  return MatchOperand_NoMatch;
819  StringRef Name = getLexer().getTok().getIdentifier();
820  unsigned RegNo = MatchRegisterName(Name);
821  if (RegNo == 0) {
822  RegNo = MatchRegisterAltName(Name);
823  if (RegNo == 0) {
824  if (HadParens)
825  getLexer().UnLex(Buf[0]);
826  return MatchOperand_NoMatch;
827  }
828  }
829  if (HadParens)
830  Operands.push_back(RISCVOperand::createToken("(", FirstS, isRV64()));
831  SMLoc S = getLoc();
833  getLexer().Lex();
834  Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64()));
835  }
836 
837  if (HadParens) {
838  getParser().Lex(); // Eat ')'
839  Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64()));
840  }
841 
842  return MatchOperand_Success;
843 }
844 
845 OperandMatchResultTy RISCVAsmParser::parseImmediate(OperandVector &Operands) {
846  SMLoc S = getLoc();
848  const MCExpr *Res;
849 
850  switch (getLexer().getKind()) {
851  default:
852  return MatchOperand_NoMatch;
853  case AsmToken::LParen:
854  case AsmToken::Minus:
855  case AsmToken::Plus:
856  case AsmToken::Integer:
857  case AsmToken::String:
858  if (getParser().parseExpression(Res))
859  return MatchOperand_ParseFail;
860  break;
861  case AsmToken::Identifier: {
863  if (getParser().parseIdentifier(Identifier))
864  return MatchOperand_ParseFail;
865  MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
866  Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
867  break;
868  }
869  case AsmToken::Percent:
870  return parseOperandWithModifier(Operands);
871  }
872 
873  Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
874  return MatchOperand_Success;
875 }
876 
878 RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) {
879  SMLoc S = getLoc();
881 
882  if (getLexer().getKind() != AsmToken::Percent) {
883  Error(getLoc(), "expected '%' for operand modifier");
884  return MatchOperand_ParseFail;
885  }
886 
887  getParser().Lex(); // Eat '%'
888 
889  if (getLexer().getKind() != AsmToken::Identifier) {
890  Error(getLoc(), "expected valid identifier for operand modifier");
891  return MatchOperand_ParseFail;
892  }
893  StringRef Identifier = getParser().getTok().getIdentifier();
895  if (VK == RISCVMCExpr::VK_RISCV_Invalid) {
896  Error(getLoc(), "unrecognized operand modifier");
897  return MatchOperand_ParseFail;
898  }
899 
900  getParser().Lex(); // Eat the identifier
901  if (getLexer().getKind() != AsmToken::LParen) {
902  Error(getLoc(), "expected '('");
903  return MatchOperand_ParseFail;
904  }
905  getParser().Lex(); // Eat '('
906 
907  const MCExpr *SubExpr;
908  if (getParser().parseParenExpression(SubExpr, E)) {
909  return MatchOperand_ParseFail;
910  }
911 
912  const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, VK, getContext());
913  Operands.push_back(RISCVOperand::createImm(ModExpr, S, E, isRV64()));
914  return MatchOperand_Success;
915 }
916 
918 RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) {
919  if (getLexer().isNot(AsmToken::LParen)) {
920  Error(getLoc(), "expected '('");
921  return MatchOperand_ParseFail;
922  }
923 
924  getParser().Lex(); // Eat '('
925  Operands.push_back(RISCVOperand::createToken("(", getLoc(), isRV64()));
926 
927  if (parseRegister(Operands) != MatchOperand_Success) {
928  Error(getLoc(), "expected register");
929  return MatchOperand_ParseFail;
930  }
931 
932  if (getLexer().isNot(AsmToken::RParen)) {
933  Error(getLoc(), "expected ')'");
934  return MatchOperand_ParseFail;
935  }
936 
937  getParser().Lex(); // Eat ')'
938  Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64()));
939 
940  return MatchOperand_Success;
941 }
942 
943 /// Looks at a token type and creates the relevant operand from this
944 /// information, adding to Operands. If operand was parsed, returns false, else
945 /// true. If ForceImmediate is true, no attempt will be made to parse the
946 /// operand as a register, which is needed for pseudoinstructions such as
947 /// call.
948 bool RISCVAsmParser::parseOperand(OperandVector &Operands,
949  bool ForceImmediate) {
950  // Attempt to parse token as register, unless ForceImmediate.
951  if (!ForceImmediate && parseRegister(Operands, true) == MatchOperand_Success)
952  return false;
953 
954  // Attempt to parse token as an immediate
955  if (parseImmediate(Operands) == MatchOperand_Success) {
956  // Parse memory base register if present
957  if (getLexer().is(AsmToken::LParen))
958  return parseMemOpBaseReg(Operands) != MatchOperand_Success;
959  return false;
960  }
961 
962  // Finally we have exhausted all options and must declare defeat.
963  Error(getLoc(), "unknown operand");
964  return true;
965 }
966 
967 bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info,
968  StringRef Name, SMLoc NameLoc,
969  OperandVector &Operands) {
970  // First operand is token for instruction
971  Operands.push_back(RISCVOperand::createToken(Name, NameLoc, isRV64()));
972 
973  // If there are no more operands, then finish
974  if (getLexer().is(AsmToken::EndOfStatement))
975  return false;
976 
977  // Parse first operand
978  bool ForceImmediate = (Name == "call" || Name == "tail");
979  if (parseOperand(Operands, ForceImmediate))
980  return true;
981 
982  // Parse until end of statement, consuming commas between operands
983  while (getLexer().is(AsmToken::Comma)) {
984  // Consume comma token
985  getLexer().Lex();
986 
987  // Parse next operand
988  if (parseOperand(Operands, false))
989  return true;
990  }
991 
992  if (getLexer().isNot(AsmToken::EndOfStatement)) {
993  SMLoc Loc = getLexer().getLoc();
994  getParser().eatToEndOfStatement();
995  return Error(Loc, "unexpected token");
996  }
997 
998  getParser().Lex(); // Consume the EndOfStatement.
999  return false;
1000 }
1001 
1002 bool RISCVAsmParser::classifySymbolRef(const MCExpr *Expr,
1004  int64_t &Addend) {
1006  Addend = 0;
1007 
1008  if (const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) {
1009  Kind = RE->getKind();
1010  Expr = RE->getSubExpr();
1011  }
1012 
1013  // It's a simple symbol reference or constant with no addend.
1014  if (isa<MCConstantExpr>(Expr) || isa<MCSymbolRefExpr>(Expr))
1015  return true;
1016 
1017  const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr);
1018  if (!BE)
1019  return false;
1020 
1021  if (!isa<MCSymbolRefExpr>(BE->getLHS()))
1022  return false;
1023 
1024  if (BE->getOpcode() != MCBinaryExpr::Add &&
1025  BE->getOpcode() != MCBinaryExpr::Sub)
1026  return false;
1027 
1028  // We are able to support the subtraction of two symbol references
1029  if (BE->getOpcode() == MCBinaryExpr::Sub &&
1030  isa<MCSymbolRefExpr>(BE->getRHS()))
1031  return true;
1032 
1033  // See if the addend is a constant, otherwise there's more going
1034  // on here than we can deal with.
1035  auto AddendExpr = dyn_cast<MCConstantExpr>(BE->getRHS());
1036  if (!AddendExpr)
1037  return false;
1038 
1039  Addend = AddendExpr->getValue();
1040  if (BE->getOpcode() == MCBinaryExpr::Sub)
1041  Addend = -Addend;
1042 
1043  // It's some symbol reference + a constant addend
1044  return Kind != RISCVMCExpr::VK_RISCV_Invalid;
1045 }
1046 
1047 bool RISCVAsmParser::ParseDirective(AsmToken DirectiveID) {
1048  // This returns false if this function recognizes the directive
1049  // regardless of whether it is successfully handles or reports an
1050  // error. Otherwise it returns true to give the generic parser a
1051  // chance at recognizing it.
1052  StringRef IDVal = DirectiveID.getString();
1053 
1054  if (IDVal == ".option")
1055  return parseDirectiveOption();
1056 
1057  return true;
1058 }
1059 
1060 bool RISCVAsmParser::parseDirectiveOption() {
1061  MCAsmParser &Parser = getParser();
1062  // Get the option token.
1063  AsmToken Tok = Parser.getTok();
1064  // At the moment only identifiers are supported.
1065  if (Tok.isNot(AsmToken::Identifier))
1066  return Error(Parser.getTok().getLoc(),
1067  "unexpected token, expected identifier");
1068 
1069  StringRef Option = Tok.getIdentifier();
1070 
1071  if (Option == "rvc") {
1072  getTargetStreamer().emitDirectiveOptionRVC();
1073 
1074  Parser.Lex();
1075  if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1076  return Error(Parser.getTok().getLoc(),
1077  "unexpected token, expected end of statement");
1078 
1079  setFeatureBits(RISCV::FeatureStdExtC, "c");
1080  return false;
1081  }
1082 
1083  if (Option == "norvc") {
1084  getTargetStreamer().emitDirectiveOptionNoRVC();
1085 
1086  Parser.Lex();
1087  if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1088  return Error(Parser.getTok().getLoc(),
1089  "unexpected token, expected end of statement");
1090 
1091  clearFeatureBits(RISCV::FeatureStdExtC, "c");
1092  return false;
1093  }
1094 
1095  // Unknown option.
1096  Warning(Parser.getTok().getLoc(),
1097  "unknown option, expected 'rvc' or 'norvc'");
1098  Parser.eatToEndOfStatement();
1099  return false;
1100 }
1101 
1102 void RISCVAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) {
1103  MCInst CInst;
1104  bool Res = compressInst(CInst, Inst, getSTI(), S.getContext());
1105  CInst.setLoc(Inst.getLoc());
1106  S.EmitInstruction((Res ? CInst : Inst), getSTI());
1107 }
1108 
1109 void RISCVAsmParser::emitLoadImm(unsigned DestReg, int64_t Value,
1110  MCStreamer &Out) {
1111  if (isInt<32>(Value)) {
1112  // Emits the MC instructions for loading a 32-bit constant into a register.
1113  //
1114  // Depending on the active bits in the immediate Value v, the following
1115  // instruction sequences are emitted:
1116  //
1117  // v == 0 : ADDI(W)
1118  // v[0,12) != 0 && v[12,32) == 0 : ADDI(W)
1119  // v[0,12) == 0 && v[12,32) != 0 : LUI
1120  // v[0,32) != 0 : LUI+ADDI(W)
1121  //
1122  int64_t Hi20 = ((Value + 0x800) >> 12) & 0xFFFFF;
1123  int64_t Lo12 = SignExtend64<12>(Value);
1124  unsigned SrcReg = RISCV::X0;
1125 
1126  if (Hi20) {
1127  emitToStreamer(Out,
1128  MCInstBuilder(RISCV::LUI).addReg(DestReg).addImm(Hi20));
1129  SrcReg = DestReg;
1130  }
1131 
1132  if (Lo12 || Hi20 == 0) {
1133  unsigned AddiOpcode =
1134  STI->hasFeature(RISCV::Feature64Bit) ? RISCV::ADDIW : RISCV::ADDI;
1135  emitToStreamer(Out, MCInstBuilder(AddiOpcode)
1136  .addReg(DestReg)
1137  .addReg(SrcReg)
1138  .addImm(Lo12));
1139  }
1140  return;
1141  }
1142  assert(STI->hasFeature(RISCV::Feature64Bit) &&
1143  "Target must be 64-bit to support a >32-bit constant");
1144 
1145  // In the worst case, for a full 64-bit constant, a sequence of 8 instructions
1146  // (i.e., LUI+ADDIW+SLLI+ADDI+SLLI+ADDI+SLLI+ADDI) has to be emmitted. Note
1147  // that the first two instructions (LUI+ADDIW) can contribute up to 32 bits
1148  // while the following ADDI instructions contribute up to 12 bits each.
1149  //
1150  // On the first glance, implementing this seems to be possible by simply
1151  // emitting the most significant 32 bits (LUI+ADDIW) followed by as many left
1152  // shift (SLLI) and immediate additions (ADDI) as needed. However, due to the
1153  // fact that ADDI performs a sign extended addition, doing it like that would
1154  // only be possible when at most 11 bits of the ADDI instructions are used.
1155  // Using all 12 bits of the ADDI instructions, like done by GAS, actually
1156  // requires that the constant is processed starting with the least significant
1157  // bit.
1158  //
1159  // In the following, constants are processed from LSB to MSB but instruction
1160  // emission is performed from MSB to LSB by recursively calling
1161  // emitLoadImm. In each recursion, first the lowest 12 bits are removed
1162  // from the constant and the optimal shift amount, which can be greater than
1163  // 12 bits if the constant is sparse, is determined. Then, the shifted
1164  // remaining constant is processed recursively and gets emitted as soon as it
1165  // fits into 32 bits. The emission of the shifts and additions is subsequently
1166  // performed when the recursion returns.
1167  //
1168  int64_t Lo12 = SignExtend64<12>(Value);
1169  int64_t Hi52 = (Value + 0x800) >> 12;
1170  int ShiftAmount = 12 + findFirstSet((uint64_t)Hi52);
1171  Hi52 = SignExtend64(Hi52 >> (ShiftAmount - 12), 64 - ShiftAmount);
1172 
1173  emitLoadImm(DestReg, Hi52, Out);
1174 
1175  emitToStreamer(Out, MCInstBuilder(RISCV::SLLI)
1176  .addReg(DestReg)
1177  .addReg(DestReg)
1178  .addImm(ShiftAmount));
1179 
1180  if (Lo12)
1181  emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
1182  .addReg(DestReg)
1183  .addReg(DestReg)
1184  .addImm(Lo12));
1185 }
1186 
1187 bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1188  MCStreamer &Out) {
1189  Inst.setLoc(IDLoc);
1190 
1191  if (Inst.getOpcode() == RISCV::PseudoLI) {
1192  auto Reg = Inst.getOperand(0).getReg();
1193  int64_t Imm = Inst.getOperand(1).getImm();
1194  // On RV32 the immediate here can either be a signed or an unsigned
1195  // 32-bit number. Sign extension has to be performed to ensure that Imm
1196  // represents the expected signed 64-bit number.
1197  if (!isRV64())
1198  Imm = SignExtend64<32>(Imm);
1199  emitLoadImm(Reg, Imm, Out);
1200  return false;
1201  }
1202 
1203  emitToStreamer(Out, Inst);
1204  return false;
1205 }
1206 
1207 extern "C" void LLVMInitializeRISCVAsmParser() {
1210 }
static bool isReg(const MCInst &MI, unsigned OpNo)
constexpr bool isUInt< 32 >(uint64_t x)
Definition: MathExtras.h:349
void push_back(const T &Elt)
Definition: SmallVector.h:213
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:111
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:321
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
unsigned convertFPR32ToFPR64(unsigned Reg)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:42
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
Definition: SmallVector.h:137
Generic assembler parser interface, for use by target specific assembly parsers.
Definition: MCAsmParser.h:110
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:137
MCTargetAsmParser - Generic interface to target specific assembly parsers.
static RoundingMode stringToRoundingMode(StringRef Str)
Definition: RISCVBaseInfo.h:97
Target specific streamer interface.
Definition: MCStreamer.h:83
unsigned Reg
bool isNot(TokenKind K) const
Definition: MCAsmMacro.h:84
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.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
Definition: MCAsmParser.cpp:34
virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, bool PrintSchedInfo=false)
Emit the given Instruction into the current section.
Definition: MCStreamer.cpp:907
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:100
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:116
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
const FeatureBitset & getFeatureBits() const
static unsigned MatchRegisterAltName(StringRef Name)
Maps from the set of all alternative registernames to a register number.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:36
Target independent representation for an assembler token.
Definition: MCAsmMacro.h:22
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:166
Target & getTheRISCV32Target()
static bool isMem(const MachineInstr &MI, unsigned Op)
Definition: X86InstrInfo.h:160
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand...
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:65
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
SMLoc getLoc() const
Definition: MCAsmLexer.cpp:28
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:161
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:76
const char * getPointer() const
Definition: SMLoc.h:35
int64_t getValue() const
Definition: MCExpr.h:152
Streaming machine code generation interface.
Definition: MCStreamer.h:183
MCTargetStreamer * getTargetStreamer()
Definition: MCStreamer.h:257
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
Definition: MathExtras.h:315
SMLoc getEndLoc() const
Definition: MCAsmLexer.cpp:32
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Target & getTheRISCV64Target()
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:24
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
Binary assembler expressions.
Definition: MCExpr.h:415
T findFirstSet(T Val, ZeroBehavior ZB=ZB_Max)
Get the index of the first set bit starting from the least significant bit.
Definition: MathExtras.h:203
void setLoc(SMLoc loc)
Definition: MCInst.h:179
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
MCStreamer & getStreamer()
Definition: MCStreamer.h:91
constexpr bool isInt< 32 >(int64_t x)
Definition: MathExtras.h:309
void LLVMInitializeRISCVAsmParser()
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:182
Promote Memory to Register
Definition: Mem2Reg.cpp:110
SMLoc getLoc() const
Definition: MCInst.h:180
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
Base class for user error types.
Definition: Error.h:339
static SMLoc getFromPointer(const char *Ptr)
Definition: SMLoc.h:37
Basic Alias true
static VariantKind getVariantKindForName(StringRef name)
Definition: RISCVMCExpr.cpp:70
#define N
bool hasFeature(unsigned Feature) const
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:323
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
Definition: MathExtras.h:749
Opcode getOpcode() const
Get the kind of this binary expression.
Definition: MCExpr.h:559
const unsigned Kind
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
Definition: Value.h:73
static unsigned MatchRegisterName(StringRef Name)
Maps from the set of all register names to a register number.
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:46
Subtraction.
Definition: MCExpr.h:439
void addOperand(const MCOperand &Op)
Definition: MCInst.h:186
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
Represents a location in source code.
Definition: SMLoc.h:24
unsigned getOpcode() const
Definition: MCInst.h:174
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:123
static const RISCVMCExpr * create(const MCExpr *Expr, VariantKind Kind, MCContext &Ctx)
Definition: RISCVMCExpr.cpp:29