LLVM  12.0.0git
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 "RISCVInstrInfo.h"
15 #include "Utils/RISCVBaseInfo.h"
16 #include "Utils/RISCVMatInt.h"
17 #include "llvm/ADT/STLExtras.h"
19 #include "llvm/ADT/SmallString.h"
20 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/ADT/Statistic.h"
22 #include "llvm/ADT/StringSwitch.h"
23 #include "llvm/CodeGen/Register.h"
24 #include "llvm/MC/MCAssembler.h"
25 #include "llvm/MC/MCContext.h"
26 #include "llvm/MC/MCExpr.h"
27 #include "llvm/MC/MCInst.h"
28 #include "llvm/MC/MCInstBuilder.h"
33 #include "llvm/MC/MCRegisterInfo.h"
34 #include "llvm/MC/MCStreamer.h"
36 #include "llvm/Support/Casting.h"
40 
41 #include <limits>
42 
43 using namespace llvm;
44 
45 #define DEBUG_TYPE "riscv-asm-parser"
46 
47 // Include the auto-generated portion of the compress emitter.
48 #define GEN_COMPRESS_INSTR
49 #include "RISCVGenCompressInstEmitter.inc"
50 
51 STATISTIC(RISCVNumInstrsCompressed,
52  "Number of RISC-V Compressed instructions emitted");
53 
54 namespace {
55 struct RISCVOperand;
56 
57 struct ParserOptionsSet {
58  bool IsPicEnabled;
59 };
60 
61 class RISCVAsmParser : public MCTargetAsmParser {
62  SmallVector<FeatureBitset, 4> FeatureBitStack;
63 
64  SmallVector<ParserOptionsSet, 4> ParserOptionsStack;
65  ParserOptionsSet ParserOptions;
66 
67  SMLoc getLoc() const { return getParser().getTok().getLoc(); }
68  bool isRV64() const { return getSTI().hasFeature(RISCV::Feature64Bit); }
69  bool isRV32E() const { return getSTI().hasFeature(RISCV::FeatureRV32E); }
70 
71  RISCVTargetStreamer &getTargetStreamer() {
72  MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
73  return static_cast<RISCVTargetStreamer &>(TS);
74  }
75 
76  unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
77  unsigned Kind) override;
78 
79  bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo,
80  int64_t Lower, int64_t Upper, Twine Msg);
81 
82  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
84  uint64_t &ErrorInfo,
85  bool MatchingInlineAsm) override;
86 
87  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
88  OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc,
89  SMLoc &EndLoc) override;
90 
91  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
92  SMLoc NameLoc, OperandVector &Operands) override;
93 
94  bool ParseDirective(AsmToken DirectiveID) override;
95 
96  // Helper to actually emit an instruction to the MCStreamer. Also, when
97  // possible, compression of the instruction is performed.
98  void emitToStreamer(MCStreamer &S, const MCInst &Inst);
99 
100  // Helper to emit a combination of LUI, ADDI(W), and SLLI instructions that
101  // synthesize the desired immedate value into the destination register.
102  void emitLoadImm(Register DestReg, int64_t Value, MCStreamer &Out);
103 
104  // Helper to emit a combination of AUIPC and SecondOpcode. Used to implement
105  // helpers such as emitLoadLocalAddress and emitLoadAddress.
106  void emitAuipcInstPair(MCOperand DestReg, MCOperand TmpReg,
108  unsigned SecondOpcode, SMLoc IDLoc, MCStreamer &Out);
109 
110  // Helper to emit pseudo instruction "lla" used in PC-rel addressing.
111  void emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
112 
113  // Helper to emit pseudo instruction "la" used in GOT/PC-rel addressing.
114  void emitLoadAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
115 
116  // Helper to emit pseudo instruction "la.tls.ie" used in initial-exec TLS
117  // addressing.
118  void emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
119 
120  // Helper to emit pseudo instruction "la.tls.gd" used in global-dynamic TLS
121  // addressing.
122  void emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
123 
124  // Helper to emit pseudo load/store instruction with a symbol.
125  void emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode, SMLoc IDLoc,
126  MCStreamer &Out, bool HasTmpReg);
127 
128  // Checks that a PseudoAddTPRel is using x4/tp in its second input operand.
129  // Enforcing this using a restricted register class for the second input
130  // operand of PseudoAddTPRel results in a poor diagnostic due to the fact
131  // 'add' is an overloaded mnemonic.
132  bool checkPseudoAddTPRel(MCInst &Inst, OperandVector &Operands);
133 
134  // Check instruction constraints.
135  bool validateInstruction(MCInst &Inst, OperandVector &Operands);
136 
137  /// Helper for processing MC instructions that have been successfully matched
138  /// by MatchAndEmitInstruction. Modifications to the emitted instructions,
139  /// like the expansion of pseudo instructions (e.g., "li"), can be performed
140  /// in this method.
141  bool processInstruction(MCInst &Inst, SMLoc IDLoc, OperandVector &Operands,
142  MCStreamer &Out);
143 
144 // Auto-generated instruction matching functions
145 #define GET_ASSEMBLER_HEADER
146 #include "RISCVGenAsmMatcher.inc"
147 
148  OperandMatchResultTy parseCSRSystemRegister(OperandVector &Operands);
151  bool AllowParens = false);
152  OperandMatchResultTy parseMemOpBaseReg(OperandVector &Operands);
153  OperandMatchResultTy parseAtomicMemOp(OperandVector &Operands);
154  OperandMatchResultTy parseOperandWithModifier(OperandVector &Operands);
155  OperandMatchResultTy parseBareSymbol(OperandVector &Operands);
156  OperandMatchResultTy parseCallSymbol(OperandVector &Operands);
157  OperandMatchResultTy parsePseudoJumpSymbol(OperandVector &Operands);
161 
162  bool parseOperand(OperandVector &Operands, StringRef Mnemonic);
163 
164  bool parseDirectiveOption();
165  bool parseDirectiveAttribute();
166 
167  void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
168  if (!(getSTI().getFeatureBits()[Feature])) {
169  MCSubtargetInfo &STI = copySTI();
170  setAvailableFeatures(
171  ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
172  }
173  }
174 
175  bool getFeatureBits(uint64_t Feature) {
176  return getSTI().getFeatureBits()[Feature];
177  }
178 
179  void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
180  if (getSTI().getFeatureBits()[Feature]) {
181  MCSubtargetInfo &STI = copySTI();
182  setAvailableFeatures(
183  ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
184  }
185  }
186 
187  void pushFeatureBits() {
188  assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
189  "These two stacks must be kept synchronized");
190  FeatureBitStack.push_back(getSTI().getFeatureBits());
191  ParserOptionsStack.push_back(ParserOptions);
192  }
193 
194  bool popFeatureBits() {
195  assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
196  "These two stacks must be kept synchronized");
197  if (FeatureBitStack.empty())
198  return true;
199 
200  FeatureBitset FeatureBits = FeatureBitStack.pop_back_val();
201  copySTI().setFeatureBits(FeatureBits);
202  setAvailableFeatures(ComputeAvailableFeatures(FeatureBits));
203 
204  ParserOptions = ParserOptionsStack.pop_back_val();
205 
206  return false;
207  }
208 
209  std::unique_ptr<RISCVOperand> defaultMaskRegOp() const;
210 
211 public:
212  enum RISCVMatchResultTy {
213  Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
214 #define GET_OPERAND_DIAGNOSTIC_TYPES
215 #include "RISCVGenAsmMatcher.inc"
216 #undef GET_OPERAND_DIAGNOSTIC_TYPES
217  };
218 
219  static bool classifySymbolRef(const MCExpr *Expr,
221  int64_t &Addend);
222 
223  RISCVAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
224  const MCInstrInfo &MII, const MCTargetOptions &Options)
225  : MCTargetAsmParser(Options, STI, MII) {
226  Parser.addAliasForDirective(".half", ".2byte");
227  Parser.addAliasForDirective(".hword", ".2byte");
228  Parser.addAliasForDirective(".word", ".4byte");
229  Parser.addAliasForDirective(".dword", ".8byte");
230  setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
231 
232  auto ABIName = StringRef(Options.ABIName);
233  if (ABIName.endswith("f") &&
234  !getSTI().getFeatureBits()[RISCV::FeatureStdExtF]) {
235  errs() << "Hard-float 'f' ABI can't be used for a target that "
236  "doesn't support the F instruction set extension (ignoring "
237  "target-abi)\n";
238  } else if (ABIName.endswith("d") &&
239  !getSTI().getFeatureBits()[RISCV::FeatureStdExtD]) {
240  errs() << "Hard-float 'd' ABI can't be used for a target that "
241  "doesn't support the D instruction set extension (ignoring "
242  "target-abi)\n";
243  }
244 
245  const MCObjectFileInfo *MOFI = Parser.getContext().getObjectFileInfo();
246  ParserOptions.IsPicEnabled = MOFI->isPositionIndependent();
247  }
248 };
249 
250 /// RISCVOperand - Instances of this class represent a parsed machine
251 /// instruction
252 struct RISCVOperand : public MCParsedAsmOperand {
253 
254  enum class KindTy {
255  Token,
256  Register,
257  Immediate,
258  SystemRegister,
259  VType,
260  } Kind;
261 
262  bool IsRV64;
263 
264  struct RegOp {
265  Register RegNum;
266  };
267 
268  struct ImmOp {
269  const MCExpr *Val;
270  };
271 
272  struct SysRegOp {
273  const char *Data;
274  unsigned Length;
275  unsigned Encoding;
276  // FIXME: Add the Encoding parsed fields as needed for checks,
277  // e.g.: read/write or user/supervisor/machine privileges.
278  };
279 
280  enum class VSEW {
281  SEW_8 = 0,
282  SEW_16,
283  SEW_32,
284  SEW_64,
285  SEW_128,
286  SEW_256,
287  SEW_512,
288  SEW_1024,
289  };
290 
291  enum class VLMUL { LMUL_1 = 0, LMUL_2, LMUL_4, LMUL_8 };
292 
293  struct VTypeOp {
294  VSEW Sew;
295  VLMUL Lmul;
296  unsigned Encoding;
297  };
298 
299  SMLoc StartLoc, EndLoc;
300  union {
301  StringRef Tok;
302  RegOp Reg;
303  ImmOp Imm;
304  struct SysRegOp SysReg;
305  struct VTypeOp VType;
306  };
307 
308  RISCVOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
309 
310 public:
311  RISCVOperand(const RISCVOperand &o) : MCParsedAsmOperand() {
312  Kind = o.Kind;
313  IsRV64 = o.IsRV64;
314  StartLoc = o.StartLoc;
315  EndLoc = o.EndLoc;
316  switch (Kind) {
317  case KindTy::Register:
318  Reg = o.Reg;
319  break;
320  case KindTy::Immediate:
321  Imm = o.Imm;
322  break;
323  case KindTy::Token:
324  Tok = o.Tok;
325  break;
326  case KindTy::SystemRegister:
327  SysReg = o.SysReg;
328  break;
329  case KindTy::VType:
330  VType = o.VType;
331  break;
332  }
333  }
334 
335  bool isToken() const override { return Kind == KindTy::Token; }
336  bool isReg() const override { return Kind == KindTy::Register; }
337  bool isV0Reg() const {
338  return Kind == KindTy::Register && Reg.RegNum == RISCV::V0;
339  }
340  bool isImm() const override { return Kind == KindTy::Immediate; }
341  bool isMem() const override { return false; }
342  bool isSystemRegister() const { return Kind == KindTy::SystemRegister; }
343  bool isVType() const { return Kind == KindTy::VType; }
344 
345  bool isGPR() const {
346  return Kind == KindTy::Register &&
347  RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(Reg.RegNum);
348  }
349 
350  static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm,
352  if (auto *RE = dyn_cast<RISCVMCExpr>(Expr)) {
353  VK = RE->getKind();
354  return RE->evaluateAsConstant(Imm);
355  }
356 
357  if (auto CE = dyn_cast<MCConstantExpr>(Expr)) {
359  Imm = CE->getValue();
360  return true;
361  }
362 
363  return false;
364  }
365 
366  // True if operand is a symbol with no modifiers, or a constant with no
367  // modifiers and isShiftedInt<N-1, 1>(Op).
368  template <int N> bool isBareSimmNLsb0() const {
369  int64_t Imm;
371  if (!isImm())
372  return false;
373  bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
374  bool IsValid;
375  if (!IsConstantImm)
376  IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
377  else
378  IsValid = isShiftedInt<N - 1, 1>(Imm);
379  return IsValid && VK == RISCVMCExpr::VK_RISCV_None;
380  }
381 
382  // Predicate methods for AsmOperands defined in RISCVInstrInfo.td
383 
384  bool isBareSymbol() const {
385  int64_t Imm;
387  // Must be of 'immediate' type but not a constant.
388  if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
389  return false;
390  return RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm) &&
392  }
393 
394  bool isCallSymbol() const {
395  int64_t Imm;
397  // Must be of 'immediate' type but not a constant.
398  if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
399  return false;
400  return RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm) &&
403  }
404 
405  bool isPseudoJumpSymbol() const {
406  int64_t Imm;
408  // Must be of 'immediate' type but not a constant.
409  if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
410  return false;
411  return RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm) &&
413  }
414 
415  bool isTPRelAddSymbol() const {
416  int64_t Imm;
418  // Must be of 'immediate' type but not a constant.
419  if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
420  return false;
421  return RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm) &&
423  }
424 
425  bool isCSRSystemRegister() const { return isSystemRegister(); }
426 
427  bool isVTypeI() const { return isVType(); }
428 
429  /// Return true if the operand is a valid for the fence instruction e.g.
430  /// ('iorw').
431  bool isFenceArg() const {
432  if (!isImm())
433  return false;
434  const MCExpr *Val = getImm();
435  auto *SVal = dyn_cast<MCSymbolRefExpr>(Val);
436  if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None)
437  return false;
438 
439  StringRef Str = SVal->getSymbol().getName();
440  // Letters must be unique, taken from 'iorw', and in ascending order. This
441  // holds as long as each individual character is one of 'iorw' and is
442  // greater than the previous character.
443  char Prev = '\0';
444  for (char c : Str) {
445  if (c != 'i' && c != 'o' && c != 'r' && c != 'w')
446  return false;
447  if (c <= Prev)
448  return false;
449  Prev = c;
450  }
451  return true;
452  }
453 
454  /// Return true if the operand is a valid floating point rounding mode.
455  bool isFRMArg() const {
456  if (!isImm())
457  return false;
458  const MCExpr *Val = getImm();
459  auto *SVal = dyn_cast<MCSymbolRefExpr>(Val);
460  if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None)
461  return false;
462 
463  StringRef Str = SVal->getSymbol().getName();
464 
466  }
467 
468  bool isImmXLenLI() const {
469  int64_t Imm;
471  if (!isImm())
472  return false;
473  bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
475  return true;
476  // Given only Imm, ensuring that the actually specified constant is either
477  // a signed or unsigned 64-bit number is unfortunately impossible.
478  return IsConstantImm && VK == RISCVMCExpr::VK_RISCV_None &&
479  (isRV64() || (isInt<32>(Imm) || isUInt<32>(Imm)));
480  }
481 
482  bool isUImmLog2XLen() const {
483  int64_t Imm;
485  if (!isImm())
486  return false;
487  if (!evaluateConstantImm(getImm(), Imm, VK) ||
489  return false;
490  return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm);
491  }
492 
493  bool isUImmLog2XLenNonZero() const {
494  int64_t Imm;
496  if (!isImm())
497  return false;
498  if (!evaluateConstantImm(getImm(), Imm, VK) ||
500  return false;
501  if (Imm == 0)
502  return false;
503  return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm);
504  }
505 
506  bool isUImmLog2XLenHalf() const {
507  int64_t Imm;
509  if (!isImm())
510  return false;
511  if (!evaluateConstantImm(getImm(), Imm, VK) ||
513  return false;
514  return (isRV64() && isUInt<5>(Imm)) || isUInt<4>(Imm);
515  }
516 
517  bool isUImm5() const {
518  int64_t Imm;
520  if (!isImm())
521  return false;
522  bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
523  return IsConstantImm && isUInt<5>(Imm) && VK == RISCVMCExpr::VK_RISCV_None;
524  }
525 
526  bool isUImm5NonZero() const {
527  int64_t Imm;
529  if (!isImm())
530  return false;
531  bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
532  return IsConstantImm && isUInt<5>(Imm) && (Imm != 0) &&
534  }
535 
536  bool isSImm5() const {
537  if (!isImm())
538  return false;
540  int64_t Imm;
541  bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
542  return IsConstantImm && isInt<5>(Imm) && VK == RISCVMCExpr::VK_RISCV_None;
543  }
544 
545  bool isSImm6() const {
546  if (!isImm())
547  return false;
549  int64_t Imm;
550  bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
551  return IsConstantImm && isInt<6>(Imm) &&
553  }
554 
555  bool isSImm6NonZero() const {
556  if (!isImm())
557  return false;
559  int64_t Imm;
560  bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
561  return IsConstantImm && isInt<6>(Imm) && (Imm != 0) &&
563  }
564 
565  bool isCLUIImm() const {
566  if (!isImm())
567  return false;
568  int64_t Imm;
570  bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
571  return IsConstantImm && (Imm != 0) &&
572  (isUInt<5>(Imm) || (Imm >= 0xfffe0 && Imm <= 0xfffff)) &&
574  }
575 
576  bool isUImm7Lsb00() const {
577  if (!isImm())
578  return false;
579  int64_t Imm;
581  bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
582  return IsConstantImm && isShiftedUInt<5, 2>(Imm) &&
584  }
585 
586  bool isUImm8Lsb00() const {
587  if (!isImm())
588  return false;
589  int64_t Imm;
591  bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
592  return IsConstantImm && isShiftedUInt<6, 2>(Imm) &&
594  }
595 
596  bool isUImm8Lsb000() const {
597  if (!isImm())
598  return false;
599  int64_t Imm;
601  bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
602  return IsConstantImm && isShiftedUInt<5, 3>(Imm) &&
604  }
605 
606  bool isSImm9Lsb0() const { return isBareSimmNLsb0<9>(); }
607 
608  bool isUImm9Lsb000() const {
609  if (!isImm())
610  return false;
611  int64_t Imm;
613  bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
614  return IsConstantImm && isShiftedUInt<6, 3>(Imm) &&
616  }
617 
618  bool isUImm10Lsb00NonZero() const {
619  if (!isImm())
620  return false;
621  int64_t Imm;
623  bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
624  return IsConstantImm && isShiftedUInt<8, 2>(Imm) && (Imm != 0) &&
626  }
627 
628  bool isSImm12() const {
630  int64_t Imm;
631  bool IsValid;
632  if (!isImm())
633  return false;
634  bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
635  if (!IsConstantImm)
636  IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
637  else
638  IsValid = isInt<12>(Imm);
639  return IsValid && ((IsConstantImm && VK == RISCVMCExpr::VK_RISCV_None) ||
640  VK == RISCVMCExpr::VK_RISCV_LO ||
643  }
644 
645  bool isSImm12Lsb0() const { return isBareSimmNLsb0<12>(); }
646 
647  bool isSImm13Lsb0() const { return isBareSimmNLsb0<13>(); }
648 
649  bool isSImm10Lsb0000NonZero() const {
650  if (!isImm())
651  return false;
652  int64_t Imm;
654  bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
655  return IsConstantImm && (Imm != 0) && isShiftedInt<6, 4>(Imm) &&
657  }
658 
659  bool isUImm20LUI() const {
661  int64_t Imm;
662  bool IsValid;
663  if (!isImm())
664  return false;
665  bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
666  if (!IsConstantImm) {
667  IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
668  return IsValid && (VK == RISCVMCExpr::VK_RISCV_HI ||
670  } else {
671  return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None ||
672  VK == RISCVMCExpr::VK_RISCV_HI ||
674  }
675  }
676 
677  bool isUImm20AUIPC() const {
679  int64_t Imm;
680  bool IsValid;
681  if (!isImm())
682  return false;
683  bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
684  if (!IsConstantImm) {
685  IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
686  return IsValid && (VK == RISCVMCExpr::VK_RISCV_PCREL_HI ||
690  } else {
691  return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None ||
696  }
697  }
698 
699  bool isSImm21Lsb0JAL() const { return isBareSimmNLsb0<21>(); }
700 
701  bool isImmZero() const {
702  if (!isImm())
703  return false;
704  int64_t Imm;
706  bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
707  return IsConstantImm && (Imm == 0) && VK == RISCVMCExpr::VK_RISCV_None;
708  }
709 
710  bool isSImm5Plus1() const {
711  if (!isImm())
712  return false;
714  int64_t Imm;
715  bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
716  return IsConstantImm && isInt<5>(Imm - 1) &&
718  }
719 
720  /// getStartLoc - Gets location of the first token of this operand
721  SMLoc getStartLoc() const override { return StartLoc; }
722  /// getEndLoc - Gets location of the last token of this operand
723  SMLoc getEndLoc() const override { return EndLoc; }
724  /// True if this operand is for an RV64 instruction
725  bool isRV64() const { return IsRV64; }
726 
727  unsigned getReg() const override {
728  assert(Kind == KindTy::Register && "Invalid type access!");
729  return Reg.RegNum.id();
730  }
731 
732  StringRef getSysReg() const {
733  assert(Kind == KindTy::SystemRegister && "Invalid access!");
734  return StringRef(SysReg.Data, SysReg.Length);
735  }
736 
737  const MCExpr *getImm() const {
738  assert(Kind == KindTy::Immediate && "Invalid type access!");
739  return Imm.Val;
740  }
741 
742  StringRef getToken() const {
743  assert(Kind == KindTy::Token && "Invalid type access!");
744  return Tok;
745  }
746 
747  static StringRef getSEWStr(VSEW Sew) {
748  switch (Sew) {
749  case VSEW::SEW_8:
750  return "e8";
751  case VSEW::SEW_16:
752  return "e16";
753  case VSEW::SEW_32:
754  return "e32";
755  case VSEW::SEW_64:
756  return "e64";
757  case VSEW::SEW_128:
758  return "e128";
759  case VSEW::SEW_256:
760  return "e256";
761  case VSEW::SEW_512:
762  return "e512";
763  case VSEW::SEW_1024:
764  return "e1024";
765  }
766  return "";
767  }
768 
769  static StringRef getLMULStr(VLMUL Lmul) {
770  switch (Lmul) {
771  case VLMUL::LMUL_1:
772  return "m1";
773  case VLMUL::LMUL_2:
774  return "m2";
775  case VLMUL::LMUL_4:
776  return "m4";
777  case VLMUL::LMUL_8:
778  return "m8";
779  }
780  return "";
781  }
782 
783  StringRef getVType(SmallString<32> &Buf) const {
784  assert(Kind == KindTy::VType && "Invalid access!");
785  Buf.append(getSEWStr(VType.Sew));
786  Buf.append(",");
787  Buf.append(getLMULStr(VType.Lmul));
788 
789  return Buf.str();
790  }
791 
792  void print(raw_ostream &OS) const override {
793  switch (Kind) {
794  case KindTy::Immediate:
795  OS << *getImm();
796  break;
797  case KindTy::Register:
798  OS << "<register x";
799  OS << getReg() << ">";
800  break;
801  case KindTy::Token:
802  OS << "'" << getToken() << "'";
803  break;
804  case KindTy::SystemRegister:
805  OS << "<sysreg: " << getSysReg() << '>';
806  break;
807  case KindTy::VType:
808  SmallString<32> VTypeBuf;
809  OS << "<vtype: " << getVType(VTypeBuf) << '>';
810  break;
811  }
812  }
813 
814  static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S,
815  bool IsRV64) {
816  auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
817  Op->Tok = Str;
818  Op->StartLoc = S;
819  Op->EndLoc = S;
820  Op->IsRV64 = IsRV64;
821  return Op;
822  }
823 
824  static std::unique_ptr<RISCVOperand> createReg(unsigned RegNo, SMLoc S,
825  SMLoc E, bool IsRV64) {
826  auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
827  Op->Reg.RegNum = RegNo;
828  Op->StartLoc = S;
829  Op->EndLoc = E;
830  Op->IsRV64 = IsRV64;
831  return Op;
832  }
833 
834  static std::unique_ptr<RISCVOperand> createImm(const MCExpr *Val, SMLoc S,
835  SMLoc E, bool IsRV64) {
836  auto Op = std::make_unique<RISCVOperand>(KindTy::Immediate);
837  Op->Imm.Val = Val;
838  Op->StartLoc = S;
839  Op->EndLoc = E;
840  Op->IsRV64 = IsRV64;
841  return Op;
842  }
843 
844  static std::unique_ptr<RISCVOperand>
845  createSysReg(StringRef Str, SMLoc S, unsigned Encoding, bool IsRV64) {
846  auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
847  Op->SysReg.Data = Str.data();
848  Op->SysReg.Length = Str.size();
849  Op->SysReg.Encoding = Encoding;
850  Op->StartLoc = S;
851  Op->IsRV64 = IsRV64;
852  return Op;
853  }
854 
855  static std::unique_ptr<RISCVOperand> createVType(APInt Sew, APInt Lmul,
856  SMLoc S, bool IsRV64) {
857  auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
858  Sew.ashrInPlace(3);
859  unsigned SewLog2 = Sew.logBase2();
860  unsigned LmulLog2 = Lmul.logBase2();
861  Op->VType.Sew = static_cast<VSEW>(SewLog2);
862  Op->VType.Lmul = static_cast<VLMUL>(LmulLog2);
863  Op->VType.Encoding = (SewLog2 << 2) | LmulLog2;
864  Op->StartLoc = S;
865  Op->IsRV64 = IsRV64;
866  return Op;
867  }
868 
869  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
870  assert(Expr && "Expr shouldn't be null!");
871  int64_t Imm = 0;
873  bool IsConstant = evaluateConstantImm(Expr, Imm, VK);
874 
875  if (IsConstant)
876  Inst.addOperand(MCOperand::createImm(Imm));
877  else
878  Inst.addOperand(MCOperand::createExpr(Expr));
879  }
880 
881  // Used by the TableGen Code
882  void addRegOperands(MCInst &Inst, unsigned N) const {
883  assert(N == 1 && "Invalid number of operands!");
885  }
886 
887  void addImmOperands(MCInst &Inst, unsigned N) const {
888  assert(N == 1 && "Invalid number of operands!");
889  addExpr(Inst, getImm());
890  }
891 
892  void addSImm5Plus1Operands(MCInst &Inst, unsigned N) const {
893  assert(N == 1 && "Invalid number of operands!");
894  int64_t Imm = 0;
896  bool IsConstant = evaluateConstantImm(getImm(), Imm, VK);
897  assert(IsConstant && "Expect constant value!");
898  (void)IsConstant;
899  Inst.addOperand(MCOperand::createImm(Imm - 1));
900  }
901 
902  void addFenceArgOperands(MCInst &Inst, unsigned N) const {
903  assert(N == 1 && "Invalid number of operands!");
904  // isFenceArg has validated the operand, meaning this cast is safe
905  auto SE = cast<MCSymbolRefExpr>(getImm());
906 
907  unsigned Imm = 0;
908  for (char c : SE->getSymbol().getName()) {
909  switch (c) {
910  default:
911  llvm_unreachable("FenceArg must contain only [iorw]");
912  case 'i': Imm |= RISCVFenceField::I; break;
913  case 'o': Imm |= RISCVFenceField::O; break;
914  case 'r': Imm |= RISCVFenceField::R; break;
915  case 'w': Imm |= RISCVFenceField::W; break;
916  }
917  }
918  Inst.addOperand(MCOperand::createImm(Imm));
919  }
920 
921  void addCSRSystemRegisterOperands(MCInst &Inst, unsigned N) const {
922  assert(N == 1 && "Invalid number of operands!");
923  Inst.addOperand(MCOperand::createImm(SysReg.Encoding));
924  }
925 
926  void addVTypeIOperands(MCInst &Inst, unsigned N) const {
927  assert(N == 1 && "Invalid number of operands!");
928  Inst.addOperand(MCOperand::createImm(VType.Encoding));
929  }
930 
931  // Returns the rounding mode represented by this RISCVOperand. Should only
932  // be called after checking isFRMArg.
933  RISCVFPRndMode::RoundingMode getRoundingMode() const {
934  // isFRMArg has validated the operand, meaning this cast is safe.
935  auto SE = cast<MCSymbolRefExpr>(getImm());
937  RISCVFPRndMode::stringToRoundingMode(SE->getSymbol().getName());
938  assert(FRM != RISCVFPRndMode::Invalid && "Invalid rounding mode");
939  return FRM;
940  }
941 
942  void addFRMArgOperands(MCInst &Inst, unsigned N) const {
943  assert(N == 1 && "Invalid number of operands!");
944  Inst.addOperand(MCOperand::createImm(getRoundingMode()));
945  }
946 };
947 } // end anonymous namespace.
948 
949 #define GET_REGISTER_MATCHER
950 #define GET_SUBTARGET_FEATURE_NAME
951 #define GET_MATCHER_IMPLEMENTATION
952 #define GET_MNEMONIC_SPELL_CHECKER
953 #include "RISCVGenAsmMatcher.inc"
954 
956  assert(Reg >= RISCV::F0_D && Reg <= RISCV::F31_D && "Invalid register");
957  return Reg - RISCV::F0_D + RISCV::F0_F;
958 }
959 
960 unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
961  unsigned Kind) {
962  RISCVOperand &Op = static_cast<RISCVOperand &>(AsmOp);
963  if (!Op.isReg())
964  return Match_InvalidOperand;
965 
966  Register Reg = Op.getReg();
967  bool IsRegFPR64 =
968  RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(Reg);
969  bool IsRegFPR64C =
970  RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(Reg);
971 
972  // As the parser couldn't differentiate an FPR32 from an FPR64, coerce the
973  // register from FPR64 to FPR32 or FPR64C to FPR32C if necessary.
974  if ((IsRegFPR64 && Kind == MCK_FPR32) ||
975  (IsRegFPR64C && Kind == MCK_FPR32C)) {
976  Op.Reg.RegNum = convertFPR64ToFPR32(Reg);
977  return Match_Success;
978  }
979  return Match_InvalidOperand;
980 }
981 
982 bool RISCVAsmParser::generateImmOutOfRangeError(
983  OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper,
984  Twine Msg = "immediate must be an integer in the range") {
985  SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
986  return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]");
987 }
988 
989 static std::string RISCVMnemonicSpellCheck(StringRef S,
990  const FeatureBitset &FBS,
991  unsigned VariantID = 0);
992 
993 bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
994  OperandVector &Operands,
995  MCStreamer &Out,
996  uint64_t &ErrorInfo,
997  bool MatchingInlineAsm) {
998  MCInst Inst;
999  FeatureBitset MissingFeatures;
1000 
1001  auto Result =
1002  MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
1003  MatchingInlineAsm);
1004  switch (Result) {
1005  default:
1006  break;
1007  case Match_Success:
1008  if (validateInstruction(Inst, Operands))
1009  return true;
1010  return processInstruction(Inst, IDLoc, Operands, Out);
1011  case Match_MissingFeature: {
1012  assert(MissingFeatures.any() && "Unknown missing features!");
1013  bool FirstFeature = true;
1014  std::string Msg = "instruction requires the following:";
1015  for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) {
1016  if (MissingFeatures[i]) {
1017  Msg += FirstFeature ? " " : ", ";
1018  Msg += getSubtargetFeatureName(i);
1019  FirstFeature = false;
1020  }
1021  }
1022  return Error(IDLoc, Msg);
1023  }
1024  case Match_MnemonicFail: {
1025  FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1026  std::string Suggestion = RISCVMnemonicSpellCheck(
1027  ((RISCVOperand &)*Operands[0]).getToken(), FBS);
1028  return Error(IDLoc, "unrecognized instruction mnemonic" + Suggestion);
1029  }
1030  case Match_InvalidOperand: {
1031  SMLoc ErrorLoc = IDLoc;
1032  if (ErrorInfo != ~0U) {
1033  if (ErrorInfo >= Operands.size())
1034  return Error(ErrorLoc, "too few operands for instruction");
1035 
1036  ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1037  if (ErrorLoc == SMLoc())
1038  ErrorLoc = IDLoc;
1039  }
1040  return Error(ErrorLoc, "invalid operand for instruction");
1041  }
1042  }
1043 
1044  // Handle the case when the error message is of specific type
1045  // other than the generic Match_InvalidOperand, and the
1046  // corresponding operand is missing.
1047  if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1048  SMLoc ErrorLoc = IDLoc;
1049  if (ErrorInfo != ~0U && ErrorInfo >= Operands.size())
1050  return Error(ErrorLoc, "too few operands for instruction");
1051  }
1052 
1053  switch(Result) {
1054  default:
1055  break;
1056  case Match_InvalidImmXLenLI:
1057  if (isRV64()) {
1058  SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1059  return Error(ErrorLoc, "operand must be a constant 64-bit integer");
1060  }
1061  return generateImmOutOfRangeError(Operands, ErrorInfo,
1064  case Match_InvalidImmZero: {
1065  SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1066  return Error(ErrorLoc, "immediate must be zero");
1067  }
1068  case Match_InvalidUImmLog2XLen:
1069  if (isRV64())
1070  return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
1071  return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1072  case Match_InvalidUImmLog2XLenNonZero:
1073  if (isRV64())
1074  return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1);
1075  return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
1076  case Match_InvalidUImmLog2XLenHalf:
1077  if (isRV64())
1078  return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1079  return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);
1080  case Match_InvalidUImm5:
1081  return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1082  case Match_InvalidSImm6:
1083  return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5),
1084  (1 << 5) - 1);
1085  case Match_InvalidSImm6NonZero:
1086  return generateImmOutOfRangeError(
1087  Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1,
1088  "immediate must be non-zero in the range");
1089  case Match_InvalidCLUIImm:
1090  return generateImmOutOfRangeError(
1091  Operands, ErrorInfo, 1, (1 << 5) - 1,
1092  "immediate must be in [0xfffe0, 0xfffff] or");
1093  case Match_InvalidUImm7Lsb00:
1094  return generateImmOutOfRangeError(
1095  Operands, ErrorInfo, 0, (1 << 7) - 4,
1096  "immediate must be a multiple of 4 bytes in the range");
1097  case Match_InvalidUImm8Lsb00:
1098  return generateImmOutOfRangeError(
1099  Operands, ErrorInfo, 0, (1 << 8) - 4,
1100  "immediate must be a multiple of 4 bytes in the range");
1101  case Match_InvalidUImm8Lsb000:
1102  return generateImmOutOfRangeError(
1103  Operands, ErrorInfo, 0, (1 << 8) - 8,
1104  "immediate must be a multiple of 8 bytes in the range");
1105  case Match_InvalidSImm9Lsb0:
1106  return generateImmOutOfRangeError(
1107  Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2,
1108  "immediate must be a multiple of 2 bytes in the range");
1109  case Match_InvalidUImm9Lsb000:
1110  return generateImmOutOfRangeError(
1111  Operands, ErrorInfo, 0, (1 << 9) - 8,
1112  "immediate must be a multiple of 8 bytes in the range");
1113  case Match_InvalidUImm10Lsb00NonZero:
1114  return generateImmOutOfRangeError(
1115  Operands, ErrorInfo, 4, (1 << 10) - 4,
1116  "immediate must be a multiple of 4 bytes in the range");
1117  case Match_InvalidSImm10Lsb0000NonZero:
1118  return generateImmOutOfRangeError(
1119  Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
1120  "immediate must be a multiple of 16 bytes and non-zero in the range");
1121  case Match_InvalidSImm12:
1122  return generateImmOutOfRangeError(
1123  Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1,
1124  "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an "
1125  "integer in the range");
1126  case Match_InvalidSImm12Lsb0:
1127  return generateImmOutOfRangeError(
1128  Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2,
1129  "immediate must be a multiple of 2 bytes in the range");
1130  case Match_InvalidSImm13Lsb0:
1131  return generateImmOutOfRangeError(
1132  Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2,
1133  "immediate must be a multiple of 2 bytes in the range");
1134  case Match_InvalidUImm20LUI:
1135  return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1,
1136  "operand must be a symbol with "
1137  "%hi/%tprel_hi modifier or an integer in "
1138  "the range");
1139  case Match_InvalidUImm20AUIPC:
1140  return generateImmOutOfRangeError(
1141  Operands, ErrorInfo, 0, (1 << 20) - 1,
1142  "operand must be a symbol with a "
1143  "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or "
1144  "an integer in the range");
1145  case Match_InvalidSImm21Lsb0JAL:
1146  return generateImmOutOfRangeError(
1147  Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2,
1148  "immediate must be a multiple of 2 bytes in the range");
1149  case Match_InvalidCSRSystemRegister: {
1150  return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1,
1151  "operand must be a valid system register "
1152  "name or an integer in the range");
1153  }
1154  case Match_InvalidFenceArg: {
1155  SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1156  return Error(
1157  ErrorLoc,
1158  "operand must be formed of letters selected in-order from 'iorw'");
1159  }
1160  case Match_InvalidFRMArg: {
1161  SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1162  return Error(
1163  ErrorLoc,
1164  "operand must be a valid floating point rounding mode mnemonic");
1165  }
1166  case Match_InvalidBareSymbol: {
1167  SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1168  return Error(ErrorLoc, "operand must be a bare symbol name");
1169  }
1170  case Match_InvalidPseudoJumpSymbol: {
1171  SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1172  return Error(ErrorLoc, "operand must be a valid jump target");
1173  }
1174  case Match_InvalidCallSymbol: {
1175  SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1176  return Error(ErrorLoc, "operand must be a bare symbol name");
1177  }
1178  case Match_InvalidTPRelAddSymbol: {
1179  SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1180  return Error(ErrorLoc, "operand must be a symbol with %tprel_add modifier");
1181  }
1182  case Match_InvalidVTypeI: {
1183  SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1184  return Error(ErrorLoc,
1185  "operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8]");
1186  }
1187  case Match_InvalidVMaskRegister: {
1188  SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1189  return Error(ErrorLoc, "operand must be v0.t");
1190  }
1191  case Match_InvalidSImm5Plus1: {
1192  return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4) + 1,
1193  (1 << 4),
1194  "immediate must be in the range");
1195  }
1196  }
1197 
1198  llvm_unreachable("Unknown match type detected!");
1199 }
1200 
1201 // Attempts to match Name as a register (either using the default name or
1202 // alternative ABI names), setting RegNo to the matching register. Upon
1203 // failure, returns true and sets RegNo to 0. If IsRV32E then registers
1204 // x16-x31 will be rejected.
1205 static bool matchRegisterNameHelper(bool IsRV32E, Register &RegNo,
1206  StringRef Name) {
1207  RegNo = MatchRegisterName(Name);
1208  // The 32- and 64-bit FPRs have the same asm name. Check that the initial
1209  // match always matches the 64-bit variant, and not the 32-bit one.
1210  assert(!(RegNo >= RISCV::F0_F && RegNo <= RISCV::F31_F));
1211  // The default FPR register class is based on the tablegen enum ordering.
1212  static_assert(RISCV::F0_D < RISCV::F0_F, "FPR matching must be updated");
1213  if (RegNo == RISCV::NoRegister)
1214  RegNo = MatchRegisterAltName(Name);
1215  if (IsRV32E && RegNo >= RISCV::X16 && RegNo <= RISCV::X31)
1216  RegNo = RISCV::NoRegister;
1217  return RegNo == RISCV::NoRegister;
1218 }
1219 
1220 bool RISCVAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1221  SMLoc &EndLoc) {
1222  if (tryParseRegister(RegNo, StartLoc, EndLoc) != MatchOperand_Success)
1223  return Error(StartLoc, "invalid register name");
1224  return false;
1225 }
1226 
1227 OperandMatchResultTy RISCVAsmParser::tryParseRegister(unsigned &RegNo,
1228  SMLoc &StartLoc,
1229  SMLoc &EndLoc) {
1230  const AsmToken &Tok = getParser().getTok();
1231  StartLoc = Tok.getLoc();
1232  EndLoc = Tok.getEndLoc();
1233  RegNo = 0;
1234  StringRef Name = getLexer().getTok().getIdentifier();
1235 
1236  if (matchRegisterNameHelper(isRV32E(), (Register &)RegNo, Name))
1237  return MatchOperand_NoMatch;
1238 
1239  getParser().Lex(); // Eat identifier token.
1240  return MatchOperand_Success;
1241 }
1242 
1243 OperandMatchResultTy RISCVAsmParser::parseRegister(OperandVector &Operands,
1244  bool AllowParens) {
1245  SMLoc FirstS = getLoc();
1246  bool HadParens = false;
1247  AsmToken LParen;
1248 
1249  // If this is an LParen and a parenthesised register name is allowed, parse it
1250  // atomically.
1251  if (AllowParens && getLexer().is(AsmToken::LParen)) {
1252  AsmToken Buf[2];
1253  size_t ReadCount = getLexer().peekTokens(Buf);
1254  if (ReadCount == 2 && Buf[1].getKind() == AsmToken::RParen) {
1255  HadParens = true;
1256  LParen = getParser().getTok();
1257  getParser().Lex(); // Eat '('
1258  }
1259  }
1260 
1261  switch (getLexer().getKind()) {
1262  default:
1263  if (HadParens)
1264  getLexer().UnLex(LParen);
1265  return MatchOperand_NoMatch;
1266  case AsmToken::Identifier:
1267  StringRef Name = getLexer().getTok().getIdentifier();
1268  Register RegNo;
1269  matchRegisterNameHelper(isRV32E(), RegNo, Name);
1270 
1271  if (RegNo == RISCV::NoRegister) {
1272  if (HadParens)
1273  getLexer().UnLex(LParen);
1274  return MatchOperand_NoMatch;
1275  }
1276  if (HadParens)
1277  Operands.push_back(RISCVOperand::createToken("(", FirstS, isRV64()));
1278  SMLoc S = getLoc();
1280  getLexer().Lex();
1281  Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64()));
1282  }
1283 
1284  if (HadParens) {
1285  getParser().Lex(); // Eat ')'
1286  Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64()));
1287  }
1288 
1289  return MatchOperand_Success;
1290 }
1291 
1293 RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) {
1294  SMLoc S = getLoc();
1295  const MCExpr *Res;
1296 
1297  switch (getLexer().getKind()) {
1298  default:
1299  return MatchOperand_NoMatch;
1300  case AsmToken::LParen:
1301  case AsmToken::Minus:
1302  case AsmToken::Plus:
1303  case AsmToken::Exclaim:
1304  case AsmToken::Tilde:
1305  case AsmToken::Integer:
1306  case AsmToken::String: {
1307  if (getParser().parseExpression(Res))
1308  return MatchOperand_ParseFail;
1309 
1310  auto *CE = dyn_cast<MCConstantExpr>(Res);
1311  if (CE) {
1312  int64_t Imm = CE->getValue();
1313  if (isUInt<12>(Imm)) {
1314  auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm);
1315  // Accept an immediate representing a named or un-named Sys Reg
1316  // if the range is valid, regardless of the required features.
1317  Operands.push_back(RISCVOperand::createSysReg(
1318  SysReg ? SysReg->Name : "", S, Imm, isRV64()));
1319  return MatchOperand_Success;
1320  }
1321  }
1322 
1323  Twine Msg = "immediate must be an integer in the range";
1324  Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]");
1325  return MatchOperand_ParseFail;
1326  }
1327  case AsmToken::Identifier: {
1329  if (getParser().parseIdentifier(Identifier))
1330  return MatchOperand_ParseFail;
1331 
1332  auto SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
1333  if (!SysReg)
1334  SysReg = RISCVSysReg::lookupSysRegByAltName(Identifier);
1335  // Accept a named Sys Reg if the required features are present.
1336  if (SysReg) {
1337  if (!SysReg->haveRequiredFeatures(getSTI().getFeatureBits())) {
1338  Error(S, "system register use requires an option to be enabled");
1339  return MatchOperand_ParseFail;
1340  }
1341  Operands.push_back(RISCVOperand::createSysReg(
1342  Identifier, S, SysReg->Encoding, isRV64()));
1343  return MatchOperand_Success;
1344  }
1345 
1346  Twine Msg = "operand must be a valid system register name "
1347  "or an integer in the range";
1348  Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]");
1349  return MatchOperand_ParseFail;
1350  }
1351  case AsmToken::Percent: {
1352  // Discard operand with modifier.
1353  Twine Msg = "immediate must be an integer in the range";
1354  Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]");
1355  return MatchOperand_ParseFail;
1356  }
1357  }
1358 
1359  return MatchOperand_NoMatch;
1360 }
1361 
1363  SMLoc S = getLoc();
1365  const MCExpr *Res;
1366 
1367  switch (getLexer().getKind()) {
1368  default:
1369  return MatchOperand_NoMatch;
1370  case AsmToken::LParen:
1371  case AsmToken::Dot:
1372  case AsmToken::Minus:
1373  case AsmToken::Plus:
1374  case AsmToken::Exclaim:
1375  case AsmToken::Tilde:
1376  case AsmToken::Integer:
1377  case AsmToken::String:
1378  case AsmToken::Identifier:
1379  if (getParser().parseExpression(Res))
1380  return MatchOperand_ParseFail;
1381  break;
1382  case AsmToken::Percent:
1383  return parseOperandWithModifier(Operands);
1384  }
1385 
1386  Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1387  return MatchOperand_Success;
1388 }
1389 
1391 RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) {
1392  SMLoc S = getLoc();
1394 
1395  if (getLexer().getKind() != AsmToken::Percent) {
1396  Error(getLoc(), "expected '%' for operand modifier");
1397  return MatchOperand_ParseFail;
1398  }
1399 
1400  getParser().Lex(); // Eat '%'
1401 
1402  if (getLexer().getKind() != AsmToken::Identifier) {
1403  Error(getLoc(), "expected valid identifier for operand modifier");
1404  return MatchOperand_ParseFail;
1405  }
1406  StringRef Identifier = getParser().getTok().getIdentifier();
1408  if (VK == RISCVMCExpr::VK_RISCV_Invalid) {
1409  Error(getLoc(), "unrecognized operand modifier");
1410  return MatchOperand_ParseFail;
1411  }
1412 
1413  getParser().Lex(); // Eat the identifier
1414  if (getLexer().getKind() != AsmToken::LParen) {
1415  Error(getLoc(), "expected '('");
1416  return MatchOperand_ParseFail;
1417  }
1418  getParser().Lex(); // Eat '('
1419 
1420  const MCExpr *SubExpr;
1421  if (getParser().parseParenExpression(SubExpr, E)) {
1422  return MatchOperand_ParseFail;
1423  }
1424 
1425  const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, VK, getContext());
1426  Operands.push_back(RISCVOperand::createImm(ModExpr, S, E, isRV64()));
1427  return MatchOperand_Success;
1428 }
1429 
1430 OperandMatchResultTy RISCVAsmParser::parseBareSymbol(OperandVector &Operands) {
1431  SMLoc S = getLoc();
1433  const MCExpr *Res;
1434 
1435  if (getLexer().getKind() != AsmToken::Identifier)
1436  return MatchOperand_NoMatch;
1437 
1439  AsmToken Tok = getLexer().getTok();
1440 
1441  if (getParser().parseIdentifier(Identifier))
1442  return MatchOperand_ParseFail;
1443 
1444  if (Identifier.consume_back("@plt")) {
1445  Error(getLoc(), "'@plt' operand not valid for instruction");
1446  return MatchOperand_ParseFail;
1447  }
1448 
1449  MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1450 
1451  if (Sym->isVariable()) {
1452  const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false);
1453  if (!isa<MCSymbolRefExpr>(V)) {
1454  getLexer().UnLex(Tok); // Put back if it's not a bare symbol.
1455  return MatchOperand_NoMatch;
1456  }
1457  Res = V;
1458  } else
1459  Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1460 
1461  MCBinaryExpr::Opcode Opcode;
1462  switch (getLexer().getKind()) {
1463  default:
1464  Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1465  return MatchOperand_Success;
1466  case AsmToken::Plus:
1467  Opcode = MCBinaryExpr::Add;
1468  break;
1469  case AsmToken::Minus:
1470  Opcode = MCBinaryExpr::Sub;
1471  break;
1472  }
1473 
1474  const MCExpr *Expr;
1475  if (getParser().parseExpression(Expr))
1476  return MatchOperand_ParseFail;
1477  Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext());
1478  Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1479  return MatchOperand_Success;
1480 }
1481 
1482 OperandMatchResultTy RISCVAsmParser::parseCallSymbol(OperandVector &Operands) {
1483  SMLoc S = getLoc();
1485  const MCExpr *Res;
1486 
1487  if (getLexer().getKind() != AsmToken::Identifier)
1488  return MatchOperand_NoMatch;
1489 
1490  // Avoid parsing the register in `call rd, foo` as a call symbol.
1491  if (getLexer().peekTok().getKind() != AsmToken::EndOfStatement)
1492  return MatchOperand_NoMatch;
1493 
1495  if (getParser().parseIdentifier(Identifier))
1496  return MatchOperand_ParseFail;
1497 
1499  if (Identifier.consume_back("@plt"))
1501 
1502  MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1503  Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1504  Res = RISCVMCExpr::create(Res, Kind, getContext());
1505  Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1506  return MatchOperand_Success;
1507 }
1508 
1510 RISCVAsmParser::parsePseudoJumpSymbol(OperandVector &Operands) {
1511  SMLoc S = getLoc();
1513  const MCExpr *Res;
1514 
1515  if (getParser().parseExpression(Res))
1516  return MatchOperand_ParseFail;
1517 
1518  if (Res->getKind() != MCExpr::ExprKind::SymbolRef ||
1519  cast<MCSymbolRefExpr>(Res)->getKind() ==
1520  MCSymbolRefExpr::VariantKind::VK_PLT) {
1521  Error(S, "operand must be a valid jump target");
1522  return MatchOperand_ParseFail;
1523  }
1524 
1525  Res = RISCVMCExpr::create(Res, RISCVMCExpr::VK_RISCV_CALL, getContext());
1526  Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1527  return MatchOperand_Success;
1528 }
1529 
1530 OperandMatchResultTy RISCVAsmParser::parseJALOffset(OperandVector &Operands) {
1531  // Parsing jal operands is fiddly due to the `jal foo` and `jal ra, foo`
1532  // both being acceptable forms. When parsing `jal ra, foo` this function
1533  // will be called for the `ra` register operand in an attempt to match the
1534  // single-operand alias. parseJALOffset must fail for this case. It would
1535  // seem logical to try parse the operand using parseImmediate and return
1536  // NoMatch if the next token is a comma (meaning we must be parsing a jal in
1537  // the second form rather than the first). We can't do this as there's no
1538  // way of rewinding the lexer state. Instead, return NoMatch if this operand
1539  // is an identifier and is followed by a comma.
1540  if (getLexer().is(AsmToken::Identifier) &&
1541  getLexer().peekTok().is(AsmToken::Comma))
1542  return MatchOperand_NoMatch;
1543 
1544  return parseImmediate(Operands);
1545 }
1546 
1547 OperandMatchResultTy RISCVAsmParser::parseVTypeI(OperandVector &Operands) {
1548  SMLoc S = getLoc();
1549  if (getLexer().getKind() != AsmToken::Identifier)
1550  return MatchOperand_NoMatch;
1551 
1552  // Parse "e8,m1"
1553  StringRef Name = getLexer().getTok().getIdentifier();
1554  if (!Name.consume_front("e"))
1555  return MatchOperand_NoMatch;
1556  APInt Sew(16, Name, 10);
1557  if (Sew != 8 && Sew != 16 && Sew != 32 && Sew != 64 && Sew != 128 &&
1558  Sew != 256 && Sew != 512 && Sew != 1024)
1559  return MatchOperand_NoMatch;
1560  getLexer().Lex();
1561 
1562  if (getLexer().getKind() == AsmToken::EndOfStatement) {
1563  Operands.push_back(
1564  RISCVOperand::createVType(Sew, APInt(16, 1), S, isRV64()));
1565 
1566  return MatchOperand_Success;
1567  }
1568 
1569  if (!getLexer().is(AsmToken::Comma))
1570  return MatchOperand_NoMatch;
1571  getLexer().Lex();
1572 
1573  Name = getLexer().getTok().getIdentifier();
1574  if (!Name.consume_front("m"))
1575  return MatchOperand_NoMatch;
1576  APInt Lmul(16, Name, 10);
1577  if (Lmul != 1 && Lmul != 2 && Lmul != 4 && Lmul != 8)
1578  return MatchOperand_NoMatch;
1579  getLexer().Lex();
1580 
1581  if (getLexer().getKind() != AsmToken::EndOfStatement)
1582  return MatchOperand_NoMatch;
1583 
1584  Operands.push_back(RISCVOperand::createVType(Sew, Lmul, S, isRV64()));
1585 
1586  return MatchOperand_Success;
1587 }
1588 
1589 OperandMatchResultTy RISCVAsmParser::parseMaskReg(OperandVector &Operands) {
1590  switch (getLexer().getKind()) {
1591  default:
1592  return MatchOperand_NoMatch;
1593  case AsmToken::Identifier:
1594  StringRef Name = getLexer().getTok().getIdentifier();
1595  if (!Name.consume_back(".t")) {
1596  Error(getLoc(), "expected '.t' suffix");
1597  return MatchOperand_ParseFail;
1598  }
1599  Register RegNo;
1600  matchRegisterNameHelper(isRV32E(), RegNo, Name);
1601 
1602  if (RegNo == RISCV::NoRegister)
1603  return MatchOperand_NoMatch;
1604  if (RegNo != RISCV::V0)
1605  return MatchOperand_NoMatch;
1606  SMLoc S = getLoc();
1608  getLexer().Lex();
1609  Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64()));
1610  }
1611 
1612  return MatchOperand_Success;
1613 }
1614 
1616 RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) {
1617  if (getLexer().isNot(AsmToken::LParen)) {
1618  Error(getLoc(), "expected '('");
1619  return MatchOperand_ParseFail;
1620  }
1621 
1622  getParser().Lex(); // Eat '('
1623  Operands.push_back(RISCVOperand::createToken("(", getLoc(), isRV64()));
1624 
1625  if (parseRegister(Operands) != MatchOperand_Success) {
1626  Error(getLoc(), "expected register");
1627  return MatchOperand_ParseFail;
1628  }
1629 
1630  if (getLexer().isNot(AsmToken::RParen)) {
1631  Error(getLoc(), "expected ')'");
1632  return MatchOperand_ParseFail;
1633  }
1634 
1635  getParser().Lex(); // Eat ')'
1636  Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64()));
1637 
1638  return MatchOperand_Success;
1639 }
1640 
1641 OperandMatchResultTy RISCVAsmParser::parseAtomicMemOp(OperandVector &Operands) {
1642  // Atomic operations such as lr.w, sc.w, and amo*.w accept a "memory operand"
1643  // as one of their register operands, such as `(a0)`. This just denotes that
1644  // the register (in this case `a0`) contains a memory address.
1645  //
1646  // Normally, we would be able to parse these by putting the parens into the
1647  // instruction string. However, GNU as also accepts a zero-offset memory
1648  // operand (such as `0(a0)`), and ignores the 0. Normally this would be parsed
1649  // with parseImmediate followed by parseMemOpBaseReg, but these instructions
1650  // do not accept an immediate operand, and we do not want to add a "dummy"
1651  // operand that is silently dropped.
1652  //
1653  // Instead, we use this custom parser. This will: allow (and discard) an
1654  // offset if it is zero; require (and discard) parentheses; and add only the
1655  // parsed register operand to `Operands`.
1656  //
1657  // These operands are printed with RISCVInstPrinter::printAtomicMemOp, which
1658  // will only print the register surrounded by parentheses (which GNU as also
1659  // uses as its canonical representation for these operands).
1660  std::unique_ptr<RISCVOperand> OptionalImmOp;
1661 
1662  if (getLexer().isNot(AsmToken::LParen)) {
1663  // Parse an Integer token. We do not accept arbritrary constant expressions
1664  // in the offset field (because they may include parens, which complicates
1665  // parsing a lot).
1666  int64_t ImmVal;
1667  SMLoc ImmStart = getLoc();
1668  if (getParser().parseIntToken(ImmVal,
1669  "expected '(' or optional integer offset"))
1670  return MatchOperand_ParseFail;
1671 
1672  // Create a RISCVOperand for checking later (so the error messages are
1673  // nicer), but we don't add it to Operands.
1674  SMLoc ImmEnd = getLoc();
1675  OptionalImmOp =
1676  RISCVOperand::createImm(MCConstantExpr::create(ImmVal, getContext()),
1677  ImmStart, ImmEnd, isRV64());
1678  }
1679 
1680  if (getLexer().isNot(AsmToken::LParen)) {
1681  Error(getLoc(), OptionalImmOp ? "expected '(' after optional integer offset"
1682  : "expected '(' or optional integer offset");
1683  return MatchOperand_ParseFail;
1684  }
1685  getParser().Lex(); // Eat '('
1686 
1687  if (parseRegister(Operands) != MatchOperand_Success) {
1688  Error(getLoc(), "expected register");
1689  return MatchOperand_ParseFail;
1690  }
1691 
1692  if (getLexer().isNot(AsmToken::RParen)) {
1693  Error(getLoc(), "expected ')'");
1694  return MatchOperand_ParseFail;
1695  }
1696  getParser().Lex(); // Eat ')'
1697 
1698  // Deferred Handling of non-zero offsets. This makes the error messages nicer.
1699  if (OptionalImmOp && !OptionalImmOp->isImmZero()) {
1700  Error(OptionalImmOp->getStartLoc(), "optional integer offset must be 0",
1701  SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
1702  return MatchOperand_ParseFail;
1703  }
1704 
1705  return MatchOperand_Success;
1706 }
1707 
1708 /// Looks at a token type and creates the relevant operand from this
1709 /// information, adding to Operands. If operand was parsed, returns false, else
1710 /// true.
1711 bool RISCVAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
1712  // Check if the current operand has a custom associated parser, if so, try to
1713  // custom parse the operand, or fallback to the general approach.
1714  OperandMatchResultTy Result =
1715  MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true);
1716  if (Result == MatchOperand_Success)
1717  return false;
1718  if (Result == MatchOperand_ParseFail)
1719  return true;
1720 
1721  // Attempt to parse token as a register.
1722  if (parseRegister(Operands, true) == MatchOperand_Success)
1723  return false;
1724 
1725  // Attempt to parse token as an immediate
1726  if (parseImmediate(Operands) == MatchOperand_Success) {
1727  // Parse memory base register if present
1728  if (getLexer().is(AsmToken::LParen))
1729  return parseMemOpBaseReg(Operands) != MatchOperand_Success;
1730  return false;
1731  }
1732 
1733  // Finally we have exhausted all options and must declare defeat.
1734  Error(getLoc(), "unknown operand");
1735  return true;
1736 }
1737 
1738 bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info,
1739  StringRef Name, SMLoc NameLoc,
1740  OperandVector &Operands) {
1741  // Ensure that if the instruction occurs when relaxation is enabled,
1742  // relocations are forced for the file. Ideally this would be done when there
1743  // is enough information to reliably determine if the instruction itself may
1744  // cause relaxations. Unfortunately instruction processing stage occurs in the
1745  // same pass as relocation emission, so it's too late to set a 'sticky bit'
1746  // for the entire file.
1747  if (getSTI().getFeatureBits()[RISCV::FeatureRelax]) {
1748  auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr();
1749  if (Assembler != nullptr) {
1750  RISCVAsmBackend &MAB =
1751  static_cast<RISCVAsmBackend &>(Assembler->getBackend());
1752  MAB.setForceRelocs();
1753  }
1754  }
1755 
1756  // First operand is token for instruction
1757  Operands.push_back(RISCVOperand::createToken(Name, NameLoc, isRV64()));
1758 
1759  // If there are no more operands, then finish
1760  if (getLexer().is(AsmToken::EndOfStatement))
1761  return false;
1762 
1763  // Parse first operand
1764  if (parseOperand(Operands, Name))
1765  return true;
1766 
1767  // Parse until end of statement, consuming commas between operands
1768  unsigned OperandIdx = 1;
1769  while (getLexer().is(AsmToken::Comma)) {
1770  // Consume comma token
1771  getLexer().Lex();
1772 
1773  // Parse next operand
1774  if (parseOperand(Operands, Name))
1775  return true;
1776 
1777  ++OperandIdx;
1778  }
1779 
1780  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1781  SMLoc Loc = getLexer().getLoc();
1782  getParser().eatToEndOfStatement();
1783  return Error(Loc, "unexpected token");
1784  }
1785 
1786  getParser().Lex(); // Consume the EndOfStatement.
1787  return false;
1788 }
1789 
1790 bool RISCVAsmParser::classifySymbolRef(const MCExpr *Expr,
1792  int64_t &Addend) {
1794  Addend = 0;
1795 
1796  if (const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) {
1797  Kind = RE->getKind();
1798  Expr = RE->getSubExpr();
1799  }
1800 
1801  // It's a simple symbol reference or constant with no addend.
1802  if (isa<MCConstantExpr>(Expr) || isa<MCSymbolRefExpr>(Expr))
1803  return true;
1804 
1805  const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr);
1806  if (!BE)
1807  return false;
1808 
1809  if (!isa<MCSymbolRefExpr>(BE->getLHS()))
1810  return false;
1811 
1812  if (BE->getOpcode() != MCBinaryExpr::Add &&
1813  BE->getOpcode() != MCBinaryExpr::Sub)
1814  return false;
1815 
1816  // We are able to support the subtraction of two symbol references
1817  if (BE->getOpcode() == MCBinaryExpr::Sub &&
1818  isa<MCSymbolRefExpr>(BE->getRHS()))
1819  return true;
1820 
1821  // See if the addend is a constant, otherwise there's more going
1822  // on here than we can deal with.
1823  auto AddendExpr = dyn_cast<MCConstantExpr>(BE->getRHS());
1824  if (!AddendExpr)
1825  return false;
1826 
1827  Addend = AddendExpr->getValue();
1828  if (BE->getOpcode() == MCBinaryExpr::Sub)
1829  Addend = -Addend;
1830 
1831  // It's some symbol reference + a constant addend
1832  return Kind != RISCVMCExpr::VK_RISCV_Invalid;
1833 }
1834 
1835 bool RISCVAsmParser::ParseDirective(AsmToken DirectiveID) {
1836  // This returns false if this function recognizes the directive
1837  // regardless of whether it is successfully handles or reports an
1838  // error. Otherwise it returns true to give the generic parser a
1839  // chance at recognizing it.
1840  StringRef IDVal = DirectiveID.getString();
1841 
1842  if (IDVal == ".option")
1843  return parseDirectiveOption();
1844  else if (IDVal == ".attribute")
1845  return parseDirectiveAttribute();
1846 
1847  return true;
1848 }
1849 
1850 bool RISCVAsmParser::parseDirectiveOption() {
1851  MCAsmParser &Parser = getParser();
1852  // Get the option token.
1853  AsmToken Tok = Parser.getTok();
1854  // At the moment only identifiers are supported.
1855  if (Tok.isNot(AsmToken::Identifier))
1856  return Error(Parser.getTok().getLoc(),
1857  "unexpected token, expected identifier");
1858 
1859  StringRef Option = Tok.getIdentifier();
1860 
1861  if (Option == "push") {
1862  getTargetStreamer().emitDirectiveOptionPush();
1863 
1864  Parser.Lex();
1865  if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1866  return Error(Parser.getTok().getLoc(),
1867  "unexpected token, expected end of statement");
1868 
1869  pushFeatureBits();
1870  return false;
1871  }
1872 
1873  if (Option == "pop") {
1874  SMLoc StartLoc = Parser.getTok().getLoc();
1875  getTargetStreamer().emitDirectiveOptionPop();
1876 
1877  Parser.Lex();
1878  if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1879  return Error(Parser.getTok().getLoc(),
1880  "unexpected token, expected end of statement");
1881 
1882  if (popFeatureBits())
1883  return Error(StartLoc, ".option pop with no .option push");
1884 
1885  return false;
1886  }
1887 
1888  if (Option == "rvc") {
1889  getTargetStreamer().emitDirectiveOptionRVC();
1890 
1891  Parser.Lex();
1892  if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1893  return Error(Parser.getTok().getLoc(),
1894  "unexpected token, expected end of statement");
1895 
1896  setFeatureBits(RISCV::FeatureStdExtC, "c");
1897  return false;
1898  }
1899 
1900  if (Option == "norvc") {
1901  getTargetStreamer().emitDirectiveOptionNoRVC();
1902 
1903  Parser.Lex();
1904  if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1905  return Error(Parser.getTok().getLoc(),
1906  "unexpected token, expected end of statement");
1907 
1908  clearFeatureBits(RISCV::FeatureStdExtC, "c");
1909  return false;
1910  }
1911 
1912  if (Option == "pic") {
1913  getTargetStreamer().emitDirectiveOptionPIC();
1914 
1915  Parser.Lex();
1916  if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1917  return Error(Parser.getTok().getLoc(),
1918  "unexpected token, expected end of statement");
1919 
1920  ParserOptions.IsPicEnabled = true;
1921  return false;
1922  }
1923 
1924  if (Option == "nopic") {
1925  getTargetStreamer().emitDirectiveOptionNoPIC();
1926 
1927  Parser.Lex();
1928  if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1929  return Error(Parser.getTok().getLoc(),
1930  "unexpected token, expected end of statement");
1931 
1932  ParserOptions.IsPicEnabled = false;
1933  return false;
1934  }
1935 
1936  if (Option == "relax") {
1937  getTargetStreamer().emitDirectiveOptionRelax();
1938 
1939  Parser.Lex();
1940  if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1941  return Error(Parser.getTok().getLoc(),
1942  "unexpected token, expected end of statement");
1943 
1944  setFeatureBits(RISCV::FeatureRelax, "relax");
1945  return false;
1946  }
1947 
1948  if (Option == "norelax") {
1949  getTargetStreamer().emitDirectiveOptionNoRelax();
1950 
1951  Parser.Lex();
1952  if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1953  return Error(Parser.getTok().getLoc(),
1954  "unexpected token, expected end of statement");
1955 
1956  clearFeatureBits(RISCV::FeatureRelax, "relax");
1957  return false;
1958  }
1959 
1960  // Unknown option.
1961  Warning(Parser.getTok().getLoc(),
1962  "unknown option, expected 'push', 'pop', 'rvc', 'norvc', 'relax' or "
1963  "'norelax'");
1964  Parser.eatToEndOfStatement();
1965  return false;
1966 }
1967 
1968 /// parseDirectiveAttribute
1969 /// ::= .attribute expression ',' ( expression | "string" )
1970 /// ::= .attribute identifier ',' ( expression | "string" )
1971 bool RISCVAsmParser::parseDirectiveAttribute() {
1972  MCAsmParser &Parser = getParser();
1973  int64_t Tag;
1974  SMLoc TagLoc;
1975  TagLoc = Parser.getTok().getLoc();
1976  if (Parser.getTok().is(AsmToken::Identifier)) {
1977  StringRef Name = Parser.getTok().getIdentifier();
1980  if (!Ret.hasValue()) {
1981  Error(TagLoc, "attribute name not recognised: " + Name);
1982  return false;
1983  }
1984  Tag = Ret.getValue();
1985  Parser.Lex();
1986  } else {
1987  const MCExpr *AttrExpr;
1988 
1989  TagLoc = Parser.getTok().getLoc();
1990  if (Parser.parseExpression(AttrExpr))
1991  return true;
1992 
1993  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr);
1994  if (check(!CE, TagLoc, "expected numeric constant"))
1995  return true;
1996 
1997  Tag = CE->getValue();
1998  }
1999 
2000  if (Parser.parseToken(AsmToken::Comma, "comma expected"))
2001  return true;
2002 
2003  StringRef StringValue;
2004  int64_t IntegerValue = 0;
2005  bool IsIntegerValue = true;
2006 
2007  // RISC-V attributes have a string value if the tag number is odd
2008  // and an integer value if the tag number is even.
2009  if (Tag % 2)
2010  IsIntegerValue = false;
2011 
2012  SMLoc ValueExprLoc = Parser.getTok().getLoc();
2013  if (IsIntegerValue) {
2014  const MCExpr *ValueExpr;
2015  if (Parser.parseExpression(ValueExpr))
2016  return true;
2017 
2018  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr);
2019  if (!CE)
2020  return Error(ValueExprLoc, "expected numeric constant");
2021  IntegerValue = CE->getValue();
2022  } else {
2023  if (Parser.getTok().isNot(AsmToken::String))
2024  return Error(Parser.getTok().getLoc(), "expected string constant");
2025 
2026  StringValue = Parser.getTok().getStringContents();
2027  Parser.Lex();
2028  }
2029 
2031  "unexpected token in '.attribute' directive"))
2032  return true;
2033 
2034  if (Tag == RISCVAttrs::ARCH) {
2035  StringRef Arch = StringValue;
2036  if (Arch.consume_front("rv32"))
2037  clearFeatureBits(RISCV::Feature64Bit, "64bit");
2038  else if (Arch.consume_front("rv64"))
2039  setFeatureBits(RISCV::Feature64Bit, "64bit");
2040  else
2041  return Error(ValueExprLoc, "bad arch string " + Arch);
2042 
2043  while (!Arch.empty()) {
2044  if (Arch[0] == 'i')
2045  clearFeatureBits(RISCV::FeatureRV32E, "e");
2046  else if (Arch[0] == 'e')
2047  setFeatureBits(RISCV::FeatureRV32E, "e");
2048  else if (Arch[0] == 'g') {
2049  clearFeatureBits(RISCV::FeatureRV32E, "e");
2050  setFeatureBits(RISCV::FeatureStdExtM, "m");
2051  setFeatureBits(RISCV::FeatureStdExtA, "a");
2052  setFeatureBits(RISCV::FeatureStdExtF, "f");
2053  setFeatureBits(RISCV::FeatureStdExtD, "d");
2054  } else if (Arch[0] == 'm')
2055  setFeatureBits(RISCV::FeatureStdExtM, "m");
2056  else if (Arch[0] == 'a')
2057  setFeatureBits(RISCV::FeatureStdExtA, "a");
2058  else if (Arch[0] == 'f')
2059  setFeatureBits(RISCV::FeatureStdExtF, "f");
2060  else if (Arch[0] == 'd') {
2061  setFeatureBits(RISCV::FeatureStdExtF, "f");
2062  setFeatureBits(RISCV::FeatureStdExtD, "d");
2063  } else if (Arch[0] == 'c') {
2064  setFeatureBits(RISCV::FeatureStdExtC, "c");
2065  } else
2066  return Error(ValueExprLoc, "bad arch string " + Arch);
2067 
2068  Arch = Arch.drop_front(1);
2069  int major = 0;
2070  int minor = 0;
2071  Arch.consumeInteger(10, major);
2072  Arch.consume_front("p");
2073  Arch.consumeInteger(10, minor);
2074  if (major != 0 || minor != 0) {
2075  Arch = Arch.drop_until([](char c) { return c == '_' || c == '"'; });
2076  Arch = Arch.drop_while([](char c) { return c == '_'; });
2077  }
2078  }
2079  }
2080 
2081  if (IsIntegerValue)
2082  getTargetStreamer().emitAttribute(Tag, IntegerValue);
2083  else {
2084  if (Tag != RISCVAttrs::ARCH) {
2085  getTargetStreamer().emitTextAttribute(Tag, StringValue);
2086  } else {
2087  std::string formalArchStr = "rv32";
2088  if (getFeatureBits(RISCV::Feature64Bit))
2089  formalArchStr = "rv64";
2090  if (getFeatureBits(RISCV::FeatureRV32E))
2091  formalArchStr = (Twine(formalArchStr) + "e1p9").str();
2092  else
2093  formalArchStr = (Twine(formalArchStr) + "i2p0").str();
2094 
2095  if (getFeatureBits(RISCV::FeatureStdExtM))
2096  formalArchStr = (Twine(formalArchStr) + "_m2p0").str();
2097  if (getFeatureBits(RISCV::FeatureStdExtA))
2098  formalArchStr = (Twine(formalArchStr) + "_a2p0").str();
2099  if (getFeatureBits(RISCV::FeatureStdExtF))
2100  formalArchStr = (Twine(formalArchStr) + "_f2p0").str();
2101  if (getFeatureBits(RISCV::FeatureStdExtD))
2102  formalArchStr = (Twine(formalArchStr) + "_d2p0").str();
2103  if (getFeatureBits(RISCV::FeatureStdExtC))
2104  formalArchStr = (Twine(formalArchStr) + "_c2p0").str();
2105 
2106  getTargetStreamer().emitTextAttribute(Tag, formalArchStr);
2107  }
2108  }
2109 
2110  return false;
2111 }
2112 
2113 void RISCVAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) {
2114  MCInst CInst;
2115  bool Res = compressInst(CInst, Inst, getSTI(), S.getContext());
2116  if (Res)
2117  ++RISCVNumInstrsCompressed;
2118  S.emitInstruction((Res ? CInst : Inst), getSTI());
2119 }
2120 
2121 void RISCVAsmParser::emitLoadImm(Register DestReg, int64_t Value,
2122  MCStreamer &Out) {
2124  RISCVMatInt::generateInstSeq(Value, isRV64(), Seq);
2125 
2126  Register SrcReg = RISCV::X0;
2127  for (RISCVMatInt::Inst &Inst : Seq) {
2128  if (Inst.Opc == RISCV::LUI) {
2129  emitToStreamer(
2130  Out, MCInstBuilder(RISCV::LUI).addReg(DestReg).addImm(Inst.Imm));
2131  } else {
2132  emitToStreamer(
2133  Out, MCInstBuilder(Inst.Opc).addReg(DestReg).addReg(SrcReg).addImm(
2134  Inst.Imm));
2135  }
2136 
2137  // Only the first instruction has X0 as its source.
2138  SrcReg = DestReg;
2139  }
2140 }
2141 
2142 void RISCVAsmParser::emitAuipcInstPair(MCOperand DestReg, MCOperand TmpReg,
2143  const MCExpr *Symbol,
2145  unsigned SecondOpcode, SMLoc IDLoc,
2146  MCStreamer &Out) {
2147  // A pair of instructions for PC-relative addressing; expands to
2148  // TmpLabel: AUIPC TmpReg, VKHi(symbol)
2149  // OP DestReg, TmpReg, %pcrel_lo(TmpLabel)
2150  MCContext &Ctx = getContext();
2151 
2152  MCSymbol *TmpLabel = Ctx.createTempSymbol(
2153  "pcrel_hi", /* AlwaysAddSuffix */ true, /* CanBeUnnamed */ false);
2154  Out.emitLabel(TmpLabel);
2155 
2156  const RISCVMCExpr *SymbolHi = RISCVMCExpr::create(Symbol, VKHi, Ctx);
2157  emitToStreamer(
2158  Out, MCInstBuilder(RISCV::AUIPC).addOperand(TmpReg).addExpr(SymbolHi));
2159 
2160  const MCExpr *RefToLinkTmpLabel =
2163 
2164  emitToStreamer(Out, MCInstBuilder(SecondOpcode)
2165  .addOperand(DestReg)
2166  .addOperand(TmpReg)
2167  .addExpr(RefToLinkTmpLabel));
2168 }
2169 
2170 void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
2171  MCStreamer &Out) {
2172  // The load local address pseudo-instruction "lla" is used in PC-relative
2173  // addressing of local symbols:
2174  // lla rdest, symbol
2175  // expands to
2176  // TmpLabel: AUIPC rdest, %pcrel_hi(symbol)
2177  // ADDI rdest, rdest, %pcrel_lo(TmpLabel)
2178  MCOperand DestReg = Inst.getOperand(0);
2179  const MCExpr *Symbol = Inst.getOperand(1).getExpr();
2180  emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI,
2181  RISCV::ADDI, IDLoc, Out);
2182 }
2183 
2184 void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc,
2185  MCStreamer &Out) {
2186  // The load address pseudo-instruction "la" is used in PC-relative and
2187  // GOT-indirect addressing of global symbols:
2188  // la rdest, symbol
2189  // expands to either (for non-PIC)
2190  // TmpLabel: AUIPC rdest, %pcrel_hi(symbol)
2191  // ADDI rdest, rdest, %pcrel_lo(TmpLabel)
2192  // or (for PIC)
2193  // TmpLabel: AUIPC rdest, %got_pcrel_hi(symbol)
2194  // Lx rdest, %pcrel_lo(TmpLabel)(rdest)
2195  MCOperand DestReg = Inst.getOperand(0);
2196  const MCExpr *Symbol = Inst.getOperand(1).getExpr();
2197  unsigned SecondOpcode;
2199  if (ParserOptions.IsPicEnabled) {
2200  SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
2202  } else {
2203  SecondOpcode = RISCV::ADDI;
2205  }
2206  emitAuipcInstPair(DestReg, DestReg, Symbol, VKHi, SecondOpcode, IDLoc, Out);
2207 }
2208 
2209 void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc,
2210  MCStreamer &Out) {
2211  // The load TLS IE address pseudo-instruction "la.tls.ie" is used in
2212  // initial-exec TLS model addressing of global symbols:
2213  // la.tls.ie rdest, symbol
2214  // expands to
2215  // TmpLabel: AUIPC rdest, %tls_ie_pcrel_hi(symbol)
2216  // Lx rdest, %pcrel_lo(TmpLabel)(rdest)
2217  MCOperand DestReg = Inst.getOperand(0);
2218  const MCExpr *Symbol = Inst.getOperand(1).getExpr();
2219  unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
2220  emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_TLS_GOT_HI,
2221  SecondOpcode, IDLoc, Out);
2222 }
2223 
2224 void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc,
2225  MCStreamer &Out) {
2226  // The load TLS GD address pseudo-instruction "la.tls.gd" is used in
2227  // global-dynamic TLS model addressing of global symbols:
2228  // la.tls.gd rdest, symbol
2229  // expands to
2230  // TmpLabel: AUIPC rdest, %tls_gd_pcrel_hi(symbol)
2231  // ADDI rdest, rdest, %pcrel_lo(TmpLabel)
2232  MCOperand DestReg = Inst.getOperand(0);
2233  const MCExpr *Symbol = Inst.getOperand(1).getExpr();
2234  emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_TLS_GD_HI,
2235  RISCV::ADDI, IDLoc, Out);
2236 }
2237 
2238 void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode,
2239  SMLoc IDLoc, MCStreamer &Out,
2240  bool HasTmpReg) {
2241  // The load/store pseudo-instruction does a pc-relative load with
2242  // a symbol.
2243  //
2244  // The expansion looks like this
2245  //
2246  // TmpLabel: AUIPC tmp, %pcrel_hi(symbol)
2247  // [S|L]X rd, %pcrel_lo(TmpLabel)(tmp)
2248  MCOperand DestReg = Inst.getOperand(0);
2249  unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
2250  unsigned TmpRegOpIdx = HasTmpReg ? 1 : 0;
2251  MCOperand TmpReg = Inst.getOperand(TmpRegOpIdx);
2252  const MCExpr *Symbol = Inst.getOperand(SymbolOpIdx).getExpr();
2253  emitAuipcInstPair(DestReg, TmpReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI,
2254  Opcode, IDLoc, Out);
2255 }
2256 
2257 bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
2258  OperandVector &Operands) {
2259  assert(Inst.getOpcode() == RISCV::PseudoAddTPRel && "Invalid instruction");
2260  assert(Inst.getOperand(2).isReg() && "Unexpected second operand kind");
2261  if (Inst.getOperand(2).getReg() != RISCV::X4) {
2262  SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();
2263  return Error(ErrorLoc, "the second input operand must be tp/x4 when using "
2264  "%tprel_add modifier");
2265  }
2266 
2267  return false;
2268 }
2269 
2270 std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp() const {
2271  return RISCVOperand::createReg(RISCV::NoRegister, llvm::SMLoc(),
2272  llvm::SMLoc(), isRV64());
2273 }
2274 
2275 bool RISCVAsmParser::validateInstruction(MCInst &Inst,
2276  OperandVector &Operands) {
2277  const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
2278  unsigned TargetFlags =
2280  if (TargetFlags == RISCV::NoConstraint)
2281  return false;
2282 
2283  unsigned DestReg = Inst.getOperand(0).getReg();
2284  // Operands[1] will be the first operand, DestReg.
2285  SMLoc Loc = Operands[1]->getStartLoc();
2286  if ((TargetFlags == RISCV::WidenV) || (TargetFlags == RISCV::WidenW) ||
2287  (TargetFlags == RISCV::SlideUp) || (TargetFlags == RISCV::Vrgather) ||
2288  (TargetFlags == RISCV::Vcompress)) {
2289  if (TargetFlags != RISCV::WidenW) {
2290  unsigned Src2Reg = Inst.getOperand(1).getReg();
2291  if (DestReg == Src2Reg)
2292  return Error(Loc, "The destination vector register group cannot overlap"
2293  " the source vector register group.");
2294  if (TargetFlags == RISCV::WidenV) {
2295  // Assume DestReg LMUL is 2 at least for widening/narrowing operations.
2296  if (DestReg + 1 == Src2Reg)
2297  return Error(Loc,
2298  "The destination vector register group cannot overlap"
2299  " the source vector register group.");
2300  }
2301  }
2302  if (Inst.getOperand(2).isReg()) {
2303  unsigned Src1Reg = Inst.getOperand(2).getReg();
2304  if (DestReg == Src1Reg)
2305  return Error(Loc, "The destination vector register group cannot overlap"
2306  " the source vector register group.");
2307  if (TargetFlags == RISCV::WidenV || TargetFlags == RISCV::WidenW) {
2308  // Assume DestReg LMUL is 2 at least for widening/narrowing operations.
2309  if (DestReg + 1 == Src1Reg)
2310  return Error(Loc,
2311  "The destination vector register group cannot overlap"
2312  " the source vector register group.");
2313  }
2314  }
2315  if (Inst.getNumOperands() == 4) {
2316  unsigned MaskReg = Inst.getOperand(3).getReg();
2317 
2318  if (DestReg == MaskReg)
2319  return Error(Loc, "The destination vector register group cannot overlap"
2320  " the mask register.");
2321  }
2322  } else if (TargetFlags == RISCV::Narrow) {
2323  unsigned Src2Reg = Inst.getOperand(1).getReg();
2324  if (DestReg == Src2Reg)
2325  return Error(Loc, "The destination vector register group cannot overlap"
2326  " the source vector register group.");
2327  // Assume Src2Reg LMUL is 2 at least for widening/narrowing operations.
2328  if (DestReg == Src2Reg + 1)
2329  return Error(Loc, "The destination vector register group cannot overlap"
2330  " the source vector register group.");
2331  } else if (TargetFlags == RISCV::WidenCvt || TargetFlags == RISCV::Iota) {
2332  unsigned Src2Reg = Inst.getOperand(1).getReg();
2333  if (DestReg == Src2Reg)
2334  return Error(Loc, "The destination vector register group cannot overlap"
2335  " the source vector register group.");
2336  if (TargetFlags == RISCV::WidenCvt) {
2337  // Assume DestReg LMUL is 2 at least for widening/narrowing operations.
2338  if (DestReg + 1 == Src2Reg)
2339  return Error(Loc, "The destination vector register group cannot overlap"
2340  " the source vector register group.");
2341  }
2342  if (Inst.getNumOperands() == 3) {
2343  unsigned MaskReg = Inst.getOperand(2).getReg();
2344 
2345  if (DestReg == MaskReg)
2346  return Error(Loc, "The destination vector register group cannot overlap"
2347  " the mask register.");
2348  }
2349  }
2350  return false;
2351 }
2352 
2353 bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
2354  OperandVector &Operands,
2355  MCStreamer &Out) {
2356  Inst.setLoc(IDLoc);
2357 
2358  switch (Inst.getOpcode()) {
2359  default:
2360  break;
2361  case RISCV::PseudoLI: {
2362  Register Reg = Inst.getOperand(0).getReg();
2363  const MCOperand &Op1 = Inst.getOperand(1);
2364  if (Op1.isExpr()) {
2365  // We must have li reg, %lo(sym) or li reg, %pcrel_lo(sym) or similar.
2366  // Just convert to an addi. This allows compatibility with gas.
2367  emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
2368  .addReg(Reg)
2369  .addReg(RISCV::X0)
2370  .addExpr(Op1.getExpr()));
2371  return false;
2372  }
2373  int64_t Imm = Inst.getOperand(1).getImm();
2374  // On RV32 the immediate here can either be a signed or an unsigned
2375  // 32-bit number. Sign extension has to be performed to ensure that Imm
2376  // represents the expected signed 64-bit number.
2377  if (!isRV64())
2378  Imm = SignExtend64<32>(Imm);
2379  emitLoadImm(Reg, Imm, Out);
2380  return false;
2381  }
2382  case RISCV::PseudoLLA:
2383  emitLoadLocalAddress(Inst, IDLoc, Out);
2384  return false;
2385  case RISCV::PseudoLA:
2386  emitLoadAddress(Inst, IDLoc, Out);
2387  return false;
2388  case RISCV::PseudoLA_TLS_IE:
2389  emitLoadTLSIEAddress(Inst, IDLoc, Out);
2390  return false;
2391  case RISCV::PseudoLA_TLS_GD:
2392  emitLoadTLSGDAddress(Inst, IDLoc, Out);
2393  return false;
2394  case RISCV::PseudoLB:
2395  emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out, /*HasTmpReg=*/false);
2396  return false;
2397  case RISCV::PseudoLBU:
2398  emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out, /*HasTmpReg=*/false);
2399  return false;
2400  case RISCV::PseudoLH:
2401  emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out, /*HasTmpReg=*/false);
2402  return false;
2403  case RISCV::PseudoLHU:
2404  emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out, /*HasTmpReg=*/false);
2405  return false;
2406  case RISCV::PseudoLW:
2407  emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out, /*HasTmpReg=*/false);
2408  return false;
2409  case RISCV::PseudoLWU:
2410  emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out, /*HasTmpReg=*/false);
2411  return false;
2412  case RISCV::PseudoLD:
2413  emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out, /*HasTmpReg=*/false);
2414  return false;
2415  case RISCV::PseudoFLW:
2416  emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out, /*HasTmpReg=*/true);
2417  return false;
2418  case RISCV::PseudoFLD:
2419  emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out, /*HasTmpReg=*/true);
2420  return false;
2421  case RISCV::PseudoSB:
2422  emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out, /*HasTmpReg=*/true);
2423  return false;
2424  case RISCV::PseudoSH:
2425  emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out, /*HasTmpReg=*/true);
2426  return false;
2427  case RISCV::PseudoSW:
2428  emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out, /*HasTmpReg=*/true);
2429  return false;
2430  case RISCV::PseudoSD:
2431  emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out, /*HasTmpReg=*/true);
2432  return false;
2433  case RISCV::PseudoFSW:
2434  emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out, /*HasTmpReg=*/true);
2435  return false;
2436  case RISCV::PseudoFSD:
2437  emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out, /*HasTmpReg=*/true);
2438  return false;
2439  case RISCV::PseudoAddTPRel:
2440  if (checkPseudoAddTPRel(Inst, Operands))
2441  return true;
2442  break;
2443  }
2444 
2445  emitToStreamer(Out, Inst);
2446  return false;
2447 }
2448 
2452 }
static bool isReg(const MCInst &MI, unsigned OpNo)
constexpr bool isUInt< 32 >(uint64_t x)
Definition: MathExtras.h:412
Represents a range in source code.
Definition: SMLoc.h:48
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Definition: MCStreamer.cpp:395
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
LLVM_NODISCARD std::enable_if_t< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type > dyn_cast(const Y &Val)
Definition: Casting.h:334
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
Definition: MCAsmMacro.h:110
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:384
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:289
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
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)
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:187
constexpr size_t size() const
Target specific streamer interface.
Definition: MCStreamer.h:90
unsigned Reg
bool consume_front(StringRef Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
Definition: StringRef.h:683
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:627
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
STATISTIC(NumFunctions, "Total number of functions")
const AsmToken & getTok() const
Get the current AsmToken from the stream.
Definition: MCAsmParser.cpp:38
static Register convertFPR64ToFPR32(Register Reg)
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:265
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string...
Definition: MCAsmMacro.h:99
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition: MCExpr.cpp:186
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
LLVM_NODISCARD StringRef drop_front(size_t N=1) const
Return a StringRef equal to &#39;this&#39; but with the first N elements dropped.
Definition: StringRef.h:654
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:43
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:192
Target & getTheRISCV32Target()
mir Rename Register Operands
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:156
static bool isMem(const MachineInstr &MI, unsigned Op)
Definition: X86InstrInfo.h:123
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand...
std::enable_if_t< std::numeric_limits< T >::is_signed, bool > consumeInteger(unsigned Radix, T &Result)
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:545
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:64
StringRef str() const
Explicit conversion to StringRef.
Definition: SmallString.h:266
Context object for machine code objects.
Definition: MCContext.h:67
std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \\\)
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
void ashrInPlace(unsigned ShiftAmt)
Arithmetic right-shift this APInt by ShiftAmt in place.
Definition: APInt.h:972
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:630
const T & getValue() const LLVM_LVALUE_FUNCTION
Definition: Optional.h:255
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:160
SMLoc getLoc() const
Definition: MCAsmLexer.cpp:27
const MCExpr * getExpr() const
Definition: MCInst.h:95
Optional< unsigned > attrTypeFromString(StringRef tag, TagNameMap tagNameMap)
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:158
Analysis containing CSE Info
Definition: CSEInfo.cpp:25
static const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition: MCExpr.cpp:175
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
void append(in_iter S, in_iter E)
Append from an iterator pair.
Definition: SmallString.h:74
LLVM_NODISCARD StringRef drop_until(function_ref< bool(char)> F) const
Return a StringRef equal to &#39;this&#39;, but with all characters not satisfying the given predicate droppe...
Definition: StringRef.h:677
FeatureBitset ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
int64_t getImm() const
Definition: MCInst.h:75
bool parseToken(AsmToken::TokenKind T, const Twine &Msg="unexpected token")
Definition: MCAsmParser.cpp:54
const char * getPointer() const
Definition: SMLoc.h:34
int64_t getValue() const
Definition: MCExpr.h:173
virtual MCContext & getContext()=0
Streaming machine code generation interface.
Definition: MCStreamer.h:196
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:239
MCTargetStreamer * getTargetStreamer()
Definition: MCStreamer.h:272
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:380
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
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:25
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:305
constexpr double e
Definition: MathExtras.h:58
const MCObjectFileInfo * getObjectFileInfo() const
Definition: MCContext.h:367
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
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
unsigned getNumOperands() const
Definition: MCInst.h:182
Binary assembler expressions.
Definition: MCExpr.h:481
void setLoc(SMLoc loc)
Definition: MCInst.h:177
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static unsigned MatchRegisterAltName(StringRef Name)
Maps from the set of all alternative registernames to a register number.
static std::string RISCVMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
MCStreamer & getStreamer()
Definition: MCStreamer.h:98
constexpr bool isInt< 32 >(int64_t x)
Definition: MathExtras.h:374
Align max(MaybeAlign Lhs, Align Rhs)
Definition: Alignment.h:350
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:883
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:180
Promote Memory to Register
Definition: Mem2Reg.cpp:110
LLVM_NODISCARD T pop_back_val()
Definition: SmallVector.h:420
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:131
unsigned logBase2() const
Definition: APInt.h:1808
bool is(TokenKind K) const
Definition: MCAsmMacro.h:82
Class for arbitrary precision integers.
Definition: APInt.h:69
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
const SysReg * lookupSysRegByName(StringRef)
Base class for user error types.
Definition: Error.h:350
static SMLoc getFromPointer(const char *Ptr)
Definition: SMLoc.h:36
bool hasValue() const
Definition: Optional.h:259
static VariantKind getVariantKindForName(StringRef name)
void generateInstSeq(int64_t Val, bool IsRV64, InstSeq &Res)
Definition: RISCVMatInt.cpp:19
LLVM_NODISCARD StringRef drop_while(function_ref< bool(char)> F) const
Return a StringRef equal to &#39;this&#39;, but with all characters satisfying the given predicate dropped fr...
Definition: StringRef.h:670
const TagNameMap RISCVAttributeTags
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
Definition: MCInstrInfo.h:62
StringRef getStringContents() const
Get the contents of a string token (without quotes).
Definition: MCAsmMacro.h:90
#define N
Generic base class for all target subtargets.
bool consume_back(StringRef Suffix)
Returns true if this StringRef has the given suffix and removes that suffix.
Definition: StringRef.h:693
Opcode getOpcode() const
Get the kind of this binary expression.
Definition: MCExpr.h:624
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVAsmParser()
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:152
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const MCExpr * getVariableValue(bool SetUsed=true) const
getVariableValue - Get the value for variable symbols.
Definition: MCSymbol.h:294
LLVM Value Representation.
Definition: Value.h:74
const SysReg * lookupSysRegByEncoding(uint16_t)
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:46
Subtraction.
Definition: MCExpr.h:505
void addOperand(const MCOperand &Op)
Definition: MCInst.h:184
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
bool isPositionIndependent() const
Represents a location in source code.
Definition: SMLoc.h:23
static const char * getSubtargetFeatureName(uint64_t Val)
unsigned getOpcode() const
Definition: MCInst.h:172
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)