LLVM  15.0.0git
CSKYAsmParser.cpp
Go to the documentation of this file.
1 //===---- CSKYAsmParser.cpp - Parse CSKY assembly to MCInst instructions --===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
14 #include "llvm/ADT/STLExtras.h"
15 #include "llvm/ADT/Statistic.h"
16 #include "llvm/ADT/StringSwitch.h"
17 #include "llvm/BinaryFormat/ELF.h"
18 #include "llvm/CodeGen/Register.h"
19 #include "llvm/MC/MCContext.h"
20 #include "llvm/MC/MCExpr.h"
21 #include "llvm/MC/MCInst.h"
22 #include "llvm/MC/MCInstrInfo.h"
26 #include "llvm/MC/MCRegisterInfo.h"
27 #include "llvm/MC/MCSectionELF.h"
28 #include "llvm/MC/MCStreamer.h"
30 #include "llvm/MC/TargetRegistry.h"
33 #include "llvm/Support/Casting.h"
35 #include "llvm/Support/Debug.h"
36 
37 using namespace llvm;
38 
39 #define DEBUG_TYPE "csky-asm-parser"
40 
41 // Include the auto-generated portion of the compress emitter.
42 #define GEN_COMPRESS_INSTR
43 #include "CSKYGenCompressInstEmitter.inc"
44 
45 STATISTIC(CSKYNumInstrsCompressed,
46  "Number of C-SKY Compressed instructions emitted");
47 
48 static cl::opt<bool>
49  EnableCompressedInst("enable-csky-asm-compressed-inst", cl::Hidden,
50  cl::init(false),
51  cl::desc("Enable C-SKY asm compressed instruction"));
52 
53 namespace {
54 struct CSKYOperand;
55 
56 class CSKYAsmParser : public MCTargetAsmParser {
57 
58  const MCRegisterInfo *MRI;
59 
60  unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
61  unsigned Kind) override;
62 
63  bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo,
64  int64_t Lower, int64_t Upper, Twine Msg);
65 
66  SMLoc getLoc() const { return getParser().getTok().getLoc(); }
67 
68  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
71  bool MatchingInlineAsm) override;
72 
73  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
74 
75  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
76  SMLoc NameLoc, OperandVector &Operands) override;
77 
78  bool ParseDirective(AsmToken DirectiveID) override;
79 
80  // Helper to actually emit an instruction to the MCStreamer. Also, when
81  // possible, compression of the instruction is performed.
82  void emitToStreamer(MCStreamer &S, const MCInst &Inst);
83 
84  OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc,
85  SMLoc &EndLoc) override;
86 
87  bool processInstruction(MCInst &Inst, SMLoc IDLoc, OperandVector &Operands,
88  MCStreamer &Out);
89  bool processLRW(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
90  bool processJSRI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
91  bool processJMPI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
92 
93  CSKYTargetStreamer &getTargetStreamer() {
94  assert(getParser().getStreamer().getTargetStreamer() &&
95  "do not have a target streamer");
96  MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
97  return static_cast<CSKYTargetStreamer &>(TS);
98  }
99 
100 // Auto-generated instruction matching functions
101 #define GET_ASSEMBLER_HEADER
102 #include "CSKYGenAsmMatcher.inc"
103 
106  OperandMatchResultTy parseBaseRegImm(OperandVector &Operands);
107  OperandMatchResultTy parseCSKYSymbol(OperandVector &Operands);
108  OperandMatchResultTy parseConstpoolSymbol(OperandVector &Operands);
109  OperandMatchResultTy parseDataSymbol(OperandVector &Operands);
113 
114  bool parseOperand(OperandVector &Operands, StringRef Mnemonic);
115 
116  bool parseDirectiveAttribute();
117 
118 public:
119  enum CSKYMatchResultTy {
120  Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
121  Match_RequiresSameSrcAndDst,
122  Match_InvalidRegOutOfRange,
123 #define GET_OPERAND_DIAGNOSTIC_TYPES
124 #include "CSKYGenAsmMatcher.inc"
125 #undef GET_OPERAND_DIAGNOSTIC_TYPES
126  };
127 
128  CSKYAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
129  const MCInstrInfo &MII, const MCTargetOptions &Options)
130  : MCTargetAsmParser(Options, STI, MII) {
131 
133 
134  // Cache the MCRegisterInfo.
135  MRI = getContext().getRegisterInfo();
136 
137  setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
138  getTargetStreamer().emitTargetAttributes(STI);
139  }
140 };
141 
142 /// Instances of this class represent a parsed machine instruction.
143 struct CSKYOperand : public MCParsedAsmOperand {
144 
145  enum KindTy {
146  Token,
147  Register,
148  Immediate,
149  RegisterSeq,
150  CPOP,
151  RegisterList
152  } Kind;
153 
154  struct RegOp {
155  unsigned RegNum;
156  };
157 
158  struct ImmOp {
159  const MCExpr *Val;
160  };
161 
162  struct ConstpoolOp {
163  const MCExpr *Val;
164  };
165 
166  struct RegSeqOp {
167  unsigned RegNumFrom;
168  unsigned RegNumTo;
169  };
170 
171  struct RegListOp {
172  unsigned List1From = 0;
173  unsigned List1To = 0;
174  unsigned List2From = 0;
175  unsigned List2To = 0;
176  unsigned List3From = 0;
177  unsigned List3To = 0;
178  unsigned List4From = 0;
179  unsigned List4To = 0;
180  };
181 
182  SMLoc StartLoc, EndLoc;
183  union {
184  StringRef Tok;
185  RegOp Reg;
186  ImmOp Imm;
187  ConstpoolOp CPool;
188  RegSeqOp RegSeq;
189  RegListOp RegList;
190  };
191 
192  CSKYOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
193 
194 public:
195  CSKYOperand(const CSKYOperand &o) : MCParsedAsmOperand() {
196  Kind = o.Kind;
197  StartLoc = o.StartLoc;
198  EndLoc = o.EndLoc;
199  switch (Kind) {
200  case Register:
201  Reg = o.Reg;
202  break;
203  case RegisterSeq:
204  RegSeq = o.RegSeq;
205  break;
206  case CPOP:
207  CPool = o.CPool;
208  break;
209  case Immediate:
210  Imm = o.Imm;
211  break;
212  case Token:
213  Tok = o.Tok;
214  break;
215  case RegisterList:
216  RegList = o.RegList;
217  break;
218  }
219  }
220 
221  bool isToken() const override { return Kind == Token; }
222  bool isReg() const override { return Kind == Register; }
223  bool isImm() const override { return Kind == Immediate; }
224  bool isRegisterSeq() const { return Kind == RegisterSeq; }
225  bool isRegisterList() const { return Kind == RegisterList; }
226  bool isConstPoolOp() const { return Kind == CPOP; }
227 
228  bool isMem() const override { return false; }
229 
230  static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm) {
231  if (auto CE = dyn_cast<MCConstantExpr>(Expr)) {
232  Imm = CE->getValue();
233  return true;
234  }
235 
236  return false;
237  }
238 
239  template <unsigned num, unsigned shift = 0> bool isUImm() const {
240  if (!isImm())
241  return false;
242 
243  int64_t Imm;
244  bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
245  return IsConstantImm && isShiftedUInt<num, shift>(Imm);
246  }
247 
248  template <unsigned num> bool isOImm() const {
249  if (!isImm())
250  return false;
251 
252  int64_t Imm;
253  bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
254  return IsConstantImm && isUInt<num>(Imm - 1);
255  }
256 
257  template <unsigned num, unsigned shift = 0> bool isSImm() const {
258  if (!isImm())
259  return false;
260 
261  int64_t Imm;
262  bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
263  return IsConstantImm && isShiftedInt<num, shift>(Imm);
264  }
265 
266  bool isUImm1() const { return isUImm<1>(); }
267  bool isUImm2() const { return isUImm<2>(); }
268  bool isUImm3() const { return isUImm<3>(); }
269  bool isUImm4() const { return isUImm<4>(); }
270  bool isUImm5() const { return isUImm<5>(); }
271  bool isUImm6() const { return isUImm<6>(); }
272  bool isUImm7() const { return isUImm<7>(); }
273  bool isUImm8() const { return isUImm<8>(); }
274  bool isUImm12() const { return isUImm<12>(); }
275  bool isUImm16() const { return isUImm<16>(); }
276  bool isUImm20() const { return isUImm<20>(); }
277  bool isUImm24() const { return isUImm<24>(); }
278 
279  bool isOImm3() const { return isOImm<3>(); }
280  bool isOImm4() const { return isOImm<4>(); }
281  bool isOImm5() const { return isOImm<5>(); }
282  bool isOImm6() const { return isOImm<6>(); }
283  bool isOImm8() const { return isOImm<8>(); }
284  bool isOImm12() const { return isOImm<12>(); }
285  bool isOImm16() const { return isOImm<16>(); }
286 
287  bool isSImm8() const { return isSImm<8>(); }
288 
289  bool isUImm5Shift1() { return isUImm<5, 1>(); }
290  bool isUImm5Shift2() { return isUImm<5, 2>(); }
291  bool isUImm7Shift1() { return isUImm<7, 1>(); }
292  bool isUImm7Shift2() { return isUImm<7, 2>(); }
293  bool isUImm7Shift3() { return isUImm<7, 3>(); }
294  bool isUImm8Shift2() { return isUImm<8, 2>(); }
295  bool isUImm8Shift3() { return isUImm<8, 3>(); }
296  bool isUImm8Shift8() { return isUImm<8, 8>(); }
297  bool isUImm8Shift16() { return isUImm<8, 16>(); }
298  bool isUImm8Shift24() { return isUImm<8, 24>(); }
299  bool isUImm12Shift1() { return isUImm<12, 1>(); }
300  bool isUImm12Shift2() { return isUImm<12, 2>(); }
301  bool isUImm16Shift8() { return isUImm<16, 8>(); }
302  bool isUImm16Shift16() { return isUImm<16, 16>(); }
303  bool isUImm24Shift8() { return isUImm<24, 8>(); }
304 
305  bool isSImm16Shift1() { return isSImm<16, 1>(); }
306 
307  bool isCSKYSymbol() const { return isImm(); }
308 
309  bool isConstpool() const { return isConstPoolOp(); }
310  bool isDataSymbol() const { return isConstPoolOp(); }
311 
312  bool isPSRFlag() const {
313  int64_t Imm;
314  // Must be of 'immediate' type and a constant.
315  if (!isImm() || !evaluateConstantImm(getImm(), Imm))
316  return false;
317 
318  return isUInt<5>(Imm);
319  }
320 
321  template <unsigned MIN, unsigned MAX> bool isRegSeqTemplate() const {
322  if (!isRegisterSeq())
323  return false;
324 
325  std::pair<unsigned, unsigned> regSeq = getRegSeq();
326 
327  return MIN <= regSeq.first && regSeq.first <= regSeq.second &&
328  regSeq.second <= MAX;
329  }
330 
331  bool isRegSeq() const { return isRegSeqTemplate<CSKY::R0, CSKY::R31>(); }
332 
333  bool isRegSeqV1() const {
334  return isRegSeqTemplate<CSKY::F0_32, CSKY::F15_32>();
335  }
336 
337  bool isRegSeqV2() const {
338  return isRegSeqTemplate<CSKY::F0_32, CSKY::F31_32>();
339  }
340 
341  static bool isLegalRegList(unsigned from, unsigned to) {
342  if (from == 0 && to == 0)
343  return true;
344 
345  if (from == to) {
346  if (from != CSKY::R4 && from != CSKY::R15 && from != CSKY::R16 &&
347  from != CSKY::R28)
348  return false;
349 
350  return true;
351  } else {
352  if (from != CSKY::R4 && from != CSKY::R16)
353  return false;
354 
355  if (from == CSKY::R4 && to > CSKY::R4 && to < CSKY::R12)
356  return true;
357  else if (from == CSKY::R16 && to > CSKY::R16 && to < CSKY::R18)
358  return true;
359  else
360  return false;
361  }
362  }
363 
364  bool isRegList() const {
365  if (!isRegisterList())
366  return false;
367 
368  auto regList = getRegList();
369 
370  if (!isLegalRegList(regList.List1From, regList.List1To))
371  return false;
372  if (!isLegalRegList(regList.List2From, regList.List2To))
373  return false;
374  if (!isLegalRegList(regList.List3From, regList.List3To))
375  return false;
376  if (!isLegalRegList(regList.List4From, regList.List4To))
377  return false;
378 
379  return true;
380  }
381 
382  bool isExtImm6() {
383  if (!isImm())
384  return false;
385 
386  int64_t Imm;
387  bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
388  if (!IsConstantImm)
389  return false;
390 
391  int uimm4 = Imm & 0xf;
392 
393  return isShiftedUInt<6, 0>(Imm) && uimm4 >= 0 && uimm4 <= 14;
394  }
395 
396  /// Gets location of the first token of this operand.
397  SMLoc getStartLoc() const override { return StartLoc; }
398  /// Gets location of the last token of this operand.
399  SMLoc getEndLoc() const override { return EndLoc; }
400 
401  unsigned getReg() const override {
402  assert(Kind == Register && "Invalid type access!");
403  return Reg.RegNum;
404  }
405 
406  std::pair<unsigned, unsigned> getRegSeq() const {
407  assert(Kind == RegisterSeq && "Invalid type access!");
408  return std::pair<unsigned, unsigned>(RegSeq.RegNumFrom, RegSeq.RegNumTo);
409  }
410 
411  RegListOp getRegList() const {
412  assert(Kind == RegisterList && "Invalid type access!");
413  return RegList;
414  }
415 
416  const MCExpr *getImm() const {
417  assert(Kind == Immediate && "Invalid type access!");
418  return Imm.Val;
419  }
420 
421  const MCExpr *getConstpoolOp() const {
422  assert(Kind == CPOP && "Invalid type access!");
423  return CPool.Val;
424  }
425 
426  StringRef getToken() const {
427  assert(Kind == Token && "Invalid type access!");
428  return Tok;
429  }
430 
431  void print(raw_ostream &OS) const override {
432  auto RegName = [](unsigned Reg) {
433  if (Reg)
435  else
436  return "noreg";
437  };
438 
439  switch (Kind) {
440  case CPOP:
441  OS << *getConstpoolOp();
442  break;
443  case Immediate:
444  OS << *getImm();
445  break;
446  case KindTy::Register:
447  OS << "<register " << RegName(getReg()) << ">";
448  break;
449  case RegisterSeq:
450  OS << "<register-seq ";
451  OS << RegName(getRegSeq().first) << "-" << RegName(getRegSeq().second)
452  << ">";
453  break;
454  case RegisterList:
455  OS << "<register-list ";
456  OS << RegName(getRegList().List1From) << "-"
457  << RegName(getRegList().List1To) << ",";
458  OS << RegName(getRegList().List2From) << "-"
459  << RegName(getRegList().List2To) << ",";
460  OS << RegName(getRegList().List3From) << "-"
461  << RegName(getRegList().List3To) << ",";
462  OS << RegName(getRegList().List4From) << "-"
463  << RegName(getRegList().List4To);
464  break;
465  case Token:
466  OS << "'" << getToken() << "'";
467  break;
468  }
469  }
470 
471  static std::unique_ptr<CSKYOperand> createToken(StringRef Str, SMLoc S) {
472  auto Op = std::make_unique<CSKYOperand>(Token);
473  Op->Tok = Str;
474  Op->StartLoc = S;
475  Op->EndLoc = S;
476  return Op;
477  }
478 
479  static std::unique_ptr<CSKYOperand> createReg(unsigned RegNo, SMLoc S,
480  SMLoc E) {
481  auto Op = std::make_unique<CSKYOperand>(Register);
482  Op->Reg.RegNum = RegNo;
483  Op->StartLoc = S;
484  Op->EndLoc = E;
485  return Op;
486  }
487 
488  static std::unique_ptr<CSKYOperand> createRegSeq(unsigned RegNoFrom,
489  unsigned RegNoTo, SMLoc S) {
490  auto Op = std::make_unique<CSKYOperand>(RegisterSeq);
491  Op->RegSeq.RegNumFrom = RegNoFrom;
492  Op->RegSeq.RegNumTo = RegNoTo;
493  Op->StartLoc = S;
494  Op->EndLoc = S;
495  return Op;
496  }
497 
498  static std::unique_ptr<CSKYOperand>
499  createRegList(SmallVector<unsigned, 4> reglist, SMLoc S) {
500  auto Op = std::make_unique<CSKYOperand>(RegisterList);
501  Op->RegList.List1From = 0;
502  Op->RegList.List1To = 0;
503  Op->RegList.List2From = 0;
504  Op->RegList.List2To = 0;
505  Op->RegList.List3From = 0;
506  Op->RegList.List3To = 0;
507  Op->RegList.List4From = 0;
508  Op->RegList.List4To = 0;
509 
510  for (unsigned i = 0; i < reglist.size(); i += 2) {
511  if (Op->RegList.List1From == 0) {
512  Op->RegList.List1From = reglist[i];
513  Op->RegList.List1To = reglist[i + 1];
514  } else if (Op->RegList.List2From == 0) {
515  Op->RegList.List2From = reglist[i];
516  Op->RegList.List2To = reglist[i + 1];
517  } else if (Op->RegList.List3From == 0) {
518  Op->RegList.List3From = reglist[i];
519  Op->RegList.List3To = reglist[i + 1];
520  } else if (Op->RegList.List4From == 0) {
521  Op->RegList.List4From = reglist[i];
522  Op->RegList.List4To = reglist[i + 1];
523  } else {
524  assert(0);
525  }
526  }
527 
528  Op->StartLoc = S;
529  Op->EndLoc = S;
530  return Op;
531  }
532 
533  static std::unique_ptr<CSKYOperand> createImm(const MCExpr *Val, SMLoc S,
534  SMLoc E) {
535  auto Op = std::make_unique<CSKYOperand>(Immediate);
536  Op->Imm.Val = Val;
537  Op->StartLoc = S;
538  Op->EndLoc = E;
539  return Op;
540  }
541 
542  static std::unique_ptr<CSKYOperand> createConstpoolOp(const MCExpr *Val,
543  SMLoc S, SMLoc E) {
544  auto Op = std::make_unique<CSKYOperand>(CPOP);
545  Op->CPool.Val = Val;
546  Op->StartLoc = S;
547  Op->EndLoc = E;
548  return Op;
549  }
550 
551  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
552  assert(Expr && "Expr shouldn't be null!");
553  if (auto *CE = dyn_cast<MCConstantExpr>(Expr))
554  Inst.addOperand(MCOperand::createImm(CE->getValue()));
555  else
556  Inst.addOperand(MCOperand::createExpr(Expr));
557  }
558 
559  // Used by the TableGen Code.
560  void addRegOperands(MCInst &Inst, unsigned N) const {
561  assert(N == 1 && "Invalid number of operands!");
563  }
564 
565  void addImmOperands(MCInst &Inst, unsigned N) const {
566  assert(N == 1 && "Invalid number of operands!");
567  addExpr(Inst, getImm());
568  }
569 
570  void addConstpoolOperands(MCInst &Inst, unsigned N) const {
571  assert(N == 1 && "Invalid number of operands!");
572  Inst.addOperand(MCOperand::createExpr(getConstpoolOp()));
573  }
574 
575  void addRegSeqOperands(MCInst &Inst, unsigned N) const {
576  assert(N == 2 && "Invalid number of operands!");
577  auto regSeq = getRegSeq();
578 
579  Inst.addOperand(MCOperand::createReg(regSeq.first));
580  Inst.addOperand(MCOperand::createReg(regSeq.second));
581  }
582 
583  static unsigned getListValue(unsigned ListFrom, unsigned ListTo) {
584  if (ListFrom == ListTo && ListFrom == CSKY::R15)
585  return (1 << 4);
586  else if (ListFrom == ListTo && ListFrom == CSKY::R28)
587  return (1 << 8);
588  else if (ListFrom == CSKY::R4)
589  return ListTo - ListFrom + 1;
590  else if (ListFrom == CSKY::R16)
591  return ((ListTo - ListFrom + 1) << 5);
592  else
593  return 0;
594  }
595 
596  void addRegListOperands(MCInst &Inst, unsigned N) const {
597  assert(N == 1 && "Invalid number of operands!");
598  auto regList = getRegList();
599 
600  unsigned V = 0;
601 
602  unsigned T = getListValue(regList.List1From, regList.List1To);
603  if (T != 0)
604  V = V | T;
605 
606  T = getListValue(regList.List2From, regList.List2To);
607  if (T != 0)
608  V = V | T;
609 
610  T = getListValue(regList.List3From, regList.List3To);
611  if (T != 0)
612  V = V | T;
613 
614  T = getListValue(regList.List4From, regList.List4To);
615  if (T != 0)
616  V = V | T;
617 
619  }
620 
621  bool isValidForTie(const CSKYOperand &Other) const {
622  if (Kind != Other.Kind)
623  return false;
624 
625  switch (Kind) {
626  default:
627  llvm_unreachable("Unexpected kind");
628  return false;
629  case Register:
630  return Reg.RegNum == Other.Reg.RegNum;
631  }
632  }
633 };
634 } // end anonymous namespace.
635 
636 #define GET_REGISTER_MATCHER
637 #define GET_SUBTARGET_FEATURE_NAME
638 #define GET_MATCHER_IMPLEMENTATION
639 #define GET_MNEMONIC_SPELL_CHECKER
640 #include "CSKYGenAsmMatcher.inc"
641 
643  assert(Reg >= CSKY::F0_32 && Reg <= CSKY::F31_32 && "Invalid register");
644  return Reg - CSKY::F0_32 + CSKY::F0_64;
645 }
646 
647 static std::string CSKYMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
648  unsigned VariantID = 0);
649 
650 bool CSKYAsmParser::generateImmOutOfRangeError(
651  OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper,
652  Twine Msg = "immediate must be an integer in the range") {
653  SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
654  return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]");
655 }
656 
657 bool CSKYAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
659  MCStreamer &Out,
661  bool MatchingInlineAsm) {
662  MCInst Inst;
663  FeatureBitset MissingFeatures;
664 
665  auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
666  MatchingInlineAsm);
667  switch (Result) {
668  default:
669  break;
670  case Match_Success:
671  return processInstruction(Inst, IDLoc, Operands, Out);
672  case Match_MissingFeature: {
673  assert(MissingFeatures.any() && "Unknown missing features!");
674  ListSeparator LS;
675  std::string Msg = "instruction requires the following: ";
676  for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) {
677  if (MissingFeatures[i]) {
678  Msg += LS;
680  }
681  }
682  return Error(IDLoc, Msg);
683  }
684  case Match_MnemonicFail: {
685  FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
686  std::string Suggestion =
687  CSKYMnemonicSpellCheck(((CSKYOperand &)*Operands[0]).getToken(), FBS);
688  return Error(IDLoc, "unrecognized instruction mnemonic" + Suggestion);
689  }
690  case Match_InvalidTiedOperand:
691  case Match_InvalidOperand: {
692  SMLoc ErrorLoc = IDLoc;
693  if (ErrorInfo != ~0U) {
694  if (ErrorInfo >= Operands.size())
695  return Error(ErrorLoc, "too few operands for instruction");
696 
697  ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
698  if (ErrorLoc == SMLoc())
699  ErrorLoc = IDLoc;
700  }
701  return Error(ErrorLoc, "invalid operand for instruction");
702  }
703  }
704 
705  // Handle the case when the error message is of specific type
706  // other than the generic Match_InvalidOperand, and the
707  // corresponding operand is missing.
708  if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
709  SMLoc ErrorLoc = IDLoc;
710  if (ErrorInfo != ~0U && ErrorInfo >= Operands.size())
711  return Error(ErrorLoc, "too few operands for instruction");
712  }
713 
714  switch (Result) {
715  default:
716  break;
717  case Match_InvalidSImm8:
718  return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 7),
719  (1 << 7) - 1);
720  case Match_InvalidOImm3:
721  return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 3));
722  case Match_InvalidOImm4:
723  return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 4));
724  case Match_InvalidOImm5:
725  return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5));
726  case Match_InvalidOImm6:
727  return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6));
728  case Match_InvalidOImm8:
729  return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 8));
730  case Match_InvalidOImm12:
731  return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 12));
732  case Match_InvalidOImm16:
733  return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 16));
734  case Match_InvalidUImm1:
735  return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 1) - 1);
736  case Match_InvalidUImm2:
737  return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1);
738  case Match_InvalidUImm3:
739  return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1);
740  case Match_InvalidUImm4:
741  return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);
742  case Match_InvalidUImm5:
743  return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
744  case Match_InvalidUImm6:
745  return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
746  case Match_InvalidUImm7:
747  return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1);
748  case Match_InvalidUImm8:
749  return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 8) - 1);
750  case Match_InvalidUImm12:
751  return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1);
752  case Match_InvalidUImm16:
753  return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 16) - 1);
754  case Match_InvalidUImm5Shift1:
755  return generateImmOutOfRangeError(
756  Operands, ErrorInfo, 0, (1 << 5) - 2,
757  "immediate must be a multiple of 2 bytes in the range");
758  case Match_InvalidUImm12Shift1:
759  return generateImmOutOfRangeError(
760  Operands, ErrorInfo, 0, (1 << 12) - 2,
761  "immediate must be a multiple of 2 bytes in the range");
762  case Match_InvalidUImm5Shift2:
763  return generateImmOutOfRangeError(
764  Operands, ErrorInfo, 0, (1 << 5) - 4,
765  "immediate must be a multiple of 4 bytes in the range");
766  case Match_InvalidUImm7Shift1:
767  return generateImmOutOfRangeError(
768  Operands, ErrorInfo, 0, (1 << 7) - 2,
769  "immediate must be a multiple of 2 bytes in the range");
770  case Match_InvalidUImm7Shift2:
771  return generateImmOutOfRangeError(
772  Operands, ErrorInfo, 0, (1 << 7) - 4,
773  "immediate must be a multiple of 4 bytes in the range");
774  case Match_InvalidUImm8Shift2:
775  return generateImmOutOfRangeError(
776  Operands, ErrorInfo, 0, (1 << 8) - 4,
777  "immediate must be a multiple of 4 bytes in the range");
778  case Match_InvalidUImm8Shift3:
779  return generateImmOutOfRangeError(
780  Operands, ErrorInfo, 0, (1 << 8) - 8,
781  "immediate must be a multiple of 8 bytes in the range");
782  case Match_InvalidUImm8Shift8:
783  return generateImmOutOfRangeError(
784  Operands, ErrorInfo, 0, (1 << 8) - 256,
785  "immediate must be a multiple of 256 bytes in the range");
786  case Match_InvalidUImm12Shift2:
787  return generateImmOutOfRangeError(
788  Operands, ErrorInfo, 0, (1 << 12) - 4,
789  "immediate must be a multiple of 4 bytes in the range");
790  case Match_InvalidCSKYSymbol: {
791  SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
792  return Error(ErrorLoc, "operand must be a symbol name");
793  }
794  case Match_InvalidConstpool: {
795  SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
796  return Error(ErrorLoc, "operand must be a constpool symbol name");
797  }
798  case Match_InvalidPSRFlag: {
799  SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
800  return Error(ErrorLoc, "psrset operand is not valid");
801  }
802  case Match_InvalidRegSeq: {
803  SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
804  return Error(ErrorLoc, "Register sequence is not valid");
805  }
806  case Match_InvalidRegOutOfRange: {
807  SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
808  return Error(ErrorLoc, "register is out of range");
809  }
810  case Match_RequiresSameSrcAndDst: {
811  SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
812  return Error(ErrorLoc, "src and dst operand must be same");
813  }
814  case Match_InvalidRegList: {
815  SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
816  return Error(ErrorLoc, "invalid register list");
817  }
818  }
819  LLVM_DEBUG(dbgs() << "Result = " << Result);
820  llvm_unreachable("Unknown match type detected!");
821 }
822 
823 bool CSKYAsmParser::processLRW(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {
824  Inst.setLoc(IDLoc);
825 
826  unsigned Opcode;
827  MCOperand Op;
828  if (Inst.getOpcode() == CSKY::PseudoLRW16)
829  Opcode = CSKY::LRW16;
830  else
831  Opcode = CSKY::LRW32;
832 
833  if (Inst.getOperand(1).isImm()) {
834  if (isUInt<8>(Inst.getOperand(1).getImm()) &&
835  Inst.getOperand(0).getReg() <= CSKY::R7) {
836  Opcode = CSKY::MOVI16;
837  } else if (getSTI().getFeatureBits()[CSKY::HasE2] &&
838  isUInt<16>(Inst.getOperand(1).getImm())) {
839  Opcode = CSKY::MOVI32;
840  } else {
841  auto *Expr = getTargetStreamer().addConstantPoolEntry(
842  MCConstantExpr::create(Inst.getOperand(1).getImm(), getContext()),
843  Inst.getLoc());
844  Inst.erase(std::prev(Inst.end()));
845  Inst.addOperand(MCOperand::createExpr(Expr));
846  }
847  } else {
848  const MCExpr *AdjustExpr = nullptr;
849  if (const CSKYMCExpr *CSKYExpr =
850  dyn_cast<CSKYMCExpr>(Inst.getOperand(1).getExpr())) {
851  if (CSKYExpr->getKind() == CSKYMCExpr::VK_CSKY_TLSGD ||
852  CSKYExpr->getKind() == CSKYMCExpr::VK_CSKY_TLSIE ||
853  CSKYExpr->getKind() == CSKYMCExpr::VK_CSKY_TLSLDM) {
854  MCSymbol *Dot = getContext().createNamedTempSymbol();
855  Out.emitLabel(Dot);
856  AdjustExpr = MCSymbolRefExpr::create(Dot, getContext());
857  }
858  }
859  auto *Expr = getTargetStreamer().addConstantPoolEntry(
860  Inst.getOperand(1).getExpr(), Inst.getLoc(), AdjustExpr);
861  Inst.erase(std::prev(Inst.end()));
862  Inst.addOperand(MCOperand::createExpr(Expr));
863  }
864 
865  Inst.setOpcode(Opcode);
866 
867  Out.emitInstruction(Inst, getSTI());
868  return false;
869 }
870 
871 bool CSKYAsmParser::processJSRI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {
872  Inst.setLoc(IDLoc);
873 
874  if (Inst.getOperand(0).isImm()) {
875  const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
876  MCConstantExpr::create(Inst.getOperand(0).getImm(), getContext()),
877  Inst.getLoc());
878  Inst.setOpcode(CSKY::JSRI32);
879  Inst.erase(std::prev(Inst.end()));
880  Inst.addOperand(MCOperand::createExpr(Expr));
881  } else {
882  const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
883  Inst.getOperand(0).getExpr(), Inst.getLoc());
884  Inst.setOpcode(CSKY::JBSR32);
885  Inst.addOperand(MCOperand::createExpr(Expr));
886  }
887 
888  Out.emitInstruction(Inst, getSTI());
889  return false;
890 }
891 
892 bool CSKYAsmParser::processJMPI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {
893  Inst.setLoc(IDLoc);
894 
895  if (Inst.getOperand(0).isImm()) {
896  const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
897  MCConstantExpr::create(Inst.getOperand(0).getImm(), getContext()),
898  Inst.getLoc());
899  Inst.setOpcode(CSKY::JMPI32);
900  Inst.erase(std::prev(Inst.end()));
901  Inst.addOperand(MCOperand::createExpr(Expr));
902  } else {
903  const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
904  Inst.getOperand(0).getExpr(), Inst.getLoc());
905  Inst.setOpcode(CSKY::JBR32);
906  Inst.addOperand(MCOperand::createExpr(Expr));
907  }
908 
909  Out.emitInstruction(Inst, getSTI());
910  return false;
911 }
912 
913 bool CSKYAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
915  MCStreamer &Out) {
916 
917  switch (Inst.getOpcode()) {
918  default:
919  break;
920  case CSKY::LDQ32:
921  case CSKY::STQ32:
922  if (Inst.getOperand(1).getReg() != CSKY::R4 ||
923  Inst.getOperand(2).getReg() != CSKY::R7) {
924  return Error(IDLoc, "Register sequence is not valid. 'r4-r7' expected");
925  }
926  Inst.setOpcode(Inst.getOpcode() == CSKY::LDQ32 ? CSKY::LDM32 : CSKY::STM32);
927  break;
928  case CSKY::SEXT32:
929  case CSKY::ZEXT32:
930  if (Inst.getOperand(2).getImm() < Inst.getOperand(3).getImm())
931  return Error(IDLoc, "msb must be greater or equal to lsb");
932  break;
933  case CSKY::INS32:
934  if (Inst.getOperand(3).getImm() < Inst.getOperand(4).getImm())
935  return Error(IDLoc, "msb must be greater or equal to lsb");
936  break;
937  case CSKY::IDLY32:
938  if (Inst.getOperand(0).getImm() > 32 || Inst.getOperand(0).getImm() < 0)
939  return Error(IDLoc, "n must be in range [0,32]");
940  break;
941  case CSKY::ADDC32:
942  case CSKY::SUBC32:
943  case CSKY::ADDC16:
944  case CSKY::SUBC16:
945  Inst.erase(std::next(Inst.begin()));
946  Inst.erase(std::prev(Inst.end()));
947  Inst.insert(std::next(Inst.begin()), MCOperand::createReg(CSKY::C));
948  Inst.insert(Inst.end(), MCOperand::createReg(CSKY::C));
949  break;
950  case CSKY::CMPNEI32:
951  case CSKY::CMPNEI16:
952  case CSKY::CMPNE32:
953  case CSKY::CMPNE16:
954  case CSKY::CMPHSI32:
955  case CSKY::CMPHSI16:
956  case CSKY::CMPHS32:
957  case CSKY::CMPHS16:
958  case CSKY::CMPLTI32:
959  case CSKY::CMPLTI16:
960  case CSKY::CMPLT32:
961  case CSKY::CMPLT16:
962  case CSKY::BTSTI32:
963  Inst.erase(Inst.begin());
964  Inst.insert(Inst.begin(), MCOperand::createReg(CSKY::C));
965  break;
966  case CSKY::MVCV32:
967  Inst.erase(std::next(Inst.begin()));
968  Inst.insert(Inst.end(), MCOperand::createReg(CSKY::C));
969  break;
970  case CSKY::PseudoLRW16:
971  case CSKY::PseudoLRW32:
972  return processLRW(Inst, IDLoc, Out);
973  case CSKY::PseudoJSRI32:
974  return processJSRI(Inst, IDLoc, Out);
975  case CSKY::PseudoJMPI32:
976  return processJMPI(Inst, IDLoc, Out);
977  case CSKY::JBSR32:
978  case CSKY::JBR16:
979  case CSKY::JBT16:
980  case CSKY::JBF16:
981  case CSKY::JBR32:
982  case CSKY::JBT32:
983  case CSKY::JBF32:
984  unsigned Num = Inst.getNumOperands() - 1;
985  assert(Inst.getOperand(Num).isExpr());
986 
987  const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
988  Inst.getOperand(Num).getExpr(), Inst.getLoc());
989 
990  Inst.addOperand(MCOperand::createExpr(Expr));
991  break;
992  }
993 
994  emitToStreamer(Out, Inst);
995  return false;
996 }
997 
998 // Attempts to match Name as a register (either using the default name or
999 // alternative ABI names), setting RegNo to the matching register. Upon
1000 // failure, returns true and sets RegNo to 0.
1002  MCRegister &RegNo, StringRef Name) {
1003  RegNo = MatchRegisterName(Name);
1004 
1005  if (RegNo == CSKY::NoRegister)
1006  RegNo = MatchRegisterAltName(Name);
1007 
1008  return RegNo == CSKY::NoRegister;
1009 }
1010 
1011 bool CSKYAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1012  SMLoc &EndLoc) {
1013  const AsmToken &Tok = getParser().getTok();
1014  StartLoc = Tok.getLoc();
1015  EndLoc = Tok.getEndLoc();
1016  StringRef Name = getLexer().getTok().getIdentifier();
1017 
1018  if (!matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name)) {
1019  getParser().Lex(); // Eat identifier token.
1020  return false;
1021  }
1022 
1023  return MatchOperand_NoMatch;
1024 }
1025 
1026 OperandMatchResultTy CSKYAsmParser::parseRegister(OperandVector &Operands) {
1027  SMLoc S = getLoc();
1028  SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1029 
1030  switch (getLexer().getKind()) {
1031  default:
1032  return MatchOperand_NoMatch;
1033  case AsmToken::Identifier: {
1034  StringRef Name = getLexer().getTok().getIdentifier();
1035  MCRegister RegNo;
1036 
1037  if (matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name))
1038  return MatchOperand_NoMatch;
1039 
1040  getLexer().Lex();
1041  Operands.push_back(CSKYOperand::createReg(RegNo, S, E));
1042 
1043  return MatchOperand_Success;
1044  }
1045  }
1046 }
1047 
1048 OperandMatchResultTy CSKYAsmParser::parseBaseRegImm(OperandVector &Operands) {
1049  assert(getLexer().is(AsmToken::LParen));
1050 
1051  Operands.push_back(CSKYOperand::createToken("(", getLoc()));
1052 
1053  auto Tok = getParser().Lex(); // Eat '('
1054 
1055  if (parseRegister(Operands) != MatchOperand_Success) {
1056  getLexer().UnLex(Tok);
1057  Operands.pop_back();
1058  return MatchOperand_NoMatch;
1059  }
1060 
1061  if (getLexer().is(AsmToken::RParen)) {
1062  Operands.push_back(CSKYOperand::createToken(")", getLoc()));
1063  getParser().Lex(); // Eat ')'
1064  return MatchOperand_Success;
1065  }
1066 
1067  if (getLexer().isNot(AsmToken::Comma)) {
1068  Error(getLoc(), "expected ','");
1069  return MatchOperand_ParseFail;
1070  }
1071 
1072  getParser().Lex(); // Eat ','
1073 
1074  if (parseRegister(Operands) == MatchOperand_Success) {
1075  if (getLexer().isNot(AsmToken::LessLess)) {
1076  Error(getLoc(), "expected '<<'");
1077  return MatchOperand_ParseFail;
1078  }
1079 
1080  Operands.push_back(CSKYOperand::createToken("<<", getLoc()));
1081 
1082  getParser().Lex(); // Eat '<<'
1083 
1085  Error(getLoc(), "expected imm");
1086  return MatchOperand_ParseFail;
1087  }
1088 
1089  } else if (parseImmediate(Operands) != MatchOperand_Success) {
1090  Error(getLoc(), "expected imm");
1091  return MatchOperand_ParseFail;
1092  }
1093 
1094  if (getLexer().isNot(AsmToken::RParen)) {
1095  Error(getLoc(), "expected ')'");
1096  return MatchOperand_ParseFail;
1097  }
1098 
1099  Operands.push_back(CSKYOperand::createToken(")", getLoc()));
1100 
1101  getParser().Lex(); // Eat ')'
1102 
1103  return MatchOperand_Success;
1104 }
1105 
1107  switch (getLexer().getKind()) {
1108  default:
1109  return MatchOperand_NoMatch;
1110  case AsmToken::LParen:
1111  case AsmToken::Minus:
1112  case AsmToken::Plus:
1113  case AsmToken::Integer:
1114  case AsmToken::String:
1115  break;
1116  }
1117 
1118  const MCExpr *IdVal;
1119  SMLoc S = getLoc();
1120  if (getParser().parseExpression(IdVal)) {
1121  Error(getLoc(), "unknown expression");
1122  return MatchOperand_ParseFail;
1123  }
1124 
1125  SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1126  Operands.push_back(CSKYOperand::createImm(IdVal, S, E));
1127  return MatchOperand_Success;
1128 }
1129 
1130 /// Looks at a token type and creates the relevant operand from this
1131 /// information, adding to Operands. If operand was parsed, returns false, else
1132 /// true.
1133 bool CSKYAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
1134  // Check if the current operand has a custom associated parser, if so, try to
1135  // custom parse the operand, or fallback to the general approach.
1137  MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true);
1138  if (Result == MatchOperand_Success)
1139  return false;
1140  if (Result == MatchOperand_ParseFail)
1141  return true;
1142 
1143  // Attempt to parse token as register
1144  auto Res = parseRegister(Operands);
1145  if (Res == MatchOperand_Success)
1146  return false;
1147  else if (Res == MatchOperand_ParseFail)
1148  return true;
1149 
1150  // Attempt to parse token as (register, imm)
1151  if (getLexer().is(AsmToken::LParen)) {
1152  Res = parseBaseRegImm(Operands);
1153  if (Res == MatchOperand_Success)
1154  return false;
1155  else if (Res == MatchOperand_ParseFail)
1156  return true;
1157  }
1158 
1159  Res = parseImmediate(Operands);
1160  if (Res == MatchOperand_Success)
1161  return false;
1162  else if (Res == MatchOperand_ParseFail)
1163  return true;
1164 
1165  // Finally we have exhausted all options and must declare defeat.
1166  Error(getLoc(), "unknown operand");
1167  return true;
1168 }
1169 
1170 OperandMatchResultTy CSKYAsmParser::parseCSKYSymbol(OperandVector &Operands) {
1171  SMLoc S = getLoc();
1172  SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1173  const MCExpr *Res;
1174 
1175  if (getLexer().getKind() != AsmToken::Identifier)
1176  return MatchOperand_NoMatch;
1177 
1179  AsmToken Tok = getLexer().getTok();
1180 
1181  if (getParser().parseIdentifier(Identifier)) {
1182  Error(getLoc(), "unknown identifier");
1183  return MatchOperand_ParseFail;
1184  }
1185 
1187  if (Identifier.consume_back("@GOT"))
1189  else if (Identifier.consume_back("@GOTOFF"))
1191  else if (Identifier.consume_back("@PLT"))
1193  else if (Identifier.consume_back("@GOTPC"))
1195  else if (Identifier.consume_back("@TLSGD32"))
1197  else if (Identifier.consume_back("@GOTTPOFF"))
1199  else if (Identifier.consume_back("@TPOFF"))
1201  else if (Identifier.consume_back("@TLSLDM32"))
1203  else if (Identifier.consume_back("@TLSLDO32"))
1205 
1206  MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier);
1207 
1208  if (!Sym)
1209  Sym = getContext().getOrCreateSymbol(Identifier);
1210 
1211  if (Sym->isVariable()) {
1212  const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false);
1213  if (!isa<MCSymbolRefExpr>(V)) {
1214  getLexer().UnLex(Tok); // Put back if it's not a bare symbol.
1215  Error(getLoc(), "unknown symbol");
1216  return MatchOperand_ParseFail;
1217  }
1218  Res = V;
1219  } else
1220  Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1221 
1222  MCBinaryExpr::Opcode Opcode;
1223  switch (getLexer().getKind()) {
1224  default:
1226  Res = CSKYMCExpr::create(Res, Kind, getContext());
1227 
1228  Operands.push_back(CSKYOperand::createImm(Res, S, E));
1229  return MatchOperand_Success;
1230  case AsmToken::Plus:
1231  Opcode = MCBinaryExpr::Add;
1232  break;
1233  case AsmToken::Minus:
1234  Opcode = MCBinaryExpr::Sub;
1235  break;
1236  }
1237 
1238  getLexer().Lex(); // eat + or -
1239 
1240  const MCExpr *Expr;
1241  if (getParser().parseExpression(Expr)) {
1242  Error(getLoc(), "unknown expression");
1243  return MatchOperand_ParseFail;
1244  }
1245  Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext());
1246  Operands.push_back(CSKYOperand::createImm(Res, S, E));
1247  return MatchOperand_Success;
1248 }
1249 
1250 OperandMatchResultTy CSKYAsmParser::parseDataSymbol(OperandVector &Operands) {
1251  SMLoc S = getLoc();
1252  SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1253  const MCExpr *Res;
1254 
1255  if (getLexer().getKind() != AsmToken::LBrac)
1256  return MatchOperand_NoMatch;
1257 
1258  getLexer().Lex(); // Eat '['.
1259 
1260  if (getLexer().getKind() != AsmToken::Identifier) {
1261  const MCExpr *Expr;
1262  if (getParser().parseExpression(Expr)) {
1263  Error(getLoc(), "unknown expression");
1264  return MatchOperand_ParseFail;
1265  }
1266 
1267  if (getLexer().getKind() != AsmToken::RBrac) {
1268  Error(getLoc(), "expected ]");
1269  return MatchOperand_ParseFail;
1270  }
1271 
1272  getLexer().Lex(); // Eat ']'.
1273 
1274  Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E));
1275  return MatchOperand_Success;
1276  }
1277 
1278  AsmToken Tok = getLexer().getTok();
1280 
1281  if (getParser().parseIdentifier(Identifier)) {
1282  Error(getLoc(), "unknown identifier " + Identifier);
1283  return MatchOperand_ParseFail;
1284  }
1285 
1287  if (Identifier.consume_back("@GOT"))
1289  else if (Identifier.consume_back("@PLT"))
1291 
1292  MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier);
1293 
1294  if (!Sym)
1295  Sym = getContext().getOrCreateSymbol(Identifier);
1296 
1297  if (Sym->isVariable()) {
1298  const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false);
1299  if (!isa<MCSymbolRefExpr>(V)) {
1300  getLexer().UnLex(Tok); // Put back if it's not a bare symbol.
1301  Error(getLoc(), "unknown symbol");
1302  return MatchOperand_ParseFail;
1303  }
1304  Res = V;
1305  } else {
1306  Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1307  }
1308 
1309  MCBinaryExpr::Opcode Opcode;
1310  switch (getLexer().getKind()) {
1311  default:
1312  Error(getLoc(), "unknown symbol");
1313  return MatchOperand_ParseFail;
1314  case AsmToken::RBrac:
1315 
1316  getLexer().Lex(); // Eat ']'.
1317 
1319  Res = CSKYMCExpr::create(Res, Kind, getContext());
1320 
1321  Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));
1322  return MatchOperand_Success;
1323  case AsmToken::Plus:
1324  Opcode = MCBinaryExpr::Add;
1325  break;
1326  case AsmToken::Minus:
1327  Opcode = MCBinaryExpr::Sub;
1328  break;
1329  }
1330 
1331  getLexer().Lex(); // eat + or -
1332 
1333  const MCExpr *Expr;
1334  if (getParser().parseExpression(Expr)) {
1335  Error(getLoc(), "unknown expression");
1336  return MatchOperand_ParseFail;
1337  }
1338 
1339  if (getLexer().getKind() != AsmToken::RBrac) {
1340  Error(getLoc(), "expected ']'");
1341  return MatchOperand_ParseFail;
1342  }
1343 
1344  getLexer().Lex(); // Eat ']'.
1345 
1346  Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext());
1347  Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));
1348  return MatchOperand_Success;
1349 }
1350 
1352 CSKYAsmParser::parseConstpoolSymbol(OperandVector &Operands) {
1353  SMLoc S = getLoc();
1354  SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1355  const MCExpr *Res;
1356 
1357  if (getLexer().getKind() != AsmToken::LBrac)
1358  return MatchOperand_NoMatch;
1359 
1360  getLexer().Lex(); // Eat '['.
1361 
1362  if (getLexer().getKind() != AsmToken::Identifier) {
1363  const MCExpr *Expr;
1364  if (getParser().parseExpression(Expr)) {
1365  Error(getLoc(), "unknown expression");
1366  return MatchOperand_ParseFail;
1367  }
1368 
1369  if (getLexer().getKind() != AsmToken::RBrac) {
1370  Error(getLoc(), "expected ']'");
1371  return MatchOperand_ParseFail;
1372  }
1373 
1374  getLexer().Lex(); // Eat ']'.
1375 
1376  Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E));
1377  return MatchOperand_Success;
1378  }
1379 
1380  AsmToken Tok = getLexer().getTok();
1382 
1383  if (getParser().parseIdentifier(Identifier)) {
1384  Error(getLoc(), "unknown identifier");
1385  return MatchOperand_ParseFail;
1386  }
1387 
1388  MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier);
1389 
1390  if (!Sym)
1391  Sym = getContext().getOrCreateSymbol(Identifier);
1392 
1393  if (Sym->isVariable()) {
1394  const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false);
1395  if (!isa<MCSymbolRefExpr>(V)) {
1396  getLexer().UnLex(Tok); // Put back if it's not a bare symbol.
1397  Error(getLoc(), "unknown symbol");
1398  return MatchOperand_ParseFail;
1399  }
1400  Res = V;
1401  } else {
1402  Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1403  }
1404 
1405  MCBinaryExpr::Opcode Opcode;
1406  switch (getLexer().getKind()) {
1407  default:
1408  Error(getLoc(), "unknown symbol");
1409  return MatchOperand_ParseFail;
1410  case AsmToken::RBrac:
1411 
1412  getLexer().Lex(); // Eat ']'.
1413 
1414  Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));
1415  return MatchOperand_Success;
1416  case AsmToken::Plus:
1417  Opcode = MCBinaryExpr::Add;
1418  break;
1419  case AsmToken::Minus:
1420  Opcode = MCBinaryExpr::Sub;
1421  break;
1422  }
1423 
1424  getLexer().Lex(); // eat + or -
1425 
1426  const MCExpr *Expr;
1427  if (getParser().parseExpression(Expr)) {
1428  Error(getLoc(), "unknown expression");
1429  return MatchOperand_ParseFail;
1430  }
1431 
1432  if (getLexer().getKind() != AsmToken::RBrac) {
1433  Error(getLoc(), "expected ']'");
1434  return MatchOperand_ParseFail;
1435  }
1436 
1437  getLexer().Lex(); // Eat ']'.
1438 
1439  Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext());
1440  Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));
1441  return MatchOperand_Success;
1442 }
1443 
1444 OperandMatchResultTy CSKYAsmParser::parsePSRFlag(OperandVector &Operands) {
1445  SMLoc S = getLoc();
1446  SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1447 
1448  unsigned Flag = 0;
1449 
1450  while (getLexer().isNot(AsmToken::EndOfStatement)) {
1452  if (getParser().parseIdentifier(Identifier)) {
1453  Error(getLoc(), "unknown identifier " + Identifier);
1454  return MatchOperand_ParseFail;
1455  }
1456 
1457  if (Identifier == "sie")
1458  Flag = (1 << 4) | Flag;
1459  else if (Identifier == "ee")
1460  Flag = (1 << 3) | Flag;
1461  else if (Identifier == "ie")
1462  Flag = (1 << 2) | Flag;
1463  else if (Identifier == "fe")
1464  Flag = (1 << 1) | Flag;
1465  else if (Identifier == "af")
1466  Flag = (1 << 0) | Flag;
1467  else {
1468  Error(getLoc(), "expected " + Identifier);
1469  return MatchOperand_ParseFail;
1470  }
1471 
1472  if (getLexer().is(AsmToken::EndOfStatement))
1473  break;
1474 
1475  if (getLexer().is(AsmToken::Comma)) {
1476  getLexer().Lex(); // eat ','
1477  } else {
1478  Error(getLoc(), "expected ,");
1479  return MatchOperand_ParseFail;
1480  }
1481  }
1482 
1483  Operands.push_back(
1484  CSKYOperand::createImm(MCConstantExpr::create(Flag, getContext()), S, E));
1485  return MatchOperand_Success;
1486 }
1487 
1488 OperandMatchResultTy CSKYAsmParser::parseRegSeq(OperandVector &Operands) {
1489  SMLoc S = getLoc();
1490 
1491  if (parseRegister(Operands) != MatchOperand_Success)
1492  return MatchOperand_NoMatch;
1493 
1494  auto Ry = Operands.back()->getReg();
1495  Operands.pop_back();
1496 
1497  if (getLexer().isNot(AsmToken::Minus)) {
1498  Error(getLoc(), "expected '-'");
1499  return MatchOperand_ParseFail;
1500  }
1501 
1502  getLexer().Lex(); // eat '-'
1503 
1504  if (parseRegister(Operands) != MatchOperand_Success) {
1505  Error(getLoc(), "invalid register");
1506  return MatchOperand_ParseFail;
1507  }
1508 
1509  auto Rz = Operands.back()->getReg();
1510  Operands.pop_back();
1511 
1512  Operands.push_back(CSKYOperand::createRegSeq(Ry, Rz, S));
1513  return MatchOperand_Success;
1514 }
1515 
1516 OperandMatchResultTy CSKYAsmParser::parseRegList(OperandVector &Operands) {
1517  SMLoc S = getLoc();
1518 
1519  SmallVector<unsigned, 4> reglist;
1520 
1521  while (true) {
1522 
1523  if (parseRegister(Operands) != MatchOperand_Success) {
1524  Error(getLoc(), "invalid register");
1525  return MatchOperand_ParseFail;
1526  }
1527 
1528  auto Ry = Operands.back()->getReg();
1529  Operands.pop_back();
1530 
1531  if (getLexer().is(AsmToken::Minus)) {
1532  getLexer().Lex(); // eat '-'
1533 
1534  if (parseRegister(Operands) != MatchOperand_Success) {
1535  Error(getLoc(), "invalid register");
1536  return MatchOperand_ParseFail;
1537  }
1538 
1539  auto Rz = Operands.back()->getReg();
1540  Operands.pop_back();
1541 
1542  reglist.push_back(Ry);
1543  reglist.push_back(Rz);
1544 
1545  if (getLexer().is(AsmToken::Comma))
1546  getLexer().Lex(); // eat ','
1547  else if (getLexer().is(AsmToken::EndOfStatement))
1548  break;
1549 
1550  } else if (getLexer().is(AsmToken::Comma)) {
1551  reglist.push_back(Ry);
1552  reglist.push_back(Ry);
1553 
1554  getLexer().Lex(); // eat ','
1555  } else if (getLexer().is(AsmToken::EndOfStatement)) {
1556  reglist.push_back(Ry);
1557  reglist.push_back(Ry);
1558  break;
1559  } else {
1560  Error(getLoc(), "invalid register list");
1561  return MatchOperand_ParseFail;
1562  }
1563  }
1564 
1565  Operands.push_back(CSKYOperand::createRegList(reglist, S));
1566  return MatchOperand_Success;
1567 }
1568 
1569 bool CSKYAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
1570  SMLoc NameLoc, OperandVector &Operands) {
1571  // First operand is token for instruction.
1572  Operands.push_back(CSKYOperand::createToken(Name, NameLoc));
1573 
1574  // If there are no more operands, then finish.
1575  if (getLexer().is(AsmToken::EndOfStatement))
1576  return false;
1577 
1578  // Parse first operand.
1579  if (parseOperand(Operands, Name))
1580  return true;
1581 
1582  // Parse until end of statement, consuming commas between operands.
1583  while (getLexer().is(AsmToken::Comma)) {
1584  // Consume comma token.
1585  getLexer().Lex();
1586 
1587  // Parse next operand.
1588  if (parseOperand(Operands, Name))
1589  return true;
1590  }
1591 
1592  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1593  SMLoc Loc = getLexer().getLoc();
1594  getParser().eatToEndOfStatement();
1595  return Error(Loc, "unexpected token");
1596  }
1597 
1598  getParser().Lex(); // Consume the EndOfStatement.
1599  return false;
1600 }
1601 
1602 OperandMatchResultTy CSKYAsmParser::tryParseRegister(unsigned &RegNo,
1603  SMLoc &StartLoc,
1604  SMLoc &EndLoc) {
1605  const AsmToken &Tok = getParser().getTok();
1606  StartLoc = Tok.getLoc();
1607  EndLoc = Tok.getEndLoc();
1608 
1609  StringRef Name = getLexer().getTok().getIdentifier();
1610 
1611  if (matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name))
1612  return MatchOperand_NoMatch;
1613 
1614  getParser().Lex(); // Eat identifier token.
1615  return MatchOperand_Success;
1616 }
1617 
1618 bool CSKYAsmParser::ParseDirective(AsmToken DirectiveID) {
1619  // This returns false if this function recognizes the directive
1620  // regardless of whether it is successfully handles or reports an
1621  // error. Otherwise it returns true to give the generic parser a
1622  // chance at recognizing it.
1623  StringRef IDVal = DirectiveID.getString();
1624 
1625  if (IDVal == ".csky_attribute")
1626  return parseDirectiveAttribute();
1627 
1628  return true;
1629 }
1630 
1631 /// parseDirectiveAttribute
1632 /// ::= .attribute expression ',' ( expression | "string" )
1633 bool CSKYAsmParser::parseDirectiveAttribute() {
1634  MCAsmParser &Parser = getParser();
1635  int64_t Tag;
1636  SMLoc TagLoc;
1637  TagLoc = Parser.getTok().getLoc();
1638  if (Parser.getTok().is(AsmToken::Identifier)) {
1639  StringRef Name = Parser.getTok().getIdentifier();
1642  if (!Ret.hasValue()) {
1643  Error(TagLoc, "attribute name not recognised: " + Name);
1644  return false;
1645  }
1646  Tag = Ret.getValue();
1647  Parser.Lex();
1648  } else {
1649  const MCExpr *AttrExpr;
1650 
1651  TagLoc = Parser.getTok().getLoc();
1652  if (Parser.parseExpression(AttrExpr))
1653  return true;
1654 
1655  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr);
1656  if (check(!CE, TagLoc, "expected numeric constant"))
1657  return true;
1658 
1659  Tag = CE->getValue();
1660  }
1661 
1662  if (Parser.parseToken(AsmToken::Comma, "comma expected"))
1663  return true;
1664 
1665  StringRef StringValue;
1666  int64_t IntegerValue = 0;
1667  bool IsIntegerValue = ((Tag != CSKYAttrs::CSKY_ARCH_NAME) &&
1670 
1671  SMLoc ValueExprLoc = Parser.getTok().getLoc();
1672  if (IsIntegerValue) {
1673  const MCExpr *ValueExpr;
1674  if (Parser.parseExpression(ValueExpr))
1675  return true;
1676 
1677  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr);
1678  if (!CE)
1679  return Error(ValueExprLoc, "expected numeric constant");
1680  IntegerValue = CE->getValue();
1681  } else {
1682  if (Parser.getTok().isNot(AsmToken::String))
1683  return Error(Parser.getTok().getLoc(), "expected string constant");
1684 
1685  StringValue = Parser.getTok().getStringContents();
1686  Parser.Lex();
1687  }
1688 
1689  if (Parser.parseEOL())
1690  return true;
1691 
1692  if (IsIntegerValue)
1693  getTargetStreamer().emitAttribute(Tag, IntegerValue);
1695  getTargetStreamer().emitTextAttribute(Tag, StringValue);
1696  else {
1698  ? CSKY::parseArch(StringValue)
1699  : CSKY::parseCPUArch(StringValue);
1700  if (ID == CSKY::ArchKind::INVALID)
1701  return Error(ValueExprLoc, (Tag == CSKYAttrs::CSKY_ARCH_NAME)
1702  ? "unknown arch name"
1703  : "unknown cpu name");
1704 
1705  getTargetStreamer().emitTextAttribute(Tag, StringValue);
1706  }
1707 
1708  return false;
1709 }
1710 
1711 unsigned CSKYAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
1712  unsigned Kind) {
1713  CSKYOperand &Op = static_cast<CSKYOperand &>(AsmOp);
1714 
1715  if (!Op.isReg())
1716  return Match_InvalidOperand;
1717 
1718  MCRegister Reg = Op.getReg();
1719 
1720  if (CSKYMCRegisterClasses[CSKY::FPR32RegClassID].contains(Reg)) {
1721  // As the parser couldn't differentiate an FPR64 from an FPR32, coerce the
1722  // register from FPR32 to FPR64 if necessary.
1723  if (Kind == MCK_FPR64 || Kind == MCK_sFPR64) {
1724  Op.Reg.RegNum = convertFPR32ToFPR64(Reg);
1725  if (Kind == MCK_sFPR64 &&
1726  (Op.Reg.RegNum < CSKY::F0_64 || Op.Reg.RegNum > CSKY::F15_64))
1727  return Match_InvalidRegOutOfRange;
1728  if (Kind == MCK_FPR64 &&
1729  (Op.Reg.RegNum < CSKY::F0_64 || Op.Reg.RegNum > CSKY::F31_64))
1730  return Match_InvalidRegOutOfRange;
1731  return Match_Success;
1732  }
1733  }
1734 
1735  if (CSKYMCRegisterClasses[CSKY::GPRRegClassID].contains(Reg)) {
1736  if (Kind == MCK_GPRPair) {
1737  Op.Reg.RegNum = MRI->getEncodingValue(Reg) + CSKY::R0_R1;
1738  return Match_Success;
1739  }
1740  }
1741 
1742  return Match_InvalidOperand;
1743 }
1744 
1745 void CSKYAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) {
1746  MCInst CInst;
1747  bool Res = false;
1749  Res = compressInst(CInst, Inst, getSTI(), S.getContext());
1750  if (Res)
1751  ++CSKYNumInstrsCompressed;
1752  S.emitInstruction((Res ? CInst : Inst), getSTI());
1753 }
1754 
1757 }
llvm::MCTargetStreamer::getStreamer
MCStreamer & getStreamer()
Definition: MCStreamer.h:101
i
i
Definition: README.txt:29
llvm::CSKYMCExpr::VK_CSKY_GOTOFF
@ VK_CSKY_GOTOFF
Definition: CSKYMCExpr.h:28
llvm::MCAsmParser
Generic assembler parser interface, for use by target specific assembly parsers.
Definition: MCAsmParser.h:124
is
should just be implemented with a CLZ instruction Since there are other e that share this it would be best to implement this in a target independent as zero is the default value for the binary encoder e add r0 add r5 Register operands should be distinct That is
Definition: README.txt:725
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::MCSymbol
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
llvm::AsmToken::is
bool is(TokenKind K) const
Definition: MCAsmMacro.h:82
llvm::CSKYAttrs::CSKY_FPU_NUMBER_MODULE
@ CSKY_FPU_NUMBER_MODULE
Definition: CSKYAttributes.h:34
llvm::CSKYMCExpr::VK_CSKY_GOTPC
@ VK_CSKY_GOTPC
Definition: CSKYMCExpr.h:27
llvm::MCOperand::createExpr
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:162
print
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
Definition: ArchiveWriter.cpp:189
llvm::MCParsedAsmOperand
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
Definition: MCParsedAsmOperand.h:24
llvm::MCBinaryExpr::Opcode
Opcode
Definition: MCExpr.h:483
llvm::MCOperand::createImm
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:141
llvm::AsmToken::LBrac
@ LBrac
Definition: MCAsmMacro.h:48
llvm::MCInst::insert
iterator insert(iterator I, const MCOperand &Op)
Definition: MCInst.h:224
llvm::AsmToken::EndOfStatement
@ EndOfStatement
Definition: MCAsmMacro.h:42
llvm::MCAsmParser::parseEOL
bool parseEOL()
Definition: MCAsmParser.cpp:47
llvm::MCConstantExpr::create
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition: MCExpr.cpp:194
contains
return AArch64::GPR64RegClass contains(Reg)
MCSectionELF.h
llvm::SmallVector< unsigned, 4 >
Statistic.h
MCParsedAsmOperand.h
llvm::CSKY::parseCPUArch
ArchKind parseCPUArch(StringRef CPU)
Definition: CSKYTargetParser.cpp:100
EnableCompressedInst
static cl::opt< bool > EnableCompressedInst("enable-csky-asm-compressed-inst", cl::Hidden, cl::init(false), cl::desc("Enable C-SKY asm compressed instruction"))
llvm::X86Disassembler::Reg
Reg
All possible values of the reg field in the ModR/M byte.
Definition: X86DisassemblerDecoder.h:462
llvm::CSKY::ArchKind
ArchKind
Definition: CSKYTargetParser.h:110
llvm::MCBinaryExpr::Add
@ Add
Addition.
Definition: MCExpr.h:484
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:139
R4
#define R4(n)
to
Should compile to
Definition: README.txt:449
convertFPR32ToFPR64
static MCRegister convertFPR32ToFPR64(MCRegister Reg)
Definition: CSKYAsmParser.cpp:642
llvm::AsmToken::Integer
@ Integer
Definition: MCAsmMacro.h:32
llvm::ELFAttrs::attrTypeFromString
Optional< unsigned > attrTypeFromString(StringRef tag, TagNameMap tagNameMap)
Definition: ELFAttributes.cpp:24
llvm::AsmToken::getStringContents
StringRef getStringContents() const
Get the contents of a string token (without quotes).
Definition: MCAsmMacro.h:90
llvm::Optional< unsigned >
T
#define T
Definition: Mips16ISelLowering.cpp:341
llvm::FeatureBitset
Container class for subtarget features.
Definition: SubtargetFeature.h:40
llvm::CSKYMCExpr::create
static const CSKYMCExpr * create(const MCExpr *Expr, VariantKind Kind, MCContext &Ctx)
Definition: CSKYMCExpr.cpp:22
llvm::MipsISD::Ret
@ Ret
Definition: MipsISelLowering.h:119
STLExtras.h
llvm::CSKYMCExpr::VK_CSKY_GOT
@ VK_CSKY_GOT
Definition: CSKYMCExpr.h:25
llvm::MCInst
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
llvm::dwarf::Tag
Tag
Definition: Dwarf.h:105
llvm::MCInst::getNumOperands
unsigned getNumOperands() const
Definition: MCInst.h:208
MCTargetAsmParser.h
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
llvm::CSKYMCExpr::VK_CSKY_None
@ VK_CSKY_None
Definition: CSKYMCExpr.h:20
llvm::AsmToken
Target independent representation for an assembler token.
Definition: MCAsmMacro.h:21
isImm
static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI)
Definition: SPIRVInstructionSelector.cpp:982
llvm::MCInst::setOpcode
void setOpcode(unsigned Op)
Definition: MCInst.h:197
llvm::getTheCSKYTarget
Target & getTheCSKYTarget()
Definition: CSKYTargetInfo.cpp:13
llvm::AsmToken::Minus
@ Minus
Definition: MCAsmMacro.h:45
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::CSKYMCExpr::VK_CSKY_TLSLDO
@ VK_CSKY_TLSLDO
Definition: CSKYMCExpr.h:34
llvm::AsmToken::LParen
@ LParen
Definition: MCAsmMacro.h:48
CommandLine.h
llvm::MCAsmParser::Lex
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
llvm::MCStreamer
Streaming machine code generation interface.
Definition: MCStreamer.h:212
llvm::MCAsmParser::parseExpression
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
ELF.h
llvm::RegisterMCAsmParser
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
Definition: TargetRegistry.h:1360
llvm::MatchOperand_Success
@ MatchOperand_Success
Definition: MCTargetAsmParser.h:127
llvm::SMLoc
Represents a location in source code.
Definition: SMLoc.h:23
getReg
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
Definition: MipsDisassembler.cpp:517
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
MatchRegisterAltName
static unsigned MatchRegisterAltName(StringRef Name)
Maps from the set of all alternative registernames to a register number.
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
MCContext.h
llvm::MCStreamer::emitLabel
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Definition: MCStreamer.cpp:423
MCInstrInfo.h
CSKYTargetParser.h
llvm::MCOperand::getImm
int64_t getImm() const
Definition: MCInst.h:80
llvm::ms_demangle::QualifierMangleMode::Result
@ Result
MCInst.h
check
#define check(cond)
llvm::MCSymbol::getVariableValue
const MCExpr * getVariableValue(bool SetUsed=true) const
getVariableValue - Get the value for variable symbols.
Definition: MCSymbol.h:298
llvm::CSKY::parseArch
ArchKind parseArch(StringRef Arch)
Definition: CSKYTargetParser.cpp:91
MCSubtargetInfo.h
llvm::MCSubtargetInfo::getFeatureBits
const FeatureBitset & getFeatureBits() const
Definition: MCSubtargetInfo.h:112
llvm::MCID::Flag
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Definition: MCInstrDesc.h:147
Options
const char LLVMTargetMachineRef LLVMPassBuilderOptionsRef Options
Definition: PassBuilderBindings.cpp:48
llvm::STATISTIC
STATISTIC(NumFunctions, "Total number of functions")
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:54
getSubtargetFeatureName
static const char * getSubtargetFeatureName(uint64_t Val)
CSKYTargetStreamer.h
llvm::MCTargetStreamer
Target specific streamer interface.
Definition: MCStreamer.h:93
Info
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
llvm::MCInst::end
iterator end()
Definition: MCInst.h:221
llvm::CSKYMCExpr::VK_CSKY_PLT
@ VK_CSKY_PLT
Definition: CSKYMCExpr.h:29
isNot
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
Definition: AMDGPULegalizerInfo.cpp:3219
Register
Promote Memory to Register
Definition: Mem2Reg.cpp:110
llvm::CSKYTargetStreamer
Definition: CSKYTargetStreamer.h:45
llvm::CSKYMCExpr::VK_CSKY_TLSLDM
@ VK_CSKY_TLSLDM
Definition: CSKYMCExpr.h:35
llvm::lltok::Kind
Kind
Definition: LLToken.h:18
llvm::MCInst::erase
void erase(iterator I)
Definition: MCInst.h:216
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
llvm::omp::OMPAtomicCompareOp::MAX
@ MAX
X
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
llvm::CSKYAttrs::CSKY_CPU_NAME
@ CSKY_CPU_NAME
Definition: CSKYAttributes.h:24
llvm::MCInst::addOperand
void addOperand(const MCOperand Op)
Definition: MCInst.h:210
Operands
mir Rename Register Operands
Definition: MIRNamerPass.cpp:74
llvm::MCConstantExpr
Definition: MCExpr.h:144
llvm::cl::opt< bool >
MCAsmLexer.h
llvm::MCOperand::isImm
bool isImm() const
Definition: MCInst.h:62
llvm::ParseInstructionInfo
Definition: MCTargetAsmParser.h:118
llvm::isUInt< 16 >
constexpr bool isUInt< 16 >(uint64_t x)
Definition: MathExtras.h:408
uint64_t
LLVM_EXTERNAL_VISIBILITY
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:126
llvm::MCAsmParserExtension::Initialize
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
Definition: MCAsmParserExtension.cpp:21
llvm::MCInst::begin
iterator begin()
Definition: MCInst.h:219
llvm::numbers::e
constexpr double e
Definition: MathExtras.h:57
llvm::MCStreamer::emitInstruction
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
Definition: MCStreamer.cpp:1096
llvm::MatchOperand_ParseFail
@ MatchOperand_ParseFail
Definition: MCTargetAsmParser.h:129
llvm::CSKYMCExpr
Definition: CSKYMCExpr.h:17
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:432
MCRegisterInfo.h
llvm::MCBinaryExpr::create
static const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition: MCExpr.cpp:183
llvm::CSKYInstPrinter::getRegisterName
static const char * getRegisterName(unsigned RegNo)
Definition: CSKYInstPrinter.cpp:263
llvm::MCSymbol::isVariable
bool isVariable() const
isVariable - Check if this is a variable symbol.
Definition: MCSymbol.h:293
llvm::CSKYMCExpr::VariantKind
VariantKind
Definition: CSKYMCExpr.h:19
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::isUInt< 8 >
constexpr bool isUInt< 8 >(uint64_t x)
Definition: MathExtras.h:405
CSKYMCTargetDesc.h
llvm::FeatureBitset::size
constexpr size_t size() const
Definition: SubtargetFeature.h:92
CSKYMnemonicSpellCheck
static std::string CSKYMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
llvm::WinEH::EncodingType::CE
@ CE
Windows NT (Windows on ARM)
MatchRegisterName
static unsigned MatchRegisterName(StringRef Name)
llvm::ErrorInfo
Base class for user error types.
Definition: Error.h:347
llvm::MCTargetOptions
Definition: MCTargetOptions.h:42
llvm::CSKYMCExpr::VK_CSKY_TLSIE
@ VK_CSKY_TLSIE
Definition: CSKYMCExpr.h:31
isReg
static bool isReg(const MCInst &MI, unsigned OpNo)
Definition: MipsInstPrinter.cpp:31
llvm::AsmToken::Comma
@ Comma
Definition: MCAsmMacro.h:49
LLVMInitializeCSKYAsmParser
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYAsmParser()
Definition: CSKYAsmParser.cpp:1755
llvm::MatchOperand_NoMatch
@ MatchOperand_NoMatch
Definition: MCTargetAsmParser.h:128
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::CSKYMCExpr::VK_CSKY_TLSLE
@ VK_CSKY_TLSLE
Definition: CSKYMCExpr.h:32
llvm::MCAsmParser::getTok
const AsmToken & getTok() const
Get the current AsmToken from the stream.
Definition: MCAsmParser.cpp:38
llvm::AsmToken::Plus
@ Plus
Definition: MCAsmMacro.h:45
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
llvm::MCOperand::createReg
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:134
llvm::CSKYMCExpr::VK_CSKY_PLT_IMM18_BY4
@ VK_CSKY_PLT_IMM18_BY4
Definition: CSKYMCExpr.h:30
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::AsmToken::RParen
@ RParen
Definition: MCAsmMacro.h:48
llvm::MCRegisterInfo
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Definition: MCRegisterInfo.h:135
llvm::CSKYMCExpr::VK_CSKY_GOT_IMM18_BY4
@ VK_CSKY_GOT_IMM18_BY4
Definition: CSKYMCExpr.h:26
CSKYAttributes.h
llvm::AsmToken::LessLess
@ LessLess
Definition: MCAsmMacro.h:53
llvm::AsmToken::getString
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
Definition: MCAsmMacro.h:110
CSKYInstPrinter.h
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::AMDGPU::SendMsg::Msg
const CustomOperand< const MCSubtargetInfo & > Msg[]
Definition: AMDGPUAsmUtils.cpp:39
llvm::OperandMatchResultTy
OperandMatchResultTy
Definition: MCTargetAsmParser.h:126
llvm::omp::OMPAtomicCompareOp::MIN
@ MIN
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:83
llvm::MCInst::getLoc
SMLoc getLoc() const
Definition: MCInst.h:204
llvm::MCInstrInfo
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:26
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
llvm::MCInst::setLoc
void setLoc(SMLoc loc)
Definition: MCInst.h:203
llvm::AsmToken::Identifier
@ Identifier
Definition: MCAsmMacro.h:28
llvm::CSKYMCExpr::VK_CSKY_TLSGD
@ VK_CSKY_TLSGD
Definition: CSKYMCExpr.h:33
llvm::AsmToken::isNot
bool isNot(TokenKind K) const
Definition: MCAsmMacro.h:83
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:345
llvm::MCBinaryExpr::Sub
@ Sub
Subtraction.
Definition: MCExpr.h:506
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
llvm::AArch64CC::LS
@ LS
Definition: AArch64BaseInfo.h:264
Casting.h
llvm::MCOperand::getExpr
const MCExpr * getExpr() const
Definition: MCInst.h:114
llvm::AsmToken::RBrac
@ RBrac
Definition: MCAsmMacro.h:48
llvm::MCInst::getOpcode
unsigned getOpcode() const
Definition: MCInst.h:198
llvm::MCTargetAsmParser
MCTargetAsmParser - Generic interface to target specific assembly parsers.
Definition: MCTargetAsmParser.h:314
parseImmediate
bool parseImmediate(MCInst &MI, uint64_t &Size, ArrayRef< uint8_t > Bytes)
Definition: WebAssemblyDisassembler.cpp:109
llvm::object::Identifier
@ Identifier
Definition: COFFModuleDefinition.cpp:34
llvm::MCSymbolRefExpr::create
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:386
StringSwitch.h
matchRegisterNameHelper
static bool matchRegisterNameHelper(const MCSubtargetInfo &STI, MCRegister &RegNo, StringRef Name)
Definition: CSKYAsmParser.cpp:1001
llvm::MCOperand::isExpr
bool isExpr() const
Definition: MCInst.h:65
CSKYMCExpr.h
llvm::RISCVMatInt::Imm
@ Imm
Definition: RISCVMatInt.h:23
llvm::MCStreamer::getTargetStreamer
MCTargetStreamer * getTargetStreamer()
Definition: MCStreamer.h:300
llvm::AsmToken::getIdentifier
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Definition: MCAsmMacro.h:99
N
#define N
MCStreamer.h
llvm::MCInst::getOperand
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:206
llvm::isMem
static bool isMem(const MachineInstr &MI, unsigned Op)
Definition: X86InstrInfo.h:131
CSKYTargetInfo.h
llvm::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
llvm::SMLoc::getFromPointer
static SMLoc getFromPointer(const char *Ptr)
Definition: SMLoc.h:36
RegName
#define RegName(no)
llvm::MCOperand
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:36
Register.h
llvm::MCSymbolRefExpr::VK_None
@ VK_None
Definition: MCExpr.h:195
llvm::AsmToken::String
@ String
Definition: MCAsmMacro.h:29
llvm::cl::desc
Definition: CommandLine.h:405
llvm::AsmToken::getLoc
SMLoc getLoc() const
Definition: MCAsmLexer.cpp:26
llvm::AsmToken::getEndLoc
SMLoc getEndLoc() const
Definition: MCAsmLexer.cpp:30
TargetRegistry.h
MCExpr.h
llvm::MCSubtargetInfo
Generic base class for all target subtargets.
Definition: MCSubtargetInfo.h:76
llvm::CSKYAttrs::CSKY_ARCH_NAME
@ CSKY_ARCH_NAME
Definition: CSKYAttributes.h:23
llvm::FeatureBitset::any
bool any() const
Definition: SubtargetFeature.h:94
llvm::CSKYAttrs::getCSKYAttributeTags
const TagNameMap & getCSKYAttributeTags()
Definition: CSKYAttributes.cpp:31
llvm::MCExpr
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
Debug.h
llvm::MCAsmParser::parseToken
bool parseToken(AsmToken::TokenKind T, const Twine &Msg="unexpected token")
Definition: MCAsmParser.cpp:61
Other
Optional< std::vector< StOtherPiece > > Other
Definition: ELFYAML.cpp:1236
llvm::MCRegister
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:24
llvm::MCOperand::getReg
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:69