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