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