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