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