LLVM  14.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 
13 #include "llvm/ADT/STLExtras.h"
14 #include "llvm/ADT/StringSwitch.h"
15 #include "llvm/CodeGen/Register.h"
16 #include "llvm/MC/MCContext.h"
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCInst.h"
22 #include "llvm/MC/MCRegisterInfo.h"
23 #include "llvm/MC/MCSectionELF.h"
24 #include "llvm/MC/MCStreamer.h"
26 #include "llvm/MC/TargetRegistry.h"
27 #include "llvm/Support/Casting.h"
28 #include "llvm/Support/Debug.h"
29 
30 #define DEBUG_TYPE "csky-asm-parser"
31 
32 using namespace llvm;
33 
34 namespace {
35 struct CSKYOperand;
36 
37 class CSKYAsmParser : public MCTargetAsmParser {
38 
39  const MCRegisterInfo *MRI;
40 
41  bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo,
42  int64_t Lower, int64_t Upper, Twine Msg);
43 
44  SMLoc getLoc() const { return getParser().getTok().getLoc(); }
45 
46  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
49  bool MatchingInlineAsm) override;
50 
51  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
52 
53  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
54  SMLoc NameLoc, OperandVector &Operands) override;
55 
56  bool ParseDirective(AsmToken DirectiveID) override;
57 
58  OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc,
59  SMLoc &EndLoc) override;
60 
61  bool processInstruction(MCInst &Inst, SMLoc IDLoc, OperandVector &Operands,
62  MCStreamer &Out);
63 
64 // Auto-generated instruction matching functions
65 #define GET_ASSEMBLER_HEADER
66 #include "CSKYGenAsmMatcher.inc"
67 
72  OperandMatchResultTy parseConstpoolSymbol(OperandVector &Operands);
77 
78  bool parseOperand(OperandVector &Operands, StringRef Mnemonic);
79 
80 public:
81  enum CSKYMatchResultTy {
82  Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
83  Match_RequiresSameSrcAndDst,
84  Match_InvalidRegOutOfRange,
85 #define GET_OPERAND_DIAGNOSTIC_TYPES
86 #include "CSKYGenAsmMatcher.inc"
87 #undef GET_OPERAND_DIAGNOSTIC_TYPES
88  };
89 
90  CSKYAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
91  const MCInstrInfo &MII, const MCTargetOptions &Options)
92  : MCTargetAsmParser(Options, STI, MII) {
93  setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
94  }
95 };
96 
97 /// Instances of this class represent a parsed machine instruction.
98 struct CSKYOperand : public MCParsedAsmOperand {
99 
100  enum KindTy {
101  Token,
102  Register,
103  Immediate,
104  RegisterSeq,
105  CPOP,
106  RegisterList
107  } Kind;
108 
109  struct RegOp {
110  unsigned RegNum;
111  };
112 
113  struct ImmOp {
114  const MCExpr *Val;
115  };
116 
117  struct ConstpoolOp {
118  const MCExpr *Val;
119  };
120 
121  struct RegSeqOp {
122  unsigned RegNumFrom;
123  unsigned RegNumTo;
124  };
125 
126  struct RegListOp {
127  unsigned List1From = 0;
128  unsigned List1To = 0;
129  unsigned List2From = 0;
130  unsigned List2To = 0;
131  unsigned List3From = 0;
132  unsigned List3To = 0;
133  unsigned List4From = 0;
134  unsigned List4To = 0;
135  };
136 
137  SMLoc StartLoc, EndLoc;
138  union {
139  StringRef Tok;
140  RegOp Reg;
141  ImmOp Imm;
142  ConstpoolOp CPool;
143  RegSeqOp RegSeq;
144  RegListOp RegList;
145  };
146 
147  CSKYOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
148 
149 public:
150  CSKYOperand(const CSKYOperand &o) : MCParsedAsmOperand() {
151  Kind = o.Kind;
152  StartLoc = o.StartLoc;
153  EndLoc = o.EndLoc;
154  switch (Kind) {
155  case Register:
156  Reg = o.Reg;
157  break;
158  case RegisterSeq:
159  RegSeq = o.RegSeq;
160  break;
161  case CPOP:
162  CPool = o.CPool;
163  break;
164  case Immediate:
165  Imm = o.Imm;
166  break;
167  case Token:
168  Tok = o.Tok;
169  break;
170  case RegisterList:
171  RegList = o.RegList;
172  break;
173  }
174  }
175 
176  bool isToken() const override { return Kind == Token; }
177  bool isReg() const override { return Kind == Register; }
178  bool isImm() const override { return Kind == Immediate; }
179  bool isRegisterSeq() const { return Kind == RegisterSeq; }
180  bool isRegisterList() const { return Kind == RegisterList; }
181  bool isConstPoolOp() const { return Kind == CPOP; }
182 
183  bool isMem() const override { return false; }
184 
185  static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm) {
186  if (auto CE = dyn_cast<MCConstantExpr>(Expr)) {
187  Imm = CE->getValue();
188  return true;
189  }
190 
191  return false;
192  }
193 
194  template <unsigned num, unsigned shift = 0> bool isUImm() const {
195  if (!isImm())
196  return false;
197 
198  int64_t Imm;
199  bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
200  return IsConstantImm && isShiftedUInt<num, shift>(Imm);
201  }
202 
203  template <unsigned num> bool isOImm() const {
204  if (!isImm())
205  return false;
206 
207  int64_t Imm;
208  bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
209  return IsConstantImm && isUInt<num>(Imm - 1);
210  }
211 
212  template <unsigned num, unsigned shift = 0> bool isSImm() const {
213  if (!isImm())
214  return false;
215 
216  int64_t Imm;
217  bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
218  return IsConstantImm && isShiftedInt<num, shift>(Imm);
219  }
220 
221  bool isUImm1() const { return isUImm<1>(); }
222  bool isUImm2() const { return isUImm<2>(); }
223  bool isUImm3() const { return isUImm<3>(); }
224  bool isUImm4() const { return isUImm<4>(); }
225  bool isUImm5() const { return isUImm<5>(); }
226  bool isUImm6() const { return isUImm<6>(); }
227  bool isUImm7() const { return isUImm<7>(); }
228  bool isUImm8() const { return isUImm<8>(); }
229  bool isUImm12() const { return isUImm<12>(); }
230  bool isUImm16() const { return isUImm<16>(); }
231  bool isUImm20() const { return isUImm<20>(); }
232  bool isUImm24() const { return isUImm<24>(); }
233 
234  bool isOImm3() const { return isOImm<3>(); }
235  bool isOImm4() const { return isOImm<4>(); }
236  bool isOImm5() const { return isOImm<5>(); }
237  bool isOImm6() const { return isOImm<6>(); }
238  bool isOImm8() const { return isOImm<8>(); }
239  bool isOImm12() const { return isOImm<12>(); }
240  bool isOImm16() const { return isOImm<16>(); }
241 
242  bool isSImm8() const { return isSImm<8>(); }
243 
244  bool isUImm5Shift1() { return isUImm<5, 1>(); }
245  bool isUImm5Shift2() { return isUImm<5, 2>(); }
246  bool isUImm7Shift1() { return isUImm<7, 1>(); }
247  bool isUImm7Shift2() { return isUImm<7, 2>(); }
248  bool isUImm7Shift3() { return isUImm<7, 3>(); }
249  bool isUImm8Shift2() { return isUImm<8, 2>(); }
250  bool isUImm8Shift3() { return isUImm<8, 3>(); }
251  bool isUImm8Shift8() { return isUImm<8, 8>(); }
252  bool isUImm8Shift16() { return isUImm<8, 16>(); }
253  bool isUImm8Shift24() { return isUImm<8, 24>(); }
254  bool isUImm12Shift1() { return isUImm<12, 1>(); }
255  bool isUImm12Shift2() { return isUImm<12, 2>(); }
256  bool isUImm16Shift8() { return isUImm<16, 8>(); }
257  bool isUImm16Shift16() { return isUImm<16, 16>(); }
258  bool isUImm24Shift8() { return isUImm<24, 8>(); }
259 
260  bool isSImm16Shift1() { return isSImm<16, 1>(); }
261 
262  bool isCSKYSymbol() const { return isImm(); }
263 
264  bool isConstpool() const { return isConstPoolOp(); }
265  bool isDataSymbol() const { return isConstPoolOp(); }
266 
267  bool isSPOperand() const {
268  if (!isReg())
269  return false;
270  return getReg() == CSKY::R14;
271  }
272 
273  bool isPSRFlag() const {
274  int64_t Imm;
275  // Must be of 'immediate' type and a constant.
276  if (!isImm() || !evaluateConstantImm(getImm(), Imm))
277  return false;
278 
279  return isUInt<5>(Imm);
280  }
281 
282  template <unsigned MIN, unsigned MAX> bool isRegSeqTemplate() const {
283  if (!isRegisterSeq())
284  return false;
285 
286  std::pair<unsigned, unsigned> regSeq = getRegSeq();
287 
288  return MIN <= regSeq.first && regSeq.first <= regSeq.second &&
289  regSeq.second <= MAX;
290  }
291 
292  bool isRegSeq() const { return isRegSeqTemplate<CSKY::R0, CSKY::R31>(); }
293 
294  static bool isLegalRegList(unsigned from, unsigned to) {
295  if (from == 0 && to == 0)
296  return true;
297 
298  if (from == to) {
299  if (from != CSKY::R4 && from != CSKY::R15 && from != CSKY::R16 &&
300  from != CSKY::R28)
301  return false;
302 
303  return true;
304  } else {
305  if (from != CSKY::R4 && from != CSKY::R16)
306  return false;
307 
308  if (from == CSKY::R4 && to > CSKY::R4 && to < CSKY::R12)
309  return true;
310  else if (from == CSKY::R16 && to > CSKY::R16 && to < CSKY::R18)
311  return true;
312  else
313  return false;
314  }
315  }
316 
317  bool isRegList() const {
318  if (!isRegisterList())
319  return false;
320 
321  auto regList = getRegList();
322 
323  if (!isLegalRegList(regList.List1From, regList.List1To))
324  return false;
325  if (!isLegalRegList(regList.List2From, regList.List2To))
326  return false;
327  if (!isLegalRegList(regList.List3From, regList.List3To))
328  return false;
329  if (!isLegalRegList(regList.List4From, regList.List4To))
330  return false;
331 
332  return true;
333  }
334 
335  bool isExtImm6() {
336  if (!isImm())
337  return false;
338 
339  int64_t Imm;
340  bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
341  if (!IsConstantImm)
342  return false;
343 
344  int uimm4 = Imm & 0xf;
345 
346  return isShiftedUInt<6, 0>(Imm) && uimm4 >= 0 && uimm4 <= 14;
347  }
348 
349  /// Gets location of the first token of this operand.
350  SMLoc getStartLoc() const override { return StartLoc; }
351  /// Gets location of the last token of this operand.
352  SMLoc getEndLoc() const override { return EndLoc; }
353 
354  unsigned getReg() const override {
355  assert(Kind == Register && "Invalid type access!");
356  return Reg.RegNum;
357  }
358 
359  std::pair<unsigned, unsigned> getRegSeq() const {
360  assert(Kind == RegisterSeq && "Invalid type access!");
361  return std::pair<unsigned, unsigned>(RegSeq.RegNumFrom, RegSeq.RegNumTo);
362  }
363 
364  RegListOp getRegList() const {
365  assert(Kind == RegisterList && "Invalid type access!");
366  return RegList;
367  }
368 
369  const MCExpr *getImm() const {
370  assert(Kind == Immediate && "Invalid type access!");
371  return Imm.Val;
372  }
373 
374  const MCExpr *getConstpoolOp() const {
375  assert(Kind == CPOP && "Invalid type access!");
376  return CPool.Val;
377  }
378 
379  StringRef getToken() const {
380  assert(Kind == Token && "Invalid type access!");
381  return Tok;
382  }
383 
384  void print(raw_ostream &OS) const override {
385  auto RegName = [](unsigned Reg) {
386  if (Reg)
388  else
389  return "noreg";
390  };
391 
392  switch (Kind) {
393  case CPOP:
394  OS << *getConstpoolOp();
395  break;
396  case Immediate:
397  OS << *getImm();
398  break;
399  case KindTy::Register:
400  OS << "<register " << RegName(getReg()) << ">";
401  break;
402  case RegisterSeq:
403  OS << "<register-seq ";
404  OS << RegName(getRegSeq().first) << "-" << RegName(getRegSeq().second)
405  << ">";
406  break;
407  case RegisterList:
408  OS << "<register-list ";
409  OS << RegName(getRegList().List1From) << "-"
410  << RegName(getRegList().List1To) << ",";
411  OS << RegName(getRegList().List2From) << "-"
412  << RegName(getRegList().List2To) << ",";
413  OS << RegName(getRegList().List3From) << "-"
414  << RegName(getRegList().List3To) << ",";
415  OS << RegName(getRegList().List4From) << "-"
416  << RegName(getRegList().List4To);
417  break;
418  case Token:
419  OS << "'" << getToken() << "'";
420  break;
421  }
422  }
423 
424  static std::unique_ptr<CSKYOperand> createToken(StringRef Str, SMLoc S) {
425  auto Op = std::make_unique<CSKYOperand>(Token);
426  Op->Tok = Str;
427  Op->StartLoc = S;
428  Op->EndLoc = S;
429  return Op;
430  }
431 
432  static std::unique_ptr<CSKYOperand> createReg(unsigned RegNo, SMLoc S,
433  SMLoc E) {
434  auto Op = std::make_unique<CSKYOperand>(Register);
435  Op->Reg.RegNum = RegNo;
436  Op->StartLoc = S;
437  Op->EndLoc = E;
438  return Op;
439  }
440 
441  static std::unique_ptr<CSKYOperand> createRegSeq(unsigned RegNoFrom,
442  unsigned RegNoTo, SMLoc S) {
443  auto Op = std::make_unique<CSKYOperand>(RegisterSeq);
444  Op->RegSeq.RegNumFrom = RegNoFrom;
445  Op->RegSeq.RegNumTo = RegNoTo;
446  Op->StartLoc = S;
447  Op->EndLoc = S;
448  return Op;
449  }
450 
451  static std::unique_ptr<CSKYOperand>
452  createRegList(SmallVector<unsigned, 4> reglist, SMLoc S) {
453  auto Op = std::make_unique<CSKYOperand>(RegisterList);
454  Op->RegList.List1From = 0;
455  Op->RegList.List1To = 0;
456  Op->RegList.List2From = 0;
457  Op->RegList.List2To = 0;
458  Op->RegList.List3From = 0;
459  Op->RegList.List3To = 0;
460  Op->RegList.List4From = 0;
461  Op->RegList.List4To = 0;
462 
463  for (unsigned i = 0; i < reglist.size(); i += 2) {
464  if (Op->RegList.List1From == 0) {
465  Op->RegList.List1From = reglist[i];
466  Op->RegList.List1To = reglist[i + 1];
467  } else if (Op->RegList.List2From == 0) {
468  Op->RegList.List2From = reglist[i];
469  Op->RegList.List2To = reglist[i + 1];
470  } else if (Op->RegList.List3From == 0) {
471  Op->RegList.List3From = reglist[i];
472  Op->RegList.List3To = reglist[i + 1];
473  } else if (Op->RegList.List4From == 0) {
474  Op->RegList.List4From = reglist[i];
475  Op->RegList.List4To = reglist[i + 1];
476  } else {
477  assert(0);
478  }
479  }
480 
481  Op->StartLoc = S;
482  Op->EndLoc = S;
483  return Op;
484  }
485 
486  static std::unique_ptr<CSKYOperand> createImm(const MCExpr *Val, SMLoc S,
487  SMLoc E) {
488  auto Op = std::make_unique<CSKYOperand>(Immediate);
489  Op->Imm.Val = Val;
490  Op->StartLoc = S;
491  Op->EndLoc = E;
492  return Op;
493  }
494 
495  static std::unique_ptr<CSKYOperand> createConstpoolOp(const MCExpr *Val,
496  SMLoc S, SMLoc E) {
497  auto Op = std::make_unique<CSKYOperand>(CPOP);
498  Op->CPool.Val = Val;
499  Op->StartLoc = S;
500  Op->EndLoc = E;
501  return Op;
502  }
503 
504  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
505  assert(Expr && "Expr shouldn't be null!");
506  if (auto *CE = dyn_cast<MCConstantExpr>(Expr))
507  Inst.addOperand(MCOperand::createImm(CE->getValue()));
508  else
509  Inst.addOperand(MCOperand::createExpr(Expr));
510  }
511 
512  // Used by the TableGen Code.
513  void addRegOperands(MCInst &Inst, unsigned N) const {
514  assert(N == 1 && "Invalid number of operands!");
516  }
517 
518  void addImmOperands(MCInst &Inst, unsigned N) const {
519  assert(N == 1 && "Invalid number of operands!");
520  addExpr(Inst, getImm());
521  }
522 
523  void addConstpoolOperands(MCInst &Inst, unsigned N) const {
524  assert(N == 1 && "Invalid number of operands!");
525  Inst.addOperand(MCOperand::createExpr(getConstpoolOp()));
526  }
527 
528  void addRegSeqOperands(MCInst &Inst, unsigned N) const {
529  assert(N == 2 && "Invalid number of operands!");
530  auto regSeq = getRegSeq();
531 
532  Inst.addOperand(MCOperand::createReg(regSeq.first));
533  Inst.addOperand(MCOperand::createReg(regSeq.second));
534  }
535 
536  static unsigned getListValue(unsigned ListFrom, unsigned ListTo) {
537  if (ListFrom == ListTo && ListFrom == CSKY::R15)
538  return (1 << 4);
539  else if (ListFrom == ListTo && ListFrom == CSKY::R28)
540  return (1 << 8);
541  else if (ListFrom == CSKY::R4)
542  return ListTo - ListFrom + 1;
543  else if (ListFrom == CSKY::R16)
544  return ((ListTo - ListFrom + 1) << 5);
545  else
546  return 0;
547  }
548 
549  void addRegListOperands(MCInst &Inst, unsigned N) const {
550  assert(N == 1 && "Invalid number of operands!");
551  auto regList = getRegList();
552 
553  unsigned V = 0;
554 
555  unsigned T = getListValue(regList.List1From, regList.List1To);
556  if (T != 0)
557  V = V | T;
558 
559  T = getListValue(regList.List2From, regList.List2To);
560  if (T != 0)
561  V = V | T;
562 
563  T = getListValue(regList.List3From, regList.List3To);
564  if (T != 0)
565  V = V | T;
566 
567  T = getListValue(regList.List4From, regList.List4To);
568  if (T != 0)
569  V = V | T;
570 
572  }
573 
574  bool isValidForTie(const CSKYOperand &Other) const {
575  if (Kind != Other.Kind)
576  return false;
577 
578  switch (Kind) {
579  default:
580  llvm_unreachable("Unexpected kind");
581  return false;
582  case Register:
583  return Reg.RegNum == Other.Reg.RegNum;
584  }
585  }
586 };
587 } // end anonymous namespace.
588 
589 #define GET_REGISTER_MATCHER
590 #define GET_SUBTARGET_FEATURE_NAME
591 #define GET_MATCHER_IMPLEMENTATION
592 #define GET_MNEMONIC_SPELL_CHECKER
593 #include "CSKYGenAsmMatcher.inc"
594 
595 static std::string CSKYMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
596  unsigned VariantID = 0);
597 
598 bool CSKYAsmParser::generateImmOutOfRangeError(
599  OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper,
600  Twine Msg = "immediate must be an integer in the range") {
601  SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
602  return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]");
603 }
604 
605 bool CSKYAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
607  MCStreamer &Out,
609  bool MatchingInlineAsm) {
610  MCInst Inst;
611  FeatureBitset MissingFeatures;
612 
613  auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
614  MatchingInlineAsm);
615  switch (Result) {
616  default:
617  break;
618  case Match_Success:
619  return processInstruction(Inst, IDLoc, Operands, Out);
620  case Match_MissingFeature: {
621  assert(MissingFeatures.any() && "Unknown missing features!");
622  ListSeparator LS;
623  std::string Msg = "instruction requires the following: ";
624  for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) {
625  if (MissingFeatures[i]) {
626  Msg += LS;
627  Msg += getSubtargetFeatureName(i);
628  }
629  }
630  return Error(IDLoc, Msg);
631  }
632  case Match_MnemonicFail: {
633  FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
634  std::string Suggestion =
635  CSKYMnemonicSpellCheck(((CSKYOperand &)*Operands[0]).getToken(), FBS);
636  return Error(IDLoc, "unrecognized instruction mnemonic" + Suggestion);
637  }
638  case Match_InvalidTiedOperand:
639  case Match_InvalidOperand: {
640  SMLoc ErrorLoc = IDLoc;
641  if (ErrorInfo != ~0U) {
642  if (ErrorInfo >= Operands.size())
643  return Error(ErrorLoc, "too few operands for instruction");
644 
645  ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
646  if (ErrorLoc == SMLoc())
647  ErrorLoc = IDLoc;
648  }
649  return Error(ErrorLoc, "invalid operand for instruction");
650  }
651  }
652 
653  // Handle the case when the error message is of specific type
654  // other than the generic Match_InvalidOperand, and the
655  // corresponding operand is missing.
656  if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
657  SMLoc ErrorLoc = IDLoc;
658  if (ErrorInfo != ~0U && ErrorInfo >= Operands.size())
659  return Error(ErrorLoc, "too few operands for instruction");
660  }
661 
662  switch (Result) {
663  default:
664  break;
665  case Match_InvalidSImm8:
666  return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 7),
667  (1 << 7) - 1);
668  case Match_InvalidOImm3:
669  return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 3));
670  case Match_InvalidOImm4:
671  return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 4));
672  case Match_InvalidOImm5:
673  return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5));
674  case Match_InvalidOImm6:
675  return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6));
676  case Match_InvalidOImm8:
677  return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 8));
678  case Match_InvalidOImm12:
679  return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 12));
680  case Match_InvalidOImm16:
681  return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 16));
682  case Match_InvalidUImm1:
683  return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 1) - 1);
684  case Match_InvalidUImm2:
685  return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1);
686  case Match_InvalidUImm3:
687  return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1);
688  case Match_InvalidUImm4:
689  return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);
690  case Match_InvalidUImm5:
691  return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
692  case Match_InvalidUImm6:
693  return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
694  case Match_InvalidUImm7:
695  return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1);
696  case Match_InvalidUImm8:
697  return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 8) - 1);
698  case Match_InvalidUImm12:
699  return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1);
700  case Match_InvalidUImm16:
701  return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 16) - 1);
702  case Match_InvalidUImm5Shift1:
703  return generateImmOutOfRangeError(
704  Operands, ErrorInfo, 0, (1 << 5) - 2,
705  "immediate must be a multiple of 2 bytes in the range");
706  case Match_InvalidUImm12Shift1:
707  return generateImmOutOfRangeError(
708  Operands, ErrorInfo, 0, (1 << 12) - 2,
709  "immediate must be a multiple of 2 bytes in the range");
710  case Match_InvalidUImm5Shift2:
711  return generateImmOutOfRangeError(
712  Operands, ErrorInfo, 0, (1 << 5) - 4,
713  "immediate must be a multiple of 4 bytes in the range");
714  case Match_InvalidUImm7Shift1:
715  return generateImmOutOfRangeError(
716  Operands, ErrorInfo, 0, (1 << 7) - 2,
717  "immediate must be a multiple of 2 bytes in the range");
718  case Match_InvalidUImm7Shift2:
719  return generateImmOutOfRangeError(
720  Operands, ErrorInfo, 0, (1 << 7) - 4,
721  "immediate must be a multiple of 4 bytes in the range");
722  case Match_InvalidUImm8Shift2:
723  return generateImmOutOfRangeError(
724  Operands, ErrorInfo, 0, (1 << 8) - 4,
725  "immediate must be a multiple of 4 bytes in the range");
726  case Match_InvalidUImm8Shift3:
727  return generateImmOutOfRangeError(
728  Operands, ErrorInfo, 0, (1 << 8) - 8,
729  "immediate must be a multiple of 8 bytes in the range");
730  case Match_InvalidUImm8Shift8:
731  return generateImmOutOfRangeError(
732  Operands, ErrorInfo, 0, (1 << 8) - 256,
733  "immediate must be a multiple of 256 bytes in the range");
734  case Match_InvalidUImm12Shift2:
735  return generateImmOutOfRangeError(
736  Operands, ErrorInfo, 0, (1 << 12) - 4,
737  "immediate must be a multiple of 4 bytes in the range");
738  case Match_InvalidCSKYSymbol: {
739  SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
740  return Error(ErrorLoc, "operand must be a symbol name");
741  }
742  case Match_InvalidConstpool: {
743  SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
744  return Error(ErrorLoc, "operand must be a constpool symbol name");
745  }
746  case Match_InvalidPSRFlag: {
747  SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
748  return Error(ErrorLoc, "psrset operand is not valid");
749  }
750  case Match_InvalidRegSeq: {
751  SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
752  return Error(ErrorLoc, "Register sequence is not valid");
753  }
754  case Match_InvalidRegOutOfRange: {
755  SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
756  return Error(ErrorLoc, "register is out of range");
757  }
758  case Match_RequiresSameSrcAndDst: {
759  SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
760  return Error(ErrorLoc, "src and dst operand must be same");
761  }
762  case Match_InvalidRegList: {
763  SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
764  return Error(ErrorLoc, "invalid register list");
765  }
766  }
767  LLVM_DEBUG(dbgs() << "Result = " << Result);
768  llvm_unreachable("Unknown match type detected!");
769 }
770 
771 bool CSKYAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
773  MCStreamer &Out) {
774 
775  if (Inst.getOpcode() == CSKY::LDQ32 || Inst.getOpcode() == CSKY::STQ32) {
776  if (Inst.getOperand(1).getReg() != CSKY::R4 ||
777  Inst.getOperand(2).getReg() != CSKY::R7) {
778  return Error(IDLoc, "Register sequence is not valid. 'r4-r7' expected");
779  }
780  Inst.setOpcode(Inst.getOpcode() == CSKY::LDQ32 ? CSKY::LDM32 : CSKY::STM32);
781  Out.emitInstruction(Inst, getSTI());
782  return false;
783  } else if (Inst.getOpcode() == CSKY::SEXT32 ||
784  Inst.getOpcode() == CSKY::ZEXT32) {
785  if (Inst.getOperand(2).getImm() < Inst.getOperand(3).getImm())
786  return Error(IDLoc, "msb must be greater or equal to lsb");
787  } else if (Inst.getOpcode() == CSKY::INS32) {
788  if (Inst.getOperand(3).getImm() < Inst.getOperand(4).getImm())
789  return Error(IDLoc, "msb must be greater or equal to lsb");
790  } else if (Inst.getOpcode() == CSKY::IDLY32) {
791  if (Inst.getOperand(0).getImm() > 32 || Inst.getOperand(0).getImm() < 0)
792  return Error(IDLoc, "n must be in range [0,32]");
793  }
794 
795  Out.emitInstruction(Inst, getSTI());
796  return false;
797 }
798 
799 // Attempts to match Name as a register (either using the default name or
800 // alternative ABI names), setting RegNo to the matching register. Upon
801 // failure, returns true and sets RegNo to 0.
803  MCRegister &RegNo, StringRef Name) {
804  RegNo = MatchRegisterName(Name);
805 
806  if (RegNo == CSKY::NoRegister)
807  RegNo = MatchRegisterAltName(Name);
808 
809  return RegNo == CSKY::NoRegister;
810 }
811 
812 bool CSKYAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
813  SMLoc &EndLoc) {
814  const AsmToken &Tok = getParser().getTok();
815  StartLoc = Tok.getLoc();
816  EndLoc = Tok.getEndLoc();
817  StringRef Name = getLexer().getTok().getIdentifier();
818 
819  if (!matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name)) {
820  getParser().Lex(); // Eat identifier token.
821  return false;
822  }
823 
824  return MatchOperand_NoMatch;
825 }
826 
827 OperandMatchResultTy CSKYAsmParser::parseRegister(OperandVector &Operands) {
828  SMLoc S = getLoc();
829  SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
830 
831  switch (getLexer().getKind()) {
832  default:
833  return MatchOperand_NoMatch;
834  case AsmToken::Identifier: {
835  StringRef Name = getLexer().getTok().getIdentifier();
836  MCRegister RegNo;
837 
838  if (matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name))
839  return MatchOperand_NoMatch;
840 
841  getLexer().Lex();
842  Operands.push_back(CSKYOperand::createReg(RegNo, S, E));
843 
844  return MatchOperand_Success;
845  }
846  }
847 }
848 
849 OperandMatchResultTy CSKYAsmParser::parseBaseRegImm(OperandVector &Operands) {
850  assert(getLexer().is(AsmToken::LParen));
851 
852  Operands.push_back(CSKYOperand::createToken("(", getLoc()));
853 
854  auto Tok = getParser().Lex(); // Eat '('
855 
856  if (parseRegister(Operands) != MatchOperand_Success) {
857  getLexer().UnLex(Tok);
858  Operands.pop_back();
859  return MatchOperand_NoMatch;
860  }
861 
862  if (getLexer().is(AsmToken::RParen)) {
863  Operands.push_back(CSKYOperand::createToken(")", getLoc()));
864  getParser().Lex(); // Eat ')'
865  return MatchOperand_Success;
866  }
867 
868  if (getLexer().isNot(AsmToken::Comma)) {
869  Error(getLoc(), "expected ','");
870  return MatchOperand_ParseFail;
871  }
872 
873  getParser().Lex(); // Eat ','
874 
875  if (parseRegister(Operands) == MatchOperand_Success) {
876  if (getLexer().isNot(AsmToken::LessLess)) {
877  Error(getLoc(), "expected '<<'");
878  return MatchOperand_ParseFail;
879  }
880 
881  Operands.push_back(CSKYOperand::createToken("<<", getLoc()));
882 
883  getParser().Lex(); // Eat '<<'
884 
886  Error(getLoc(), "expected imm");
887  return MatchOperand_ParseFail;
888  }
889 
891  Error(getLoc(), "expected imm");
892  return MatchOperand_ParseFail;
893  }
894 
895  if (getLexer().isNot(AsmToken::RParen)) {
896  Error(getLoc(), "expected ')'");
897  return MatchOperand_ParseFail;
898  }
899 
900  Operands.push_back(CSKYOperand::createToken(")", getLoc()));
901 
902  getParser().Lex(); // Eat ')'
903 
904  return MatchOperand_Success;
905 }
906 
908  switch (getLexer().getKind()) {
909  default:
910  return MatchOperand_NoMatch;
911  case AsmToken::LParen:
912  case AsmToken::Minus:
913  case AsmToken::Plus:
914  case AsmToken::Integer:
915  case AsmToken::String:
916  break;
917  }
918 
919  const MCExpr *IdVal;
920  SMLoc S = getLoc();
921  if (getParser().parseExpression(IdVal)) {
922  Error(getLoc(), "unknown expression");
923  return MatchOperand_ParseFail;
924  }
925 
926  SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
927  Operands.push_back(CSKYOperand::createImm(IdVal, S, E));
928  return MatchOperand_Success;
929 }
930 
931 /// Looks at a token type and creates the relevant operand from this
932 /// information, adding to Operands. If operand was parsed, returns false, else
933 /// true.
934 bool CSKYAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
935  // Check if the current operand has a custom associated parser, if so, try to
936  // custom parse the operand, or fallback to the general approach.
938  MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true);
939  if (Result == MatchOperand_Success)
940  return false;
941  if (Result == MatchOperand_ParseFail)
942  return true;
943 
944  // Attempt to parse token as register
945  auto Res = parseRegister(Operands);
946  if (Res == MatchOperand_Success)
947  return false;
948  else if (Res == MatchOperand_ParseFail)
949  return true;
950 
951  // Attempt to parse token as (register, imm)
952  if (getLexer().is(AsmToken::LParen)) {
953  Res = parseBaseRegImm(Operands);
954  if (Res == MatchOperand_Success)
955  return false;
956  else if (Res == MatchOperand_ParseFail)
957  return true;
958  }
959 
960  Res = parseImmediate(Operands);
961  if (Res == MatchOperand_Success)
962  return false;
963  else if (Res == MatchOperand_ParseFail)
964  return true;
965 
966  // Finally we have exhausted all options and must declare defeat.
967  Error(getLoc(), "unknown operand");
968  return true;
969 }
970 
971 OperandMatchResultTy CSKYAsmParser::parseCSKYSymbol(OperandVector &Operands) {
972  SMLoc S = getLoc();
973  SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
974  const MCExpr *Res;
975 
976  if (getLexer().getKind() != AsmToken::Identifier)
977  return MatchOperand_NoMatch;
978 
980  AsmToken Tok = getLexer().getTok();
981 
982  if (getParser().parseIdentifier(Identifier)) {
983  Error(getLoc(), "unknown identifier");
984  return MatchOperand_ParseFail;
985  }
986 
988  if (Identifier.consume_back("@GOT"))
990  else if (Identifier.consume_back("@GOTOFF"))
992  else if (Identifier.consume_back("@PLT"))
994  else if (Identifier.consume_back("@GOTPC"))
996  else if (Identifier.consume_back("@TLSGD32"))
998  else if (Identifier.consume_back("@GOTTPOFF"))
1000  else if (Identifier.consume_back("@TPOFF"))
1002  else if (Identifier.consume_back("@TLSLDM32"))
1004  else if (Identifier.consume_back("@TLSLDO32"))
1006 
1007  MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier);
1008 
1009  if (!Sym)
1010  Sym = getContext().getOrCreateSymbol(Identifier);
1011 
1012  if (Sym->isVariable()) {
1013  const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false);
1014  if (!isa<MCSymbolRefExpr>(V)) {
1015  getLexer().UnLex(Tok); // Put back if it's not a bare symbol.
1016  Error(getLoc(), "unknown symbol");
1017  return MatchOperand_ParseFail;
1018  }
1019  Res = V;
1020  } else
1021  Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1022 
1023  MCBinaryExpr::Opcode Opcode;
1024  switch (getLexer().getKind()) {
1025  default:
1027  Res = CSKYMCExpr::create(Res, Kind, getContext());
1028 
1029  Operands.push_back(CSKYOperand::createImm(Res, S, E));
1030  return MatchOperand_Success;
1031  case AsmToken::Plus:
1032  Opcode = MCBinaryExpr::Add;
1033  break;
1034  case AsmToken::Minus:
1035  Opcode = MCBinaryExpr::Sub;
1036  break;
1037  }
1038 
1039  getLexer().Lex(); // eat + or -
1040 
1041  const MCExpr *Expr;
1042  if (getParser().parseExpression(Expr)) {
1043  Error(getLoc(), "unknown expression");
1044  return MatchOperand_ParseFail;
1045  }
1046  Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext());
1047  Operands.push_back(CSKYOperand::createImm(Res, S, E));
1048  return MatchOperand_Success;
1049 }
1050 
1051 OperandMatchResultTy CSKYAsmParser::parseDataSymbol(OperandVector &Operands) {
1052  SMLoc S = getLoc();
1053  SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1054  const MCExpr *Res;
1055 
1056  if (getLexer().getKind() != AsmToken::LBrac)
1057  return MatchOperand_NoMatch;
1058 
1059  getLexer().Lex(); // Eat '['.
1060 
1061  if (getLexer().getKind() != AsmToken::Identifier) {
1062  const MCExpr *Expr;
1063  if (getParser().parseExpression(Expr)) {
1064  Error(getLoc(), "unknown expression");
1065  return MatchOperand_ParseFail;
1066  }
1067 
1068  if (getLexer().getKind() != AsmToken::RBrac) {
1069  Error(getLoc(), "expected ]");
1070  return MatchOperand_ParseFail;
1071  }
1072 
1073  getLexer().Lex(); // Eat ']'.
1074 
1075  Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E));
1076  return MatchOperand_Success;
1077  }
1078 
1079  AsmToken Tok = getLexer().getTok();
1081 
1082  if (getParser().parseIdentifier(Identifier)) {
1083  Error(getLoc(), "unknown identifier " + Identifier);
1084  return MatchOperand_ParseFail;
1085  }
1086 
1088  if (Identifier.consume_back("@GOT"))
1090  else if (Identifier.consume_back("@PLT"))
1092 
1093  MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier);
1094 
1095  if (!Sym)
1096  Sym = getContext().getOrCreateSymbol(Identifier);
1097 
1098  if (Sym->isVariable()) {
1099  const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false);
1100  if (!isa<MCSymbolRefExpr>(V)) {
1101  getLexer().UnLex(Tok); // Put back if it's not a bare symbol.
1102  Error(getLoc(), "unknown symbol");
1103  return MatchOperand_ParseFail;
1104  }
1105  Res = V;
1106  } else {
1107  Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1108  }
1109 
1110  MCBinaryExpr::Opcode Opcode;
1111  switch (getLexer().getKind()) {
1112  default:
1113  Error(getLoc(), "unknown symbol");
1114  return MatchOperand_ParseFail;
1115  case AsmToken::RBrac:
1116 
1117  getLexer().Lex(); // Eat ']'.
1118 
1120  Res = CSKYMCExpr::create(Res, Kind, getContext());
1121 
1122  Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));
1123  return MatchOperand_Success;
1124  case AsmToken::Plus:
1125  Opcode = MCBinaryExpr::Add;
1126  break;
1127  case AsmToken::Minus:
1128  Opcode = MCBinaryExpr::Sub;
1129  break;
1130  }
1131 
1132  getLexer().Lex(); // eat + or -
1133 
1134  const MCExpr *Expr;
1135  if (getParser().parseExpression(Expr)) {
1136  Error(getLoc(), "unknown expression");
1137  return MatchOperand_ParseFail;
1138  }
1139 
1140  if (getLexer().getKind() != AsmToken::RBrac) {
1141  Error(getLoc(), "expected ']'");
1142  return MatchOperand_ParseFail;
1143  }
1144 
1145  getLexer().Lex(); // Eat ']'.
1146 
1147  Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext());
1148  Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));
1149  return MatchOperand_Success;
1150 }
1151 
1153 CSKYAsmParser::parseConstpoolSymbol(OperandVector &Operands) {
1154  SMLoc S = getLoc();
1155  SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1156  const MCExpr *Res;
1157 
1158  if (getLexer().getKind() != AsmToken::LBrac)
1159  return MatchOperand_NoMatch;
1160 
1161  getLexer().Lex(); // Eat '['.
1162 
1163  if (getLexer().getKind() != AsmToken::Identifier) {
1164  const MCExpr *Expr;
1165  if (getParser().parseExpression(Expr)) {
1166  Error(getLoc(), "unknown expression");
1167  return MatchOperand_ParseFail;
1168  }
1169 
1170  if (getLexer().getKind() != AsmToken::RBrac) {
1171  Error(getLoc(), "expected ']'");
1172  return MatchOperand_ParseFail;
1173  }
1174 
1175  getLexer().Lex(); // Eat ']'.
1176 
1177  Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E));
1178  return MatchOperand_Success;
1179  }
1180 
1181  AsmToken Tok = getLexer().getTok();
1183 
1184  if (getParser().parseIdentifier(Identifier)) {
1185  Error(getLoc(), "unknown identifier");
1186  return MatchOperand_ParseFail;
1187  }
1188 
1189  MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier);
1190 
1191  if (!Sym)
1192  Sym = getContext().getOrCreateSymbol(Identifier);
1193 
1194  if (Sym->isVariable()) {
1195  const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false);
1196  if (!isa<MCSymbolRefExpr>(V)) {
1197  getLexer().UnLex(Tok); // Put back if it's not a bare symbol.
1198  Error(getLoc(), "unknown symbol");
1199  return MatchOperand_ParseFail;
1200  }
1201  Res = V;
1202  } else {
1203  Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1204  }
1205 
1206  MCBinaryExpr::Opcode Opcode;
1207  switch (getLexer().getKind()) {
1208  default:
1209  Error(getLoc(), "unknown symbol");
1210  return MatchOperand_ParseFail;
1211  case AsmToken::RBrac:
1212 
1213  getLexer().Lex(); // Eat ']'.
1214 
1215  Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));
1216  return MatchOperand_Success;
1217  case AsmToken::Plus:
1218  Opcode = MCBinaryExpr::Add;
1219  break;
1220  case AsmToken::Minus:
1221  Opcode = MCBinaryExpr::Sub;
1222  break;
1223  }
1224 
1225  getLexer().Lex(); // eat + or -
1226 
1227  const MCExpr *Expr;
1228  if (getParser().parseExpression(Expr)) {
1229  Error(getLoc(), "unknown expression");
1230  return MatchOperand_ParseFail;
1231  }
1232 
1233  if (getLexer().getKind() != AsmToken::RBrac) {
1234  Error(getLoc(), "expected ']'");
1235  return MatchOperand_ParseFail;
1236  }
1237 
1238  getLexer().Lex(); // Eat ']'.
1239 
1240  Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext());
1241  Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));
1242  return MatchOperand_Success;
1243 }
1244 
1245 OperandMatchResultTy CSKYAsmParser::parsePSRFlag(OperandVector &Operands) {
1246  SMLoc S = getLoc();
1247  SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1248 
1249  unsigned Flag = 0;
1250 
1251  while (getLexer().isNot(AsmToken::EndOfStatement)) {
1253  if (getParser().parseIdentifier(Identifier)) {
1254  Error(getLoc(), "unknown identifier " + Identifier);
1255  return MatchOperand_ParseFail;
1256  }
1257 
1258  if (Identifier == "sie")
1259  Flag = (1 << 4) | Flag;
1260  else if (Identifier == "ee")
1261  Flag = (1 << 3) | Flag;
1262  else if (Identifier == "ie")
1263  Flag = (1 << 2) | Flag;
1264  else if (Identifier == "fe")
1265  Flag = (1 << 1) | Flag;
1266  else if (Identifier == "af")
1267  Flag = (1 << 0) | Flag;
1268  else {
1269  Error(getLoc(), "expected " + Identifier);
1270  return MatchOperand_ParseFail;
1271  }
1272 
1273  if (getLexer().is(AsmToken::EndOfStatement))
1274  break;
1275 
1276  if (getLexer().is(AsmToken::Comma)) {
1277  getLexer().Lex(); // eat ','
1278  } else {
1279  Error(getLoc(), "expected ,");
1280  return MatchOperand_ParseFail;
1281  }
1282  }
1283 
1284  Operands.push_back(
1285  CSKYOperand::createImm(MCConstantExpr::create(Flag, getContext()), S, E));
1286  return MatchOperand_Success;
1287 }
1288 
1289 OperandMatchResultTy CSKYAsmParser::parseRegSeq(OperandVector &Operands) {
1290  SMLoc S = getLoc();
1291 
1292  if (parseRegister(Operands) != MatchOperand_Success)
1293  return MatchOperand_NoMatch;
1294 
1295  auto Ry = Operands.back()->getReg();
1296  Operands.pop_back();
1297 
1298  if (getLexer().isNot(AsmToken::Minus)) {
1299  Error(getLoc(), "expected '-'");
1300  return MatchOperand_ParseFail;
1301  }
1302 
1303  getLexer().Lex(); // eat '-'
1304 
1305  if (parseRegister(Operands) != MatchOperand_Success) {
1306  Error(getLoc(), "invalid register");
1307  return MatchOperand_ParseFail;
1308  }
1309 
1310  auto Rz = Operands.back()->getReg();
1311  Operands.pop_back();
1312 
1313  Operands.push_back(CSKYOperand::createRegSeq(Ry, Rz, S));
1314  return MatchOperand_Success;
1315 }
1316 
1317 OperandMatchResultTy CSKYAsmParser::parseRegList(OperandVector &Operands) {
1318  SMLoc S = getLoc();
1319 
1320  SmallVector<unsigned, 4> reglist;
1321 
1322  while (true) {
1323 
1324  if (parseRegister(Operands) != MatchOperand_Success) {
1325  Error(getLoc(), "invalid register");
1326  return MatchOperand_ParseFail;
1327  }
1328 
1329  auto Ry = Operands.back()->getReg();
1330  Operands.pop_back();
1331 
1332  if (getLexer().is(AsmToken::Minus)) {
1333  getLexer().Lex(); // eat '-'
1334 
1335  if (parseRegister(Operands) != MatchOperand_Success) {
1336  Error(getLoc(), "invalid register");
1337  return MatchOperand_ParseFail;
1338  }
1339 
1340  auto Rz = Operands.back()->getReg();
1341  Operands.pop_back();
1342 
1343  reglist.push_back(Ry);
1344  reglist.push_back(Rz);
1345 
1346  if (getLexer().is(AsmToken::Comma))
1347  getLexer().Lex(); // eat ','
1348  else if (getLexer().is(AsmToken::EndOfStatement))
1349  break;
1350 
1351  } else if (getLexer().is(AsmToken::Comma)) {
1352  reglist.push_back(Ry);
1353  reglist.push_back(Ry);
1354 
1355  getLexer().Lex(); // eat ','
1356  } else if (getLexer().is(AsmToken::EndOfStatement)) {
1357  reglist.push_back(Ry);
1358  reglist.push_back(Ry);
1359  break;
1360  } else {
1361  Error(getLoc(), "invalid register list");
1362  return MatchOperand_ParseFail;
1363  }
1364  }
1365 
1366  Operands.push_back(CSKYOperand::createRegList(reglist, S));
1367  return MatchOperand_Success;
1368 }
1369 
1370 bool CSKYAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
1371  SMLoc NameLoc, OperandVector &Operands) {
1372  // First operand is token for instruction.
1373  Operands.push_back(CSKYOperand::createToken(Name, NameLoc));
1374 
1375  // If there are no more operands, then finish.
1376  if (getLexer().is(AsmToken::EndOfStatement))
1377  return false;
1378 
1379  // Parse first operand.
1380  if (parseOperand(Operands, Name))
1381  return true;
1382 
1383  // Parse until end of statement, consuming commas between operands.
1384  while (getLexer().is(AsmToken::Comma)) {
1385  // Consume comma token.
1386  getLexer().Lex();
1387 
1388  // Parse next operand.
1389  if (parseOperand(Operands, Name))
1390  return true;
1391  }
1392 
1393  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1394  SMLoc Loc = getLexer().getLoc();
1395  getParser().eatToEndOfStatement();
1396  return Error(Loc, "unexpected token");
1397  }
1398 
1399  getParser().Lex(); // Consume the EndOfStatement.
1400  return false;
1401 }
1402 
1403 OperandMatchResultTy CSKYAsmParser::tryParseRegister(unsigned &RegNo,
1404  SMLoc &StartLoc,
1405  SMLoc &EndLoc) {
1406  const AsmToken &Tok = getParser().getTok();
1407  StartLoc = Tok.getLoc();
1408  EndLoc = Tok.getEndLoc();
1409 
1410  StringRef Name = getLexer().getTok().getIdentifier();
1411 
1412  if (matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name))
1413  return MatchOperand_NoMatch;
1414 
1415  getParser().Lex(); // Eat identifier token.
1416  return MatchOperand_Success;
1417 }
1418 
1419 bool CSKYAsmParser::ParseDirective(AsmToken DirectiveID) { return true; }
1420 
1423 }
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 file implements support for optimizing divisions by a constant.
Definition: AllocatorList.h:23
Reg
unsigned Reg
Definition: MachineSink.cpp:1566
llvm::MCSymbol
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
llvm::CSKYMCExpr::VK_CSKY_GOTPC
@ VK_CSKY_GOTPC
Definition: CSKYMCExpr.h:27
llvm::HexPrintStyle::Upper
@ Upper
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:147
llvm::MCParsedAsmOperand
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
Definition: MCParsedAsmOperand.h:24
llvm::MCBinaryExpr::Opcode
Opcode
Definition: MCExpr.h:482
T
llvm::MCOperand::createImm
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:141
llvm::AsmToken::LBrac
@ LBrac
Definition: MCAsmMacro.h:48
llvm::AsmToken::EndOfStatement
@ EndOfStatement
Definition: MCAsmMacro.h:42
llvm::MCConstantExpr::create
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition: MCExpr.cpp:194
MCSectionELF.h
llvm::SmallVector< unsigned, 4 >
MCParsedAsmOperand.h
llvm::MCBinaryExpr::Add
@ Add
Addition.
Definition: MCExpr.h:483
R4
#define R4(n)
to
Should compile to
Definition: README.txt:449
llvm::AsmToken::Integer
@ Integer
Definition: MCAsmMacro.h:32
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:20
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
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
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
llvm::MCStreamer
Streaming machine code generation interface.
Definition: MCStreamer.h:199
llvm::RegisterMCAsmParser
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
Definition: TargetRegistry.h:1317
llvm::MatchOperand_Success
@ MatchOperand_Success
Definition: MCTargetAsmParser.h:122
llvm::SMLoc
Represents a location in source code.
Definition: SMLoc.h:23
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.
MCContext.h
llvm::MCOperand::getImm
int64_t getImm() const
Definition: MCInst.h:80
llvm::ms_demangle::QualifierMangleMode::Result
@ Result
MCInst.h
llvm::MCSymbol::getVariableValue
const MCExpr * getVariableValue(bool SetUsed=true) const
getVariableValue - Get the value for variable symbols.
Definition: MCSymbol.h:298
MCSubtargetInfo.h
llvm::MCSubtargetInfo::getFeatureBits
const FeatureBitset & getFeatureBits() const
Definition: MCSubtargetInfo.h:111
llvm::MCID::Flag
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Definition: MCInstrDesc.h:146
Options
const char LLVMTargetMachineRef LLVMPassBuilderOptionsRef Options
Definition: PassBuilderBindings.cpp:48
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
getSubtargetFeatureName
static const char * getSubtargetFeatureName(uint64_t Val)
Info
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
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:2804
Register
Promote Memory to Register
Definition: Mem2Reg.cpp:110
llvm::CSKYMCExpr::VK_CSKY_TLSLDM
@ VK_CSKY_TLSLDM
Definition: CSKYMCExpr.h:35
llvm::lltok::Kind
Kind
Definition: LLToken.h:18
X
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
llvm::MCInst::addOperand
void addOperand(const MCOperand Op)
Definition: MCInst.h:210
Operands
mir Rename Register Operands
Definition: MIRNamerPass.cpp:78
MCAsmLexer.h
llvm::ParseInstructionInfo
Definition: MCTargetAsmParser.h:113
uint64_t
LLVM_EXTERNAL_VISIBILITY
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:132
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:1087
llvm::MatchOperand_ParseFail
@ MatchOperand_ParseFail
Definition: MCTargetAsmParser.h:124
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:200
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())
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:349
llvm::MCTargetOptions
Definition: MCTargetOptions.h:36
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:1421
llvm::MatchOperand_NoMatch
@ MatchOperand_NoMatch
Definition: MCTargetAsmParser.h:123
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::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:134
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
llvm::AsmToken::LessLess
@ LessLess
Definition: MCAsmMacro.h:53
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::OperandMatchResultTy
OperandMatchResultTy
Definition: MCTargetAsmParser.h:121
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:83
llvm::MCInstrInfo
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:25
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
llvm::AsmToken::Identifier
@ Identifier
Definition: MCAsmMacro.h:28
llvm::CSKYMCExpr::VK_CSKY_TLSGD
@ VK_CSKY_TLSGD
Definition: CSKYMCExpr.h:33
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:324
llvm::MCBinaryExpr::Sub
@ Sub
Subtraction.
Definition: MCExpr.h:505
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
llvm::AArch64CC::LS
@ LS
Definition: AArch64BaseInfo.h:264
Casting.h
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:309
parseImmediate
bool parseImmediate(MCInst &MI, uint64_t &Size, ArrayRef< uint8_t > Bytes)
Definition: WebAssemblyDisassembler.cpp:109
llvm::object::Identifier
@ Identifier
Definition: COFFModuleDefinition.cpp:36
llvm::MCSymbolRefExpr::create
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:385
StringSwitch.h
matchRegisterNameHelper
static bool matchRegisterNameHelper(const MCSubtargetInfo &STI, MCRegister &RegNo, StringRef Name)
Definition: CSKYAsmParser.cpp:802
CSKYMCExpr.h
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:123
CSKYTargetInfo.h
llvm::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:43
llvm::SMLoc::getFromPointer
static SMLoc getFromPointer(const char *Ptr)
Definition: SMLoc.h:36
RegName
#define RegName(no)
Register.h
llvm::MCSymbolRefExpr::VK_None
@ VK_None
Definition: MCExpr.h:195
llvm::AsmToken::String
@ String
Definition: MCAsmMacro.h:29
llvm::AsmToken::getLoc
SMLoc getLoc() const
Definition: MCAsmLexer.cpp:27
llvm::AsmToken::getEndLoc
SMLoc getEndLoc() const
Definition: MCAsmLexer.cpp:31
TargetRegistry.h
MCExpr.h
llvm::MCSubtargetInfo
Generic base class for all target subtargets.
Definition: MCSubtargetInfo.h:75
llvm::FeatureBitset::any
bool any() const
Definition: SubtargetFeature.h:94
llvm::MCExpr
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
Debug.h
Other
Optional< std::vector< StOtherPiece > > Other
Definition: ELFYAML.cpp:1184
getReg
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
Definition: MipsDisassembler.cpp:572
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