40#define DEBUG_TYPE "csky-asm-parser" 
   43#define GEN_COMPRESS_INSTR 
   44#include "CSKYGenCompressInstEmitter.inc" 
   47          "Number of C-SKY Compressed instructions emitted");
 
   52                         cl::desc(
"Enable C-SKY asm compressed instruction"));
 
   62                                      unsigned Kind) 
override;
 
   68  SMLoc getLoc()
 const { 
return getParser().getTok().getLoc(); }
 
   70  bool matchAndEmitInstruction(SMLoc IDLoc, 
unsigned &Opcode,
 
   73                               bool MatchingInlineAsm) 
override;
 
   75  bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc) 
override;
 
   77  bool parseInstruction(ParseInstructionInfo &
Info, StringRef Name,
 
   80  ParseStatus parseDirective(AsmToken DirectiveID) 
override;
 
   84  void emitToStreamer(MCStreamer &S, 
const MCInst &Inst);
 
   86  ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
 
   87                               SMLoc &EndLoc) 
override;
 
   89  bool processInstruction(MCInst &Inst, SMLoc IDLoc, 
OperandVector &Operands,
 
   91  bool processLRW(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
 
   92  bool processJSRI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
 
   93  bool processJMPI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
 
   95  CSKYTargetStreamer &getTargetStreamer() {
 
   96    assert(getParser().getStreamer().getTargetStreamer() &&
 
   97           "do not have a target streamer");
 
   98    MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
 
   99    return static_cast<CSKYTargetStreamer &
>(TS);
 
  103#define GET_ASSEMBLER_HEADER 
  104#include "CSKYGenAsmMatcher.inc" 
  118  bool parseDirectiveAttribute();
 
  121  enum CSKYMatchResultTy {
 
  122    Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
 
  123    Match_RequiresSameSrcAndDst,
 
  124    Match_InvalidRegOutOfRange,
 
  125#define GET_OPERAND_DIAGNOSTIC_TYPES 
  126#include "CSKYGenAsmMatcher.inc" 
  127#undef GET_OPERAND_DIAGNOSTIC_TYPES 
  130  CSKYAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
 
  131                const MCInstrInfo &MII, 
const MCTargetOptions &
Options)
 
  132      : MCTargetAsmParser(
Options, STI, MII) {
 
  139    setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
 
  140    getTargetStreamer().emitTargetAttributes(STI);
 
  169    MCRegister RegNumFrom;
 
  174    MCRegister List1From;
 
  176    MCRegister List2From;
 
  178    MCRegister List3From;
 
  180    MCRegister List4From;
 
  184  SMLoc StartLoc, EndLoc;
 
  194  CSKYOperand(KindTy K) : MCParsedAsmOperand(), Kind(
K) {}
 
  197  CSKYOperand(
const CSKYOperand &o) : MCParsedAsmOperand() {
 
  199    StartLoc = 
o.StartLoc;
 
  223  bool isToken()
 const override { 
return Kind == Token; }
 
  224  bool isReg()
 const override { 
return Kind == Register; }
 
  225  bool isImm()
 const override { 
return Kind == Immediate; }
 
  226  bool isRegisterSeq()
 const { 
return Kind == RegisterSeq; }
 
  227  bool isRegisterList()
 const { 
return Kind == RegisterList; }
 
  228  bool isConstPoolOp()
 const { 
return Kind == CPOP; }
 
  230  bool isMem()
 const override { 
return false; }
 
  232  static bool evaluateConstantImm(
const MCExpr *Expr, int64_t &Imm) {
 
  234      Imm = 
CE->getValue();
 
  241  template <
unsigned num, 
unsigned shift = 0> 
bool isUImm()
 const {
 
  246    bool IsConstantImm = evaluateConstantImm(
getImm(), Imm);
 
  250  template <
unsigned num> 
bool isOImm()
 const {
 
  255    bool IsConstantImm = evaluateConstantImm(
getImm(), Imm);
 
  259  template <
unsigned num, 
unsigned shift = 0> 
bool isSImm()
 const {
 
  264    bool IsConstantImm = evaluateConstantImm(
getImm(), Imm);
 
  268  bool isUImm1()
 const { 
return isUImm<1>(); }
 
  269  bool isUImm2()
 const { 
return isUImm<2>(); }
 
  270  bool isUImm3()
 const { 
return isUImm<3>(); }
 
  271  bool isUImm4()
 const { 
return isUImm<4>(); }
 
  272  bool isUImm5()
 const { 
return isUImm<5>(); }
 
  273  bool isUImm6()
 const { 
return isUImm<6>(); }
 
  274  bool isUImm7()
 const { 
return isUImm<7>(); }
 
  275  bool isUImm8()
 const { 
return isUImm<8>(); }
 
  276  bool isUImm12()
 const { 
return isUImm<12>(); }
 
  277  bool isUImm16()
 const { 
return isUImm<16>(); }
 
  278  bool isUImm20()
 const { 
return isUImm<20>(); }
 
  279  bool isUImm24()
 const { 
return isUImm<24>(); }
 
  281  bool isOImm3()
 const { 
return isOImm<3>(); }
 
  282  bool isOImm4()
 const { 
return isOImm<4>(); }
 
  283  bool isOImm5()
 const { 
return isOImm<5>(); }
 
  284  bool isOImm6()
 const { 
return isOImm<6>(); }
 
  285  bool isOImm8()
 const { 
return isOImm<8>(); }
 
  286  bool isOImm12()
 const { 
return isOImm<12>(); }
 
  287  bool isOImm16()
 const { 
return isOImm<16>(); }
 
  289  bool isSImm8()
 const { 
return isSImm<8>(); }
 
  291  bool isUImm5Shift1() { 
return isUImm<5, 1>(); }
 
  292  bool isUImm5Shift2() { 
return isUImm<5, 2>(); }
 
  293  bool isUImm7Shift1() { 
return isUImm<7, 1>(); }
 
  294  bool isUImm7Shift2() { 
return isUImm<7, 2>(); }
 
  295  bool isUImm7Shift3() { 
return isUImm<7, 3>(); }
 
  296  bool isUImm8Shift2() { 
return isUImm<8, 2>(); }
 
  297  bool isUImm8Shift3() { 
return isUImm<8, 3>(); }
 
  298  bool isUImm8Shift8() { 
return isUImm<8, 8>(); }
 
  299  bool isUImm8Shift16() { 
return isUImm<8, 16>(); }
 
  300  bool isUImm8Shift24() { 
return isUImm<8, 24>(); }
 
  301  bool isUImm12Shift1() { 
return isUImm<12, 1>(); }
 
  302  bool isUImm12Shift2() { 
return isUImm<12, 2>(); }
 
  303  bool isUImm16Shift8() { 
return isUImm<16, 8>(); }
 
  304  bool isUImm16Shift16() { 
return isUImm<16, 16>(); }
 
  305  bool isUImm24Shift8() { 
return isUImm<24, 8>(); }
 
  307  bool isSImm16Shift1() { 
return isSImm<16, 1>(); }
 
  309  bool isCSKYSymbol()
 const { 
return isImm(); }
 
  311  bool isConstpool()
 const { 
return isConstPoolOp(); }
 
  312  bool isDataSymbol()
 const { 
return isConstPoolOp(); }
 
  314  bool isPSRFlag()
 const {
 
  317    if (!isImm() || !evaluateConstantImm(
getImm(), Imm))
 
  323  template <
unsigned MIN, 
unsigned MAX> 
bool isRegSeqTemplate()
 const {
 
  324    if (!isRegisterSeq())
 
  327    std::pair<unsigned, unsigned> regSeq = getRegSeq();
 
  329    return MIN <= regSeq.first && regSeq.first <= regSeq.second &&
 
  330           regSeq.second <= 
MAX;
 
  333  bool isRegSeq()
 const { 
return isRegSeqTemplate<CSKY::R0, CSKY::R31>(); }
 
  335  bool isRegSeqV1()
 const {
 
  336    return isRegSeqTemplate<CSKY::F0_32, CSKY::F15_32>();
 
  339  bool isRegSeqV2()
 const {
 
  340    return isRegSeqTemplate<CSKY::F0_32, CSKY::F31_32>();
 
  343  static bool isLegalRegList(
unsigned from, 
unsigned to) {
 
  344    if (from == 0 && to == 0)
 
  348      if (from != CSKY::R4 && from != CSKY::R15 && from != CSKY::R16 &&
 
  354      if (from != CSKY::R4 && from != CSKY::R16)
 
  357      if (from == CSKY::R4 && to > CSKY::R4 && to < CSKY::R12)
 
  359      else if (from == CSKY::R16 && to > CSKY::R16 && to < CSKY::R18)
 
  366  bool isRegList()
 const {
 
  367    if (!isRegisterList())
 
  370    auto regList = getRegList();
 
  372    if (!isLegalRegList(regList.List1From, regList.List1To))
 
  374    if (!isLegalRegList(regList.List2From, regList.List2To))
 
  376    if (!isLegalRegList(regList.List3From, regList.List3To))
 
  378    if (!isLegalRegList(regList.List4From, regList.List4To))
 
  389    bool IsConstantImm = evaluateConstantImm(
getImm(), Imm);
 
  393    int uimm4 = 
Imm & 0xf;
 
  399  SMLoc getStartLoc()
 const override { 
return StartLoc; }
 
  401  SMLoc getEndLoc()
 const override { 
return EndLoc; }
 
  403  MCRegister 
getReg()
 const override {
 
  404    assert(Kind == Register && 
"Invalid type access!");
 
  408  std::pair<MCRegister, MCRegister> getRegSeq()
 const {
 
  409    assert(Kind == RegisterSeq && 
"Invalid type access!");
 
  410    return {RegSeq.RegNumFrom, RegSeq.RegNumTo};
 
  413  RegListOp getRegList()
 const {
 
  414    assert(Kind == RegisterList && 
"Invalid type access!");
 
  418  const MCExpr *
getImm()
 const {
 
  419    assert(Kind == Immediate && 
"Invalid type access!");
 
  423  const MCExpr *getConstpoolOp()
 const {
 
  424    assert(Kind == CPOP && 
"Invalid type access!");
 
  429    assert(Kind == Token && 
"Invalid type access!");
 
  433  void print(raw_ostream &OS, 
const MCAsmInfo &MAI)
 const override {
 
  448    case KindTy::Register:
 
  452      OS << 
"<register-seq ";
 
  453      OS << 
RegName(getRegSeq().first) << 
"-" << 
RegName(getRegSeq().second)
 
  457      OS << 
"<register-list ";
 
  458      OS << 
RegName(getRegList().List1From) << 
"-" 
  459         << 
RegName(getRegList().List1To) << 
",";
 
  460      OS << 
RegName(getRegList().List2From) << 
"-" 
  461         << 
RegName(getRegList().List2To) << 
",";
 
  462      OS << 
RegName(getRegList().List3From) << 
"-" 
  463         << 
RegName(getRegList().List3To) << 
",";
 
  464      OS << 
RegName(getRegList().List4From) << 
"-" 
  465         << 
RegName(getRegList().List4To);
 
  473  static std::unique_ptr<CSKYOperand> createToken(StringRef Str, SMLoc S) {
 
  474    auto Op = std::make_unique<CSKYOperand>(Token);
 
  481  static std::unique_ptr<CSKYOperand> createReg(MCRegister RegNo, SMLoc S,
 
  483    auto Op = std::make_unique<CSKYOperand>(Register);
 
  484    Op->Reg.RegNum = RegNo;
 
  490  static std::unique_ptr<CSKYOperand>
 
  491  createRegSeq(MCRegister RegNoFrom, MCRegister RegNoTo, SMLoc S) {
 
  492    auto Op = std::make_unique<CSKYOperand>(RegisterSeq);
 
  493    Op->RegSeq.RegNumFrom = RegNoFrom;
 
  494    Op->RegSeq.RegNumTo = RegNoTo;
 
  500  static std::unique_ptr<CSKYOperand>
 
  502    auto Op = std::make_unique<CSKYOperand>(RegisterList);
 
  503    Op->RegList.List1From = 0;
 
  504    Op->RegList.List1To = 0;
 
  505    Op->RegList.List2From = 0;
 
  506    Op->RegList.List2To = 0;
 
  507    Op->RegList.List3From = 0;
 
  508    Op->RegList.List3To = 0;
 
  509    Op->RegList.List4From = 0;
 
  510    Op->RegList.List4To = 0;
 
  512    for (
unsigned i = 0; i < reglist.
size(); i += 2) {
 
  513      if (
Op->RegList.List1From == 0) {
 
  514        Op->RegList.List1From = reglist[i];
 
  515        Op->RegList.List1To = reglist[i + 1];
 
  516      } 
else if (
Op->RegList.List2From == 0) {
 
  517        Op->RegList.List2From = reglist[i];
 
  518        Op->RegList.List2To = reglist[i + 1];
 
  519      } 
else if (
Op->RegList.List3From == 0) {
 
  520        Op->RegList.List3From = reglist[i];
 
  521        Op->RegList.List3To = reglist[i + 1];
 
  522      } 
else if (
Op->RegList.List4From == 0) {
 
  523        Op->RegList.List4From = reglist[i];
 
  524        Op->RegList.List4To = reglist[i + 1];
 
  535  static std::unique_ptr<CSKYOperand> createImm(
const MCExpr *Val, SMLoc S,
 
  537    auto Op = std::make_unique<CSKYOperand>(Immediate);
 
  544  static std::unique_ptr<CSKYOperand> createConstpoolOp(
const MCExpr *Val,
 
  546    auto Op = std::make_unique<CSKYOperand>(CPOP);
 
  553  void addExpr(MCInst &Inst, 
const MCExpr *Expr)
 const {
 
  554    assert(Expr && 
"Expr shouldn't be null!");
 
  562  void addRegOperands(MCInst &Inst, 
unsigned N)
 const {
 
  563    assert(
N == 1 && 
"Invalid number of operands!");
 
  567  void addImmOperands(MCInst &Inst, 
unsigned N)
 const {
 
  568    assert(
N == 1 && 
"Invalid number of operands!");
 
  572  void addConstpoolOperands(MCInst &Inst, 
unsigned N)
 const {
 
  573    assert(
N == 1 && 
"Invalid number of operands!");
 
  577  void addRegSeqOperands(MCInst &Inst, 
unsigned N)
 const {
 
  578    assert(
N == 2 && 
"Invalid number of operands!");
 
  579    auto regSeq = getRegSeq();
 
  585  static unsigned getListValue(
unsigned ListFrom, 
unsigned ListTo) {
 
  586    if (ListFrom == ListTo && ListFrom == CSKY::R15)
 
  588    else if (ListFrom == ListTo && ListFrom == CSKY::R28)
 
  590    else if (ListFrom == CSKY::R4)
 
  591      return ListTo - ListFrom + 1;
 
  592    else if (ListFrom == CSKY::R16)
 
  593      return ((ListTo - ListFrom + 1) << 5);
 
  598  void addRegListOperands(MCInst &Inst, 
unsigned N)
 const {
 
  599    assert(
N == 1 && 
"Invalid number of operands!");
 
  600    auto regList = getRegList();
 
  604    unsigned T = getListValue(regList.List1From, regList.List1To);
 
  608    T = getListValue(regList.List2From, regList.List2To);
 
  612    T = getListValue(regList.List3From, regList.List3To);
 
  616    T = getListValue(regList.List4From, regList.List4To);
 
  623  bool isValidForTie(
const CSKYOperand &
Other)
 const {
 
  624    if (Kind != 
Other.Kind)
 
  632      return Reg.RegNum == 
Other.Reg.RegNum;
 
  638#define GET_REGISTER_MATCHER 
  639#define GET_SUBTARGET_FEATURE_NAME 
  640#define GET_MATCHER_IMPLEMENTATION 
  641#define GET_MNEMONIC_SPELL_CHECKER 
  642#include "CSKYGenAsmMatcher.inc" 
  645  assert(
Reg >= CSKY::F0_32 && 
Reg <= CSKY::F31_32 && 
"Invalid register");
 
  646  return Reg - CSKY::F0_32 + CSKY::F0_64;
 
 
  650                                          unsigned VariantID = 0);
 
  652bool CSKYAsmParser::generateImmOutOfRangeError(
 
  654    const Twine &Msg = 
"immediate must be an integer in the range") {
 
  655  SMLoc ErrorLoc = ((CSKYOperand &)*Operands[
ErrorInfo]).getStartLoc();
 
  659bool CSKYAsmParser::matchAndEmitInstruction(SMLoc IDLoc, 
unsigned &Opcode,
 
  663                                            bool MatchingInlineAsm) {
 
  665  FeatureBitset MissingFeatures;
 
  667  auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
 
  673    return processInstruction(Inst, IDLoc, Operands, Out);
 
  674  case Match_MissingFeature: {
 
  675    assert(MissingFeatures.
any() && 
"Unknown missing features!");
 
  677    std::string Msg = 
"instruction requires the following: ";
 
  678    for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
 
  679      if (MissingFeatures[i]) {
 
  684    return Error(IDLoc, Msg);
 
  686  case Match_MnemonicFail: {
 
  687    FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
 
  688    std::string Suggestion =
 
  690    return Error(IDLoc, 
"unrecognized instruction mnemonic" + Suggestion);
 
  692  case Match_InvalidTiedOperand:
 
  693  case Match_InvalidOperand: {
 
  694    SMLoc ErrorLoc = IDLoc;
 
  695    if (ErrorInfo != ~0U) {
 
  696      if (ErrorInfo >= Operands.
size())
 
  697        return Error(ErrorLoc, 
"too few operands for instruction");
 
  699      ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
 
  700      if (ErrorLoc == SMLoc())
 
  703    return Error(ErrorLoc, 
"invalid operand for instruction");
 
  710  if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
 
  711    SMLoc ErrorLoc = IDLoc;
 
  712    if (ErrorInfo != ~0U && ErrorInfo >= Operands.
size())
 
  713      return Error(ErrorLoc, 
"too few operands for instruction");
 
  719  case Match_InvalidSImm8:
 
  720    return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 7),
 
  722  case Match_InvalidOImm3:
 
  723    return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 3));
 
  724  case Match_InvalidOImm4:
 
  725    return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 4));
 
  726  case Match_InvalidOImm5:
 
  727    return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5));
 
  728  case Match_InvalidOImm6:
 
  729    return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6));
 
  730  case Match_InvalidOImm8:
 
  731    return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 8));
 
  732  case Match_InvalidOImm12:
 
  733    return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 12));
 
  734  case Match_InvalidOImm16:
 
  735    return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 16));
 
  736  case Match_InvalidUImm1:
 
  737    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 1) - 1);
 
  738  case Match_InvalidUImm2:
 
  739    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1);
 
  740  case Match_InvalidUImm3:
 
  741    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1);
 
  742  case Match_InvalidUImm4:
 
  743    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);
 
  744  case Match_InvalidUImm5:
 
  745    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
 
  746  case Match_InvalidUImm6:
 
  747    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
 
  748  case Match_InvalidUImm7:
 
  749    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1);
 
  750  case Match_InvalidUImm8:
 
  751    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 8) - 1);
 
  752  case Match_InvalidUImm12:
 
  753    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1);
 
  754  case Match_InvalidUImm16:
 
  755    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 16) - 1);
 
  756  case Match_InvalidUImm5Shift1:
 
  757    return generateImmOutOfRangeError(
 
  758        Operands, ErrorInfo, 0, (1 << 5) - 2,
 
  759        "immediate must be a multiple of 2 bytes in the range");
 
  760  case Match_InvalidUImm12Shift1:
 
  761    return generateImmOutOfRangeError(
 
  762        Operands, ErrorInfo, 0, (1 << 12) - 2,
 
  763        "immediate must be a multiple of 2 bytes in the range");
 
  764  case Match_InvalidUImm5Shift2:
 
  765    return generateImmOutOfRangeError(
 
  766        Operands, ErrorInfo, 0, (1 << 5) - 4,
 
  767        "immediate must be a multiple of 4 bytes in the range");
 
  768  case Match_InvalidUImm7Shift1:
 
  769    return generateImmOutOfRangeError(
 
  770        Operands, ErrorInfo, 0, (1 << 7) - 2,
 
  771        "immediate must be a multiple of 2 bytes in the range");
 
  772  case Match_InvalidUImm7Shift2:
 
  773    return generateImmOutOfRangeError(
 
  774        Operands, ErrorInfo, 0, (1 << 7) - 4,
 
  775        "immediate must be a multiple of 4 bytes in the range");
 
  776  case Match_InvalidUImm8Shift2:
 
  777    return generateImmOutOfRangeError(
 
  778        Operands, ErrorInfo, 0, (1 << 8) - 4,
 
  779        "immediate must be a multiple of 4 bytes in the range");
 
  780  case Match_InvalidUImm8Shift3:
 
  781    return generateImmOutOfRangeError(
 
  782        Operands, ErrorInfo, 0, (1 << 8) - 8,
 
  783        "immediate must be a multiple of 8 bytes in the range");
 
  784  case Match_InvalidUImm8Shift8:
 
  785    return generateImmOutOfRangeError(
 
  786        Operands, ErrorInfo, 0, (1 << 8) - 256,
 
  787        "immediate must be a multiple of 256 bytes in the range");
 
  788  case Match_InvalidUImm12Shift2:
 
  789    return generateImmOutOfRangeError(
 
  790        Operands, ErrorInfo, 0, (1 << 12) - 4,
 
  791        "immediate must be a multiple of 4 bytes in the range");
 
  792  case Match_InvalidCSKYSymbol: {
 
  793    SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
 
  794    return Error(ErrorLoc, 
"operand must be a symbol name");
 
  796  case Match_InvalidConstpool: {
 
  797    SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
 
  798    return Error(ErrorLoc, 
"operand must be a constpool symbol name");
 
  800  case Match_InvalidPSRFlag: {
 
  801    SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
 
  802    return Error(ErrorLoc, 
"psrset operand is not valid");
 
  804  case Match_InvalidRegSeq: {
 
  805    SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
 
  806    return Error(ErrorLoc, 
"Register sequence is not valid");
 
  808  case Match_InvalidRegOutOfRange: {
 
  809    SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
 
  810    return Error(ErrorLoc, 
"register is out of range");
 
  812  case Match_RequiresSameSrcAndDst: {
 
  813    SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
 
  814    return Error(ErrorLoc, 
"src and dst operand must be same");
 
  816  case Match_InvalidRegList: {
 
  817    SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
 
  818    return Error(ErrorLoc, 
"invalid register list");
 
  825bool CSKYAsmParser::processLRW(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {
 
  830  if (Inst.
getOpcode() == CSKY::PseudoLRW16)
 
  831    Opcode = CSKY::LRW16;
 
  833    Opcode = CSKY::LRW32;
 
  838      Opcode = CSKY::MOVI16;
 
  839    } 
else if (getSTI().hasFeature(CSKY::HasE2) &&
 
  841      Opcode = CSKY::MOVI32;
 
  843      auto *Expr = getTargetStreamer().addConstantPoolEntry(
 
  850    const MCExpr *AdjustExpr = 
nullptr;
 
  851    if (
const auto *CSKYExpr =
 
  861    auto *Expr = getTargetStreamer().addConstantPoolEntry(
 
  873bool CSKYAsmParser::processJSRI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {
 
  877    const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
 
  884    const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
 
  894bool CSKYAsmParser::processJMPI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {
 
  898    const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
 
  905    const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
 
  915bool CSKYAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
 
  926      return Error(IDLoc, 
"Register sequence is not valid. 'r4-r7' expected");
 
  933      return Error(IDLoc, 
"msb must be greater or equal to lsb");
 
  937      return Error(IDLoc, 
"msb must be greater or equal to lsb");
 
  941      return Error(IDLoc, 
"n must be in range [0,32]");
 
  972  case CSKY::PseudoLRW16:
 
  973  case CSKY::PseudoLRW32:
 
  974    return processLRW(Inst, IDLoc, Out);
 
  975  case CSKY::PseudoJSRI32:
 
  976    return processJSRI(Inst, IDLoc, Out);
 
  977  case CSKY::PseudoJMPI32:
 
  978    return processJMPI(Inst, IDLoc, Out);
 
  989    const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
 
  996  emitToStreamer(Out, Inst);
 
 1007  if (
Reg == CSKY::NoRegister)
 
 1010  return Reg == CSKY::NoRegister;
 
 
 1013bool CSKYAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
 
 1015  const AsmToken &Tok = getParser().getTok();
 
 1018  StringRef 
Name = getLexer().getTok().getIdentifier();
 
 1028ParseStatus CSKYAsmParser::parseRegister(
OperandVector &Operands) {
 
 1032  switch (getLexer().getKind()) {
 
 1036    StringRef 
Name = getLexer().getTok().getIdentifier();
 
 1050ParseStatus CSKYAsmParser::parseBaseRegImm(
OperandVector &Operands) {
 
 1053  Operands.
push_back(CSKYOperand::createToken(
"(", getLoc()));
 
 1055  auto Tok = getParser().Lex(); 
 
 1057  if (!parseRegister(Operands).isSuccess()) {
 
 1058    getLexer().UnLex(Tok);
 
 1064    Operands.
push_back(CSKYOperand::createToken(
")", getLoc()));
 
 1070    return Error(getLoc(), 
"expected ','");
 
 1074  if (parseRegister(Operands).isSuccess()) {
 
 1076      return Error(getLoc(), 
"expected '<<'");
 
 1078    Operands.
push_back(CSKYOperand::createToken(
"<<", getLoc()));
 
 1083      return Error(getLoc(), 
"expected imm");
 
 1086    return Error(getLoc(), 
"expected imm");
 
 1090    return Error(getLoc(), 
"expected ')'");
 
 1092  Operands.
push_back(CSKYOperand::createToken(
")", getLoc()));
 
 1099ParseStatus CSKYAsmParser::parseImmediate(
OperandVector &Operands) {
 
 1100  switch (getLexer().getKind()) {
 
 1111  const MCExpr *IdVal;
 
 1113  if (getParser().parseExpression(IdVal))
 
 1114    return Error(getLoc(), 
"unknown expression");
 
 1117  Operands.
push_back(CSKYOperand::createImm(IdVal, S, 
E));
 
 1124bool CSKYAsmParser::parseOperand(
OperandVector &Operands, StringRef Mnemonic) {
 
 1128      MatchOperandParserImpl(Operands, Mnemonic, 
true);
 
 1135  auto Res = parseRegister(Operands);
 
 1136  if (Res.isSuccess())
 
 1138  if (Res.isFailure())
 
 1143    Res = parseBaseRegImm(Operands);
 
 1144    if (Res.isSuccess())
 
 1146    if (Res.isFailure())
 
 1151  if (Res.isSuccess())
 
 1153  if (Res.isFailure())
 
 1157  Error(getLoc(), 
"unknown operand");
 
 1161ParseStatus CSKYAsmParser::parseCSKYSymbol(
OperandVector &Operands) {
 
 1170  AsmToken Tok = getLexer().getTok();
 
 1172  if (getParser().parseIdentifier(Identifier))
 
 1173    return Error(getLoc(), 
"unknown identifier");
 
 1184  else if (
Identifier.consume_back(
"@TLSGD32"))
 
 1186  else if (
Identifier.consume_back(
"@GOTTPOFF"))
 
 1190  else if (
Identifier.consume_back(
"@TLSLDM32"))
 
 1192  else if (
Identifier.consume_back(
"@TLSLDO32"))
 
 1198    Sym = 
getContext().getOrCreateSymbol(Identifier);
 
 1203      getLexer().UnLex(Tok); 
 
 1204      return Error(getLoc(), 
"unknown symbol");
 
 1211  switch (getLexer().getKind()) {
 
 1216    Operands.
push_back(CSKYOperand::createImm(Res, S, 
E));
 
 1229  if (getParser().parseExpression(Expr))
 
 1230    return Error(getLoc(), 
"unknown expression");
 
 1232  Operands.
push_back(CSKYOperand::createImm(Res, S, 
E));
 
 1236ParseStatus CSKYAsmParser::parseDataSymbol(
OperandVector &Operands) {
 
 1245    if (getParser().parseExpression(Expr))
 
 1246      return Error(getLoc(), 
"unknown expression");
 
 1251    Operands.
push_back(CSKYOperand::createConstpoolOp(Expr, S, 
E));
 
 1255  AsmToken Tok = getLexer().getTok();
 
 1258  if (getParser().parseIdentifier(Identifier))
 
 1259    return Error(getLoc(), 
"unknown identifier " + Identifier);
 
 1270    Sym = 
getContext().getOrCreateSymbol(Identifier);
 
 1275      getLexer().UnLex(Tok); 
 
 1276      return Error(getLoc(), 
"unknown symbol");
 
 1284  switch (getLexer().getKind()) {
 
 1286    return Error(getLoc(), 
"unknown symbol");
 
 1294    Operands.
push_back(CSKYOperand::createConstpoolOp(Res, S, 
E));
 
 1307  if (getParser().parseExpression(Expr))
 
 1308    return Error(getLoc(), 
"unknown expression");
 
 1313  Operands.
push_back(CSKYOperand::createConstpoolOp(Res, S, 
E));
 
 1317ParseStatus CSKYAsmParser::parseConstpoolSymbol(
OperandVector &Operands) {
 
 1327    if (getParser().parseExpression(Expr))
 
 1328      return Error(getLoc(), 
"unknown expression");
 
 1332    Operands.
push_back(CSKYOperand::createConstpoolOp(Expr, S, 
E));
 
 1336  AsmToken Tok = getLexer().getTok();
 
 1339  if (getParser().parseIdentifier(Identifier))
 
 1340    return Error(getLoc(), 
"unknown identifier");
 
 1345    Sym = 
getContext().getOrCreateSymbol(Identifier);
 
 1350      getLexer().UnLex(Tok); 
 
 1351      return Error(getLoc(), 
"unknown symbol");
 
 1359  switch (getLexer().getKind()) {
 
 1361    return Error(getLoc(), 
"unknown symbol");
 
 1366    Operands.
push_back(CSKYOperand::createConstpoolOp(Res, S, 
E));
 
 1379  if (getParser().parseExpression(Expr))
 
 1380    return Error(getLoc(), 
"unknown expression");
 
 1385  Operands.
push_back(CSKYOperand::createConstpoolOp(Res, S, 
E));
 
 1389ParseStatus CSKYAsmParser::parsePSRFlag(
OperandVector &Operands) {
 
 1397    if (getParser().parseIdentifier(Identifier))
 
 1398      return Error(getLoc(), 
"unknown identifier " + Identifier);
 
 1400    if (Identifier == 
"sie")
 
 1401      Flag = (1 << 4) | Flag;
 
 1402    else if (Identifier == 
"ee")
 
 1403      Flag = (1 << 3) | Flag;
 
 1404    else if (Identifier == 
"ie")
 
 1405      Flag = (1 << 2) | Flag;
 
 1406    else if (Identifier == 
"fe")
 
 1407      Flag = (1 << 1) | Flag;
 
 1408    else if (Identifier == 
"af")
 
 1409      Flag = (1 << 0) | Flag;
 
 1411      return Error(getLoc(), 
"expected " + Identifier);
 
 1425ParseStatus CSKYAsmParser::parseRegSeq(
OperandVector &Operands) {
 
 1428  if (!parseRegister(Operands).isSuccess())
 
 1431  auto Ry = Operands.
back()->getReg();
 
 1436  if (!parseRegister(Operands).isSuccess())
 
 1437    return Error(getLoc(), 
"invalid register");
 
 1439  auto Rz = Operands.
back()->getReg();
 
 1442  Operands.
push_back(CSKYOperand::createRegSeq(Ry, Rz, S));
 
 1446ParseStatus CSKYAsmParser::parseRegList(
OperandVector &Operands) {
 
 1451    if (!parseRegister(Operands).isSuccess())
 
 1452      return Error(getLoc(), 
"invalid register");
 
 1454    auto Ry = Operands.
back()->getReg();
 
 1458      if (!parseRegister(Operands).isSuccess())
 
 1459        return Error(getLoc(), 
"invalid register");
 
 1461      auto Rz = Operands.
back()->getReg();
 
 1478      return Error(getLoc(), 
"invalid register list");
 
 1482  Operands.
push_back(CSKYOperand::createRegList(reglist, S));
 
 1486bool CSKYAsmParser::parseInstruction(ParseInstructionInfo &
Info, StringRef Name,
 
 1489  Operands.
push_back(CSKYOperand::createToken(Name, NameLoc));
 
 1496  if (parseOperand(Operands, Name))
 
 1501    if (parseOperand(Operands, Name))
 
 1505    SMLoc Loc = getLexer().getLoc();
 
 1506    getParser().eatToEndOfStatement();
 
 1507    return Error(Loc, 
"unexpected token");
 
 1514ParseStatus CSKYAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
 
 1516  const AsmToken &Tok = getParser().getTok();
 
 1520  StringRef 
Name = getLexer().getTok().getIdentifier();
 
 1529ParseStatus CSKYAsmParser::parseDirective(AsmToken DirectiveID) {
 
 1530  StringRef IDVal = DirectiveID.
getString();
 
 1532  if (IDVal == 
".csky_attribute")
 
 1533    return parseDirectiveAttribute();
 
 1540bool CSKYAsmParser::parseDirectiveAttribute() {
 
 1541  MCAsmParser &Parser = getParser();
 
 1547    std::optional<unsigned> 
Ret =
 
 1550      return Error(TagLoc, 
"attribute name not recognised: " + Name);
 
 1554    const MCExpr *AttrExpr;
 
 1562      return Error(TagLoc, 
"expected numeric constant");
 
 1564    Tag = 
CE->getValue();
 
 1570  StringRef StringValue;
 
 1571  int64_t IntegerValue = 0;
 
 1577  if (IsIntegerValue) {
 
 1578    const MCExpr *ValueExpr;
 
 1584      return Error(ValueExprLoc, 
"expected numeric constant");
 
 1585    IntegerValue = 
CE->getValue();
 
 1598    getTargetStreamer().emitAttribute(
Tag, IntegerValue);
 
 1600    getTargetStreamer().emitTextAttribute(
Tag, StringValue);
 
 1605    if (
ID == CSKY::ArchKind::INVALID)
 
 1607                                     ? 
"unknown arch name" 
 1608                                     : 
"unknown cpu name");
 
 1610    getTargetStreamer().emitTextAttribute(
Tag, StringValue);
 
 1616unsigned CSKYAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
 
 1618  CSKYOperand &
Op = 
static_cast<CSKYOperand &
>(AsmOp);
 
 1621    return Match_InvalidOperand;
 
 1623  MCRegister 
Reg = 
Op.getReg();
 
 1625  if (CSKYMCRegisterClasses[CSKY::FPR32RegClassID].
contains(
Reg)) {
 
 1628    if (Kind == MCK_FPR64 || Kind == MCK_sFPR64) {
 
 1630      if (Kind == MCK_sFPR64 &&
 
 1631          (
Op.Reg.RegNum < CSKY::F0_64 || 
Op.Reg.RegNum > CSKY::F15_64))
 
 1632        return Match_InvalidRegOutOfRange;
 
 1633      if (Kind == MCK_FPR64 &&
 
 1634          (
Op.Reg.RegNum < CSKY::F0_64 || 
Op.Reg.RegNum > CSKY::F31_64))
 
 1635        return Match_InvalidRegOutOfRange;
 
 1636      return Match_Success;
 
 1640  if (CSKYMCRegisterClasses[CSKY::GPRRegClassID].
contains(
Reg)) {
 
 1641    if (Kind == MCK_GPRPair) {
 
 1642      Op.Reg.RegNum = 
MRI->getEncodingValue(
Reg) + CSKY::R0_R1;
 
 1643      return Match_Success;
 
 1647  return Match_InvalidOperand;
 
 1650void CSKYAsmParser::emitToStreamer(MCStreamer &S, 
const MCInst &Inst) {
 
 1654    Res = compressInst(CInst, Inst, getSTI());
 
 1656    ++CSKYNumInstrsCompressed;
 
unsigned const MachineRegisterInfo * MRI
 
static MCRegister MatchRegisterName(StringRef Name)
 
static const char * getSubtargetFeatureName(uint64_t Val)
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
 
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
 
static MCRegister MatchRegisterAltName(StringRef Name)
Maps from the set of all alternative registernames to a register number.
 
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
 
Analysis containing CSE Info
 
static bool matchRegisterNameHelper(const MCSubtargetInfo &STI, MCRegister &Reg, StringRef Name)
 
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYAsmParser()
 
static MCRegister convertFPR32ToFPR64(MCRegister Reg)
 
static std::string CSKYMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
 
static cl::opt< bool > EnableCompressedInst("enable-csky-asm-compressed-inst", cl::Hidden, cl::init(false), cl::desc("Enable C-SKY asm compressed instruction"))
 
#define LLVM_EXTERNAL_VISIBILITY
 
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
 
static bool isReg(const MCInst &MI, unsigned OpNo)
 
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
 
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
 
#define STATISTIC(VARNAME, DESC)
 
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
 
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
 
bool parseImmediate(MCInst &MI, uint64_t &Size, ArrayRef< uint8_t > Bytes)
 
LLVM_ABI SMLoc getLoc() const
 
bool isNot(TokenKind K) const
 
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
 
StringRef getStringContents() const
Get the contents of a string token (without quotes).
 
bool is(TokenKind K) const
 
LLVM_ABI SMLoc getEndLoc() const
 
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
 
static const char * getRegisterName(MCRegister Reg)
 
Base class for user error types.
 
Container class for subtarget features.
 
constexpr size_t size() const
 
void printExpr(raw_ostream &, const MCExpr &) const
 
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
 
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
 
const AsmToken & getTok() const
Get the current AsmToken from the stream.
 
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
 
static LLVM_ABI const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
 
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
 
unsigned getNumOperands() const
 
unsigned getOpcode() const
 
iterator insert(iterator I, const MCOperand &Op)
 
void addOperand(const MCOperand Op)
 
void setOpcode(unsigned Op)
 
const MCOperand & getOperand(unsigned i) const
 
static MCOperand createExpr(const MCExpr *Val)
 
static MCOperand createReg(MCRegister Reg)
 
static MCOperand createImm(int64_t Val)
 
MCRegister getReg() const
Returns the register number.
 
const MCExpr * getExpr() const
 
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
 
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
 
Wrapper class representing physical registers. Should be passed by value.
 
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
 
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
 
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
 
Generic base class for all target subtargets.
 
const FeatureBitset & getFeatureBits() const
 
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
 
bool isVariable() const
isVariable - Check if this is a variable symbol.
 
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
 
MCTargetAsmParser - Generic interface to target specific assembly parsers.
 
Ternary parse status returned by various parse* methods.
 
static constexpr StatusTy Failure
 
static constexpr StatusTy Success
 
static constexpr StatusTy NoMatch
 
Represents a location in source code.
 
static SMLoc getFromPointer(const char *Ptr)
 
constexpr const char * getPointer() const
 
void push_back(const T &Elt)
 
StringRef - Represent a constant reference to a string, i.e.
 
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
 
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
 
LLVM_ABI const TagNameMap & getCSKYAttributeTags()
 
LLVM_ABI ArchKind parseCPUArch(StringRef CPU)
 
LLVM_ABI ArchKind parseArch(StringRef Arch)
 
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
 
LLVM_ABI std::optional< unsigned > attrTypeFromString(StringRef tag, TagNameMap tagNameMap)
 
Flag
These should be considered private to the implementation of the MCInstrDesc class.
 
@ CE
Windows NT (Windows on ARM)
 
initializer< Ty > init(const Ty &Val)
 
Context & getContext() const
 
This is an optimization pass for GlobalISel generic memory operations.
 
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
 
static bool isMem(const MachineInstr &MI, unsigned Op)
 
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
 
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
 
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
 
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
 
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
 
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
 
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
 
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
 
Target & getTheCSKYTarget()
 
DWARFExpression::Operation Op
 
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
 
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
 
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...