//===---- CSKYAsmParser.cpp - Parse CSKY assembly to MCInst instructions --===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "MCTargetDesc/CSKYInstPrinter.h"
#include "MCTargetDesc/CSKYMCExpr.h"
#include "MCTargetDesc/CSKYMCTargetDesc.h"
#include "MCTargetDesc/CSKYTargetStreamer.h"
#include "TargetInfo/CSKYTargetInfo.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/CodeGen/Register.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/CSKYAttributes.h"
#include "llvm/Support/CSKYTargetParser.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"

using namespace llvm;

#define DEBUG_TYPE "csky-asm-parser"

// Include the auto-generated portion of the compress emitter.
#define GEN_COMPRESS_INSTR
#include "CSKYGenCompressInstEmitter.inc"

STATISTIC(CSKYNumInstrsCompressed,
          "Number of C-SKY Compressed instructions emitted");

static cl::opt<bool>
    EnableCompressedInst("enable-csky-asm-compressed-inst", cl::Hidden,
                         cl::init(false),
                         cl::desc("Enable C-SKY asm compressed instruction"));

namespace {
struct CSKYOperand;

class CSKYAsmParser : public MCTargetAsmParser {

  const MCRegisterInfo *MRI;

  unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
                                      unsigned Kind) override;

  bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo,
                                  int64_t Lower, int64_t Upper, Twine Msg);

  SMLoc getLoc() const { return getParser().getTok().getLoc(); }

  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
                               OperandVector &Operands, MCStreamer &Out,
                               uint64_t &ErrorInfo,
                               bool MatchingInlineAsm) override;

  bool parseRegister(MCRegister &RegNo, SMLoc &StartLoc,
                     SMLoc &EndLoc) override;

  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
                        SMLoc NameLoc, OperandVector &Operands) override;

  bool ParseDirective(AsmToken DirectiveID) override;

  // Helper to actually emit an instruction to the MCStreamer. Also, when
  // possible, compression of the instruction is performed.
  void emitToStreamer(MCStreamer &S, const MCInst &Inst);

  OperandMatchResultTy tryParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
                                        SMLoc &EndLoc) override;

  bool processInstruction(MCInst &Inst, SMLoc IDLoc, OperandVector &Operands,
                          MCStreamer &Out);
  bool processLRW(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
  bool processJSRI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
  bool processJMPI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);

  CSKYTargetStreamer &getTargetStreamer() {
    assert(getParser().getStreamer().getTargetStreamer() &&
           "do not have a target streamer");
    MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
    return static_cast<CSKYTargetStreamer &>(TS);
  }

// Auto-generated instruction matching functions
#define GET_ASSEMBLER_HEADER
#include "CSKYGenAsmMatcher.inc"

  OperandMatchResultTy parseImmediate(OperandVector &Operands);
  OperandMatchResultTy parseRegister(OperandVector &Operands);
  OperandMatchResultTy parseBaseRegImm(OperandVector &Operands);
  OperandMatchResultTy parseCSKYSymbol(OperandVector &Operands);
  OperandMatchResultTy parseConstpoolSymbol(OperandVector &Operands);
  OperandMatchResultTy parseDataSymbol(OperandVector &Operands);
  OperandMatchResultTy parsePSRFlag(OperandVector &Operands);
  OperandMatchResultTy parseRegSeq(OperandVector &Operands);
  OperandMatchResultTy parseRegList(OperandVector &Operands);

  bool parseOperand(OperandVector &Operands, StringRef Mnemonic);

  bool parseDirectiveAttribute();

public:
  enum CSKYMatchResultTy {
    Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
    Match_RequiresSameSrcAndDst,
    Match_InvalidRegOutOfRange,
#define GET_OPERAND_DIAGNOSTIC_TYPES
#include "CSKYGenAsmMatcher.inc"
#undef GET_OPERAND_DIAGNOSTIC_TYPES
  };

  CSKYAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
                const MCInstrInfo &MII, const MCTargetOptions &Options)
      : MCTargetAsmParser(Options, STI, MII) {

    MCAsmParserExtension::Initialize(Parser);

    // Cache the MCRegisterInfo.
    MRI = getContext().getRegisterInfo();

    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
    getTargetStreamer().emitTargetAttributes(STI);
  }
};

/// Instances of this class represent a parsed machine instruction.
struct CSKYOperand : public MCParsedAsmOperand {

  enum KindTy {
    Token,
    Register,
    Immediate,
    RegisterSeq,
    CPOP,
    RegisterList
  } Kind;

  struct RegOp {
    unsigned RegNum;
  };

  struct ImmOp {
    const MCExpr *Val;
  };

  struct ConstpoolOp {
    const MCExpr *Val;
  };

  struct RegSeqOp {
    unsigned RegNumFrom;
    unsigned RegNumTo;
  };

  struct RegListOp {
    unsigned List1From = 0;
    unsigned List1To = 0;
    unsigned List2From = 0;
    unsigned List2To = 0;
    unsigned List3From = 0;
    unsigned List3To = 0;
    unsigned List4From = 0;
    unsigned List4To = 0;
  };

  SMLoc StartLoc, EndLoc;
  union {
    StringRef Tok;
    RegOp Reg;
    ImmOp Imm;
    ConstpoolOp CPool;
    RegSeqOp RegSeq;
    RegListOp RegList;
  };

  CSKYOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}

public:
  CSKYOperand(const CSKYOperand &o) : MCParsedAsmOperand() {
    Kind = o.Kind;
    StartLoc = o.StartLoc;
    EndLoc = o.EndLoc;
    switch (Kind) {
    case Register:
      Reg = o.Reg;
      break;
    case RegisterSeq:
      RegSeq = o.RegSeq;
      break;
    case CPOP:
      CPool = o.CPool;
      break;
    case Immediate:
      Imm = o.Imm;
      break;
    case Token:
      Tok = o.Tok;
      break;
    case RegisterList:
      RegList = o.RegList;
      break;
    }
  }

  bool isToken() const override { return Kind == Token; }
  bool isReg() const override { return Kind == Register; }
  bool isImm() const override { return Kind == Immediate; }
  bool isRegisterSeq() const { return Kind == RegisterSeq; }
  bool isRegisterList() const { return Kind == RegisterList; }
  bool isConstPoolOp() const { return Kind == CPOP; }

  bool isMem() const override { return false; }

  static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm) {
    if (auto CE = dyn_cast<MCConstantExpr>(Expr)) {
      Imm = CE->getValue();
      return true;
    }

    return false;
  }

  template <unsigned num, unsigned shift = 0> bool isUImm() const {
    if (!isImm())
      return false;

    int64_t Imm;
    bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
    return IsConstantImm && isShiftedUInt<num, shift>(Imm);
  }

  template <unsigned num> bool isOImm() const {
    if (!isImm())
      return false;

    int64_t Imm;
    bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
    return IsConstantImm && isUInt<num>(Imm - 1);
  }

  template <unsigned num, unsigned shift = 0> bool isSImm() const {
    if (!isImm())
      return false;

    int64_t Imm;
    bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
    return IsConstantImm && isShiftedInt<num, shift>(Imm);
  }

  bool isUImm1() const { return isUImm<1>(); }
  bool isUImm2() const { return isUImm<2>(); }
  bool isUImm3() const { return isUImm<3>(); }
  bool isUImm4() const { return isUImm<4>(); }
  bool isUImm5() const { return isUImm<5>(); }
  bool isUImm6() const { return isUImm<6>(); }
  bool isUImm7() const { return isUImm<7>(); }
  bool isUImm8() const { return isUImm<8>(); }
  bool isUImm12() const { return isUImm<12>(); }
  bool isUImm16() const { return isUImm<16>(); }
  bool isUImm20() const { return isUImm<20>(); }
  bool isUImm24() const { return isUImm<24>(); }

  bool isOImm3() const { return isOImm<3>(); }
  bool isOImm4() const { return isOImm<4>(); }
  bool isOImm5() const { return isOImm<5>(); }
  bool isOImm6() const { return isOImm<6>(); }
  bool isOImm8() const { return isOImm<8>(); }
  bool isOImm12() const { return isOImm<12>(); }
  bool isOImm16() const { return isOImm<16>(); }

  bool isSImm8() const { return isSImm<8>(); }

  bool isUImm5Shift1() { return isUImm<5, 1>(); }
  bool isUImm5Shift2() { return isUImm<5, 2>(); }
  bool isUImm7Shift1() { return isUImm<7, 1>(); }
  bool isUImm7Shift2() { return isUImm<7, 2>(); }
  bool isUImm7Shift3() { return isUImm<7, 3>(); }
  bool isUImm8Shift2() { return isUImm<8, 2>(); }
  bool isUImm8Shift3() { return isUImm<8, 3>(); }
  bool isUImm8Shift8() { return isUImm<8, 8>(); }
  bool isUImm8Shift16() { return isUImm<8, 16>(); }
  bool isUImm8Shift24() { return isUImm<8, 24>(); }
  bool isUImm12Shift1() { return isUImm<12, 1>(); }
  bool isUImm12Shift2() { return isUImm<12, 2>(); }
  bool isUImm16Shift8() { return isUImm<16, 8>(); }
  bool isUImm16Shift16() { return isUImm<16, 16>(); }
  bool isUImm24Shift8() { return isUImm<24, 8>(); }

  bool isSImm16Shift1() { return isSImm<16, 1>(); }

  bool isCSKYSymbol() const { return isImm(); }

  bool isConstpool() const { return isConstPoolOp(); }
  bool isDataSymbol() const { return isConstPoolOp(); }

  bool isPSRFlag() const {
    int64_t Imm;
    // Must be of 'immediate' type and a constant.
    if (!isImm() || !evaluateConstantImm(getImm(), Imm))
      return false;

    return isUInt<5>(Imm);
  }

  template <unsigned MIN, unsigned MAX> bool isRegSeqTemplate() const {
    if (!isRegisterSeq())
      return false;

    std::pair<unsigned, unsigned> regSeq = getRegSeq();

    return MIN <= regSeq.first && regSeq.first <= regSeq.second &&
           regSeq.second <= MAX;
  }

  bool isRegSeq() const { return isRegSeqTemplate<CSKY::R0, CSKY::R31>(); }

  bool isRegSeqV1() const {
    return isRegSeqTemplate<CSKY::F0_32, CSKY::F15_32>();
  }

  bool isRegSeqV2() const {
    return isRegSeqTemplate<CSKY::F0_32, CSKY::F31_32>();
  }

  static bool isLegalRegList(unsigned from, unsigned to) {
    if (from == 0 && to == 0)
      return true;

    if (from == to) {
      if (from != CSKY::R4 && from != CSKY::R15 && from != CSKY::R16 &&
          from != CSKY::R28)
        return false;

      return true;
    } else {
      if (from != CSKY::R4 && from != CSKY::R16)
        return false;

      if (from == CSKY::R4 && to > CSKY::R4 && to < CSKY::R12)
        return true;
      else if (from == CSKY::R16 && to > CSKY::R16 && to < CSKY::R18)
        return true;
      else
        return false;
    }
  }

  bool isRegList() const {
    if (!isRegisterList())
      return false;

    auto regList = getRegList();

    if (!isLegalRegList(regList.List1From, regList.List1To))
      return false;
    if (!isLegalRegList(regList.List2From, regList.List2To))
      return false;
    if (!isLegalRegList(regList.List3From, regList.List3To))
      return false;
    if (!isLegalRegList(regList.List4From, regList.List4To))
      return false;

    return true;
  }

  bool isExtImm6() {
    if (!isImm())
      return false;

    int64_t Imm;
    bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
    if (!IsConstantImm)
      return false;

    int uimm4 = Imm & 0xf;

    return isShiftedUInt<6, 0>(Imm) && uimm4 >= 0 && uimm4 <= 14;
  }

  /// Gets location of the first token of this operand.
  SMLoc getStartLoc() const override { return StartLoc; }
  /// Gets location of the last token of this operand.
  SMLoc getEndLoc() const override { return EndLoc; }

  unsigned getReg() const override {
    assert(Kind == Register && "Invalid type access!");
    return Reg.RegNum;
  }

  std::pair<unsigned, unsigned> getRegSeq() const {
    assert(Kind == RegisterSeq && "Invalid type access!");
    return std::pair<unsigned, unsigned>(RegSeq.RegNumFrom, RegSeq.RegNumTo);
  }

  RegListOp getRegList() const {
    assert(Kind == RegisterList && "Invalid type access!");
    return RegList;
  }

  const MCExpr *getImm() const {
    assert(Kind == Immediate && "Invalid type access!");
    return Imm.Val;
  }

  const MCExpr *getConstpoolOp() const {
    assert(Kind == CPOP && "Invalid type access!");
    return CPool.Val;
  }

  StringRef getToken() const {
    assert(Kind == Token && "Invalid type access!");
    return Tok;
  }

  void print(raw_ostream &OS) const override {
    auto RegName = [](MCRegister Reg) {
      if (Reg)
        return CSKYInstPrinter::getRegisterName(Reg);
      else
        return "noreg";
    };

    switch (Kind) {
    case CPOP:
      OS << *getConstpoolOp();
      break;
    case Immediate:
      OS << *getImm();
      break;
    case KindTy::Register:
      OS << "<register " << RegName(getReg()) << ">";
      break;
    case RegisterSeq:
      OS << "<register-seq ";
      OS << RegName(getRegSeq().first) << "-" << RegName(getRegSeq().second)
         << ">";
      break;
    case RegisterList:
      OS << "<register-list ";
      OS << RegName(getRegList().List1From) << "-"
         << RegName(getRegList().List1To) << ",";
      OS << RegName(getRegList().List2From) << "-"
         << RegName(getRegList().List2To) << ",";
      OS << RegName(getRegList().List3From) << "-"
         << RegName(getRegList().List3To) << ",";
      OS << RegName(getRegList().List4From) << "-"
         << RegName(getRegList().List4To);
      break;
    case Token:
      OS << "'" << getToken() << "'";
      break;
    }
  }

  static std::unique_ptr<CSKYOperand> createToken(StringRef Str, SMLoc S) {
    auto Op = std::make_unique<CSKYOperand>(Token);
    Op->Tok = Str;
    Op->StartLoc = S;
    Op->EndLoc = S;
    return Op;
  }

  static std::unique_ptr<CSKYOperand> createReg(unsigned RegNo, SMLoc S,
                                                SMLoc E) {
    auto Op = std::make_unique<CSKYOperand>(Register);
    Op->Reg.RegNum = RegNo;
    Op->StartLoc = S;
    Op->EndLoc = E;
    return Op;
  }

  static std::unique_ptr<CSKYOperand> createRegSeq(unsigned RegNoFrom,
                                                   unsigned RegNoTo, SMLoc S) {
    auto Op = std::make_unique<CSKYOperand>(RegisterSeq);
    Op->RegSeq.RegNumFrom = RegNoFrom;
    Op->RegSeq.RegNumTo = RegNoTo;
    Op->StartLoc = S;
    Op->EndLoc = S;
    return Op;
  }

  static std::unique_ptr<CSKYOperand>
  createRegList(SmallVector<unsigned, 4> reglist, SMLoc S) {
    auto Op = std::make_unique<CSKYOperand>(RegisterList);
    Op->RegList.List1From = 0;
    Op->RegList.List1To = 0;
    Op->RegList.List2From = 0;
    Op->RegList.List2To = 0;
    Op->RegList.List3From = 0;
    Op->RegList.List3To = 0;
    Op->RegList.List4From = 0;
    Op->RegList.List4To = 0;

    for (unsigned i = 0; i < reglist.size(); i += 2) {
      if (Op->RegList.List1From == 0) {
        Op->RegList.List1From = reglist[i];
        Op->RegList.List1To = reglist[i + 1];
      } else if (Op->RegList.List2From == 0) {
        Op->RegList.List2From = reglist[i];
        Op->RegList.List2To = reglist[i + 1];
      } else if (Op->RegList.List3From == 0) {
        Op->RegList.List3From = reglist[i];
        Op->RegList.List3To = reglist[i + 1];
      } else if (Op->RegList.List4From == 0) {
        Op->RegList.List4From = reglist[i];
        Op->RegList.List4To = reglist[i + 1];
      } else {
        assert(0);
      }
    }

    Op->StartLoc = S;
    Op->EndLoc = S;
    return Op;
  }

  static std::unique_ptr<CSKYOperand> createImm(const MCExpr *Val, SMLoc S,
                                                SMLoc E) {
    auto Op = std::make_unique<CSKYOperand>(Immediate);
    Op->Imm.Val = Val;
    Op->StartLoc = S;
    Op->EndLoc = E;
    return Op;
  }

  static std::unique_ptr<CSKYOperand> createConstpoolOp(const MCExpr *Val,
                                                        SMLoc S, SMLoc E) {
    auto Op = std::make_unique<CSKYOperand>(CPOP);
    Op->CPool.Val = Val;
    Op->StartLoc = S;
    Op->EndLoc = E;
    return Op;
  }

  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
    assert(Expr && "Expr shouldn't be null!");
    if (auto *CE = dyn_cast<MCConstantExpr>(Expr))
      Inst.addOperand(MCOperand::createImm(CE->getValue()));
    else
      Inst.addOperand(MCOperand::createExpr(Expr));
  }

  // Used by the TableGen Code.
  void addRegOperands(MCInst &Inst, unsigned N) const {
    assert(N == 1 && "Invalid number of operands!");
    Inst.addOperand(MCOperand::createReg(getReg()));
  }

  void addImmOperands(MCInst &Inst, unsigned N) const {
    assert(N == 1 && "Invalid number of operands!");
    addExpr(Inst, getImm());
  }

  void addConstpoolOperands(MCInst &Inst, unsigned N) const {
    assert(N == 1 && "Invalid number of operands!");
    Inst.addOperand(MCOperand::createExpr(getConstpoolOp()));
  }

  void addRegSeqOperands(MCInst &Inst, unsigned N) const {
    assert(N == 2 && "Invalid number of operands!");
    auto regSeq = getRegSeq();

    Inst.addOperand(MCOperand::createReg(regSeq.first));
    Inst.addOperand(MCOperand::createReg(regSeq.second));
  }

  static unsigned getListValue(unsigned ListFrom, unsigned ListTo) {
    if (ListFrom == ListTo && ListFrom == CSKY::R15)
      return (1 << 4);
    else if (ListFrom == ListTo && ListFrom == CSKY::R28)
      return (1 << 8);
    else if (ListFrom == CSKY::R4)
      return ListTo - ListFrom + 1;
    else if (ListFrom == CSKY::R16)
      return ((ListTo - ListFrom + 1) << 5);
    else
      return 0;
  }

  void addRegListOperands(MCInst &Inst, unsigned N) const {
    assert(N == 1 && "Invalid number of operands!");
    auto regList = getRegList();

    unsigned V = 0;

    unsigned T = getListValue(regList.List1From, regList.List1To);
    if (T != 0)
      V = V | T;

    T = getListValue(regList.List2From, regList.List2To);
    if (T != 0)
      V = V | T;

    T = getListValue(regList.List3From, regList.List3To);
    if (T != 0)
      V = V | T;

    T = getListValue(regList.List4From, regList.List4To);
    if (T != 0)
      V = V | T;

    Inst.addOperand(MCOperand::createImm(V));
  }

  bool isValidForTie(const CSKYOperand &Other) const {
    if (Kind != Other.Kind)
      return false;

    switch (Kind) {
    default:
      llvm_unreachable("Unexpected kind");
      return false;
    case Register:
      return Reg.RegNum == Other.Reg.RegNum;
    }
  }
};
} // end anonymous namespace.

#define GET_REGISTER_MATCHER
#define GET_SUBTARGET_FEATURE_NAME
#define GET_MATCHER_IMPLEMENTATION
#define GET_MNEMONIC_SPELL_CHECKER
#include "CSKYGenAsmMatcher.inc"

static MCRegister convertFPR32ToFPR64(MCRegister Reg) {
  assert(Reg >= CSKY::F0_32 && Reg <= CSKY::F31_32 && "Invalid register");
  return Reg - CSKY::F0_32 + CSKY::F0_64;
}

static std::string CSKYMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
                                          unsigned VariantID = 0);

bool CSKYAsmParser::generateImmOutOfRangeError(
    OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper,
    Twine Msg = "immediate must be an integer in the range") {
  SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
  return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]");
}

bool CSKYAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
                                            OperandVector &Operands,
                                            MCStreamer &Out,
                                            uint64_t &ErrorInfo,
                                            bool MatchingInlineAsm) {
  MCInst Inst;
  FeatureBitset MissingFeatures;

  auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
                                     MatchingInlineAsm);
  switch (Result) {
  default:
    break;
  case Match_Success:
    return processInstruction(Inst, IDLoc, Operands, Out);
  case Match_MissingFeature: {
    assert(MissingFeatures.any() && "Unknown missing features!");
    ListSeparator LS;
    std::string Msg = "instruction requires the following: ";
    for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) {
      if (MissingFeatures[i]) {
        Msg += LS;
        Msg += getSubtargetFeatureName(i);
      }
    }
    return Error(IDLoc, Msg);
  }
  case Match_MnemonicFail: {
    FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
    std::string Suggestion =
        CSKYMnemonicSpellCheck(((CSKYOperand &)*Operands[0]).getToken(), FBS);
    return Error(IDLoc, "unrecognized instruction mnemonic" + Suggestion);
  }
  case Match_InvalidTiedOperand:
  case Match_InvalidOperand: {
    SMLoc ErrorLoc = IDLoc;
    if (ErrorInfo != ~0U) {
      if (ErrorInfo >= Operands.size())
        return Error(ErrorLoc, "too few operands for instruction");

      ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
      if (ErrorLoc == SMLoc())
        ErrorLoc = IDLoc;
    }
    return Error(ErrorLoc, "invalid operand for instruction");
  }
  }

  // Handle the case when the error message is of specific type
  // other than the generic Match_InvalidOperand, and the
  // corresponding operand is missing.
  if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
    SMLoc ErrorLoc = IDLoc;
    if (ErrorInfo != ~0U && ErrorInfo >= Operands.size())
      return Error(ErrorLoc, "too few operands for instruction");
  }

  switch (Result) {
  default:
    break;
  case Match_InvalidSImm8:
    return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 7),
                                      (1 << 7) - 1);
  case Match_InvalidOImm3:
    return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 3));
  case Match_InvalidOImm4:
    return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 4));
  case Match_InvalidOImm5:
    return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5));
  case Match_InvalidOImm6:
    return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6));
  case Match_InvalidOImm8:
    return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 8));
  case Match_InvalidOImm12:
    return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 12));
  case Match_InvalidOImm16:
    return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 16));
  case Match_InvalidUImm1:
    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 1) - 1);
  case Match_InvalidUImm2:
    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1);
  case Match_InvalidUImm3:
    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1);
  case Match_InvalidUImm4:
    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);
  case Match_InvalidUImm5:
    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
  case Match_InvalidUImm6:
    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
  case Match_InvalidUImm7:
    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1);
  case Match_InvalidUImm8:
    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 8) - 1);
  case Match_InvalidUImm12:
    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1);
  case Match_InvalidUImm16:
    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 16) - 1);
  case Match_InvalidUImm5Shift1:
    return generateImmOutOfRangeError(
        Operands, ErrorInfo, 0, (1 << 5) - 2,
        "immediate must be a multiple of 2 bytes in the range");
  case Match_InvalidUImm12Shift1:
    return generateImmOutOfRangeError(
        Operands, ErrorInfo, 0, (1 << 12) - 2,
        "immediate must be a multiple of 2 bytes in the range");
  case Match_InvalidUImm5Shift2:
    return generateImmOutOfRangeError(
        Operands, ErrorInfo, 0, (1 << 5) - 4,
        "immediate must be a multiple of 4 bytes in the range");
  case Match_InvalidUImm7Shift1:
    return generateImmOutOfRangeError(
        Operands, ErrorInfo, 0, (1 << 7) - 2,
        "immediate must be a multiple of 2 bytes in the range");
  case Match_InvalidUImm7Shift2:
    return generateImmOutOfRangeError(
        Operands, ErrorInfo, 0, (1 << 7) - 4,
        "immediate must be a multiple of 4 bytes in the range");
  case Match_InvalidUImm8Shift2:
    return generateImmOutOfRangeError(
        Operands, ErrorInfo, 0, (1 << 8) - 4,
        "immediate must be a multiple of 4 bytes in the range");
  case Match_InvalidUImm8Shift3:
    return generateImmOutOfRangeError(
        Operands, ErrorInfo, 0, (1 << 8) - 8,
        "immediate must be a multiple of 8 bytes in the range");
  case Match_InvalidUImm8Shift8:
    return generateImmOutOfRangeError(
        Operands, ErrorInfo, 0, (1 << 8) - 256,
        "immediate must be a multiple of 256 bytes in the range");
  case Match_InvalidUImm12Shift2:
    return generateImmOutOfRangeError(
        Operands, ErrorInfo, 0, (1 << 12) - 4,
        "immediate must be a multiple of 4 bytes in the range");
  case Match_InvalidCSKYSymbol: {
    SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
    return Error(ErrorLoc, "operand must be a symbol name");
  }
  case Match_InvalidConstpool: {
    SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
    return Error(ErrorLoc, "operand must be a constpool symbol name");
  }
  case Match_InvalidPSRFlag: {
    SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
    return Error(ErrorLoc, "psrset operand is not valid");
  }
  case Match_InvalidRegSeq: {
    SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
    return Error(ErrorLoc, "Register sequence is not valid");
  }
  case Match_InvalidRegOutOfRange: {
    SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
    return Error(ErrorLoc, "register is out of range");
  }
  case Match_RequiresSameSrcAndDst: {
    SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
    return Error(ErrorLoc, "src and dst operand must be same");
  }
  case Match_InvalidRegList: {
    SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
    return Error(ErrorLoc, "invalid register list");
  }
  }
  LLVM_DEBUG(dbgs() << "Result = " << Result);
  llvm_unreachable("Unknown match type detected!");
}

bool CSKYAsmParser::processLRW(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {
  Inst.setLoc(IDLoc);

  unsigned Opcode;
  MCOperand Op;
  if (Inst.getOpcode() == CSKY::PseudoLRW16)
    Opcode = CSKY::LRW16;
  else
    Opcode = CSKY::LRW32;

  if (Inst.getOperand(1).isImm()) {
    if (isUInt<8>(Inst.getOperand(1).getImm()) &&
        Inst.getOperand(0).getReg() <= CSKY::R7) {
      Opcode = CSKY::MOVI16;
    } else if (getSTI().getFeatureBits()[CSKY::HasE2] &&
               isUInt<16>(Inst.getOperand(1).getImm())) {
      Opcode = CSKY::MOVI32;
    } else {
      auto *Expr = getTargetStreamer().addConstantPoolEntry(
          MCConstantExpr::create(Inst.getOperand(1).getImm(), getContext()),
          Inst.getLoc());
      Inst.erase(std::prev(Inst.end()));
      Inst.addOperand(MCOperand::createExpr(Expr));
    }
  } else {
    const MCExpr *AdjustExpr = nullptr;
    if (const CSKYMCExpr *CSKYExpr =
            dyn_cast<CSKYMCExpr>(Inst.getOperand(1).getExpr())) {
      if (CSKYExpr->getKind() == CSKYMCExpr::VK_CSKY_TLSGD ||
          CSKYExpr->getKind() == CSKYMCExpr::VK_CSKY_TLSIE ||
          CSKYExpr->getKind() == CSKYMCExpr::VK_CSKY_TLSLDM) {
        MCSymbol *Dot = getContext().createNamedTempSymbol();
        Out.emitLabel(Dot);
        AdjustExpr = MCSymbolRefExpr::create(Dot, getContext());
      }
    }
    auto *Expr = getTargetStreamer().addConstantPoolEntry(
        Inst.getOperand(1).getExpr(), Inst.getLoc(), AdjustExpr);
    Inst.erase(std::prev(Inst.end()));
    Inst.addOperand(MCOperand::createExpr(Expr));
  }

  Inst.setOpcode(Opcode);

  Out.emitInstruction(Inst, getSTI());
  return false;
}

bool CSKYAsmParser::processJSRI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {
  Inst.setLoc(IDLoc);

  if (Inst.getOperand(0).isImm()) {
    const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
        MCConstantExpr::create(Inst.getOperand(0).getImm(), getContext()),
        Inst.getLoc());
    Inst.setOpcode(CSKY::JSRI32);
    Inst.erase(std::prev(Inst.end()));
    Inst.addOperand(MCOperand::createExpr(Expr));
  } else {
    const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
        Inst.getOperand(0).getExpr(), Inst.getLoc());
    Inst.setOpcode(CSKY::JBSR32);
    Inst.addOperand(MCOperand::createExpr(Expr));
  }

  Out.emitInstruction(Inst, getSTI());
  return false;
}

bool CSKYAsmParser::processJMPI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {
  Inst.setLoc(IDLoc);

  if (Inst.getOperand(0).isImm()) {
    const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
        MCConstantExpr::create(Inst.getOperand(0).getImm(), getContext()),
        Inst.getLoc());
    Inst.setOpcode(CSKY::JMPI32);
    Inst.erase(std::prev(Inst.end()));
    Inst.addOperand(MCOperand::createExpr(Expr));
  } else {
    const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
        Inst.getOperand(0).getExpr(), Inst.getLoc());
    Inst.setOpcode(CSKY::JBR32);
    Inst.addOperand(MCOperand::createExpr(Expr));
  }

  Out.emitInstruction(Inst, getSTI());
  return false;
}

bool CSKYAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
                                       OperandVector &Operands,
                                       MCStreamer &Out) {

  switch (Inst.getOpcode()) {
  default:
    break;
  case CSKY::LDQ32:
  case CSKY::STQ32:
    if (Inst.getOperand(1).getReg() != CSKY::R4 ||
        Inst.getOperand(2).getReg() != CSKY::R7) {
      return Error(IDLoc, "Register sequence is not valid. 'r4-r7' expected");
    }
    Inst.setOpcode(Inst.getOpcode() == CSKY::LDQ32 ? CSKY::LDM32 : CSKY::STM32);
    break;
  case CSKY::SEXT32:
  case CSKY::ZEXT32:
    if (Inst.getOperand(2).getImm() < Inst.getOperand(3).getImm())
      return Error(IDLoc, "msb must be greater or equal to lsb");
    break;
  case CSKY::INS32:
    if (Inst.getOperand(3).getImm() < Inst.getOperand(4).getImm())
      return Error(IDLoc, "msb must be greater or equal to lsb");
    break;
  case CSKY::IDLY32:
    if (Inst.getOperand(0).getImm() > 32 || Inst.getOperand(0).getImm() < 0)
      return Error(IDLoc, "n must be in range [0,32]");
    break;
  case CSKY::ADDC32:
  case CSKY::SUBC32:
  case CSKY::ADDC16:
  case CSKY::SUBC16:
    Inst.erase(std::next(Inst.begin()));
    Inst.erase(std::prev(Inst.end()));
    Inst.insert(std::next(Inst.begin()), MCOperand::createReg(CSKY::C));
    Inst.insert(Inst.end(), MCOperand::createReg(CSKY::C));
    break;
  case CSKY::CMPNEI32:
  case CSKY::CMPNEI16:
  case CSKY::CMPNE32:
  case CSKY::CMPNE16:
  case CSKY::CMPHSI32:
  case CSKY::CMPHSI16:
  case CSKY::CMPHS32:
  case CSKY::CMPHS16:
  case CSKY::CMPLTI32:
  case CSKY::CMPLTI16:
  case CSKY::CMPLT32:
  case CSKY::CMPLT16:
  case CSKY::BTSTI32:
    Inst.erase(Inst.begin());
    Inst.insert(Inst.begin(), MCOperand::createReg(CSKY::C));
    break;
  case CSKY::MVCV32:
    Inst.erase(std::next(Inst.begin()));
    Inst.insert(Inst.end(), MCOperand::createReg(CSKY::C));
    break;
  case CSKY::PseudoLRW16:
  case CSKY::PseudoLRW32:
    return processLRW(Inst, IDLoc, Out);
  case CSKY::PseudoJSRI32:
    return processJSRI(Inst, IDLoc, Out);
  case CSKY::PseudoJMPI32:
    return processJMPI(Inst, IDLoc, Out);
  case CSKY::JBSR32:
  case CSKY::JBR16:
  case CSKY::JBT16:
  case CSKY::JBF16:
  case CSKY::JBR32:
  case CSKY::JBT32:
  case CSKY::JBF32:
    unsigned Num = Inst.getNumOperands() - 1;
    assert(Inst.getOperand(Num).isExpr());

    const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
        Inst.getOperand(Num).getExpr(), Inst.getLoc());

    Inst.addOperand(MCOperand::createExpr(Expr));
    break;
  }

  emitToStreamer(Out, Inst);
  return false;
}

// Attempts to match Name as a register (either using the default name or
// alternative ABI names), setting RegNo to the matching register. Upon
// failure, returns true and sets RegNo to 0.
static bool matchRegisterNameHelper(const MCSubtargetInfo &STI,
                                    MCRegister &RegNo, StringRef Name) {
  RegNo = MatchRegisterName(Name);

  if (RegNo == CSKY::NoRegister)
    RegNo = MatchRegisterAltName(Name);

  return RegNo == CSKY::NoRegister;
}

bool CSKYAsmParser::parseRegister(MCRegister &RegNo, SMLoc &StartLoc,
                                  SMLoc &EndLoc) {
  const AsmToken &Tok = getParser().getTok();
  StartLoc = Tok.getLoc();
  EndLoc = Tok.getEndLoc();
  StringRef Name = getLexer().getTok().getIdentifier();

  if (!matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name)) {
    getParser().Lex(); // Eat identifier token.
    return false;
  }

  return MatchOperand_NoMatch;
}

OperandMatchResultTy CSKYAsmParser::parseRegister(OperandVector &Operands) {
  SMLoc S = getLoc();
  SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);

  switch (getLexer().getKind()) {
  default:
    return MatchOperand_NoMatch;
  case AsmToken::Identifier: {
    StringRef Name = getLexer().getTok().getIdentifier();
    MCRegister RegNo;

    if (matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name))
      return MatchOperand_NoMatch;

    getLexer().Lex();
    Operands.push_back(CSKYOperand::createReg(RegNo, S, E));

    return MatchOperand_Success;
  }
  }
}

OperandMatchResultTy CSKYAsmParser::parseBaseRegImm(OperandVector &Operands) {
  assert(getLexer().is(AsmToken::LParen));

  Operands.push_back(CSKYOperand::createToken("(", getLoc()));

  auto Tok = getParser().Lex(); // Eat '('

  if (parseRegister(Operands) != MatchOperand_Success) {
    getLexer().UnLex(Tok);
    Operands.pop_back();
    return MatchOperand_NoMatch;
  }

  if (getLexer().is(AsmToken::RParen)) {
    Operands.push_back(CSKYOperand::createToken(")", getLoc()));
    getParser().Lex(); // Eat ')'
    return MatchOperand_Success;
  }

  if (getLexer().isNot(AsmToken::Comma)) {
    Error(getLoc(), "expected ','");
    return MatchOperand_ParseFail;
  }

  getParser().Lex(); // Eat ','

  if (parseRegister(Operands) == MatchOperand_Success) {
    if (getLexer().isNot(AsmToken::LessLess)) {
      Error(getLoc(), "expected '<<'");
      return MatchOperand_ParseFail;
    }

    Operands.push_back(CSKYOperand::createToken("<<", getLoc()));

    getParser().Lex(); // Eat '<<'

    if (parseImmediate(Operands) != MatchOperand_Success) {
      Error(getLoc(), "expected imm");
      return MatchOperand_ParseFail;
    }

  } else if (parseImmediate(Operands) != MatchOperand_Success) {
    Error(getLoc(), "expected imm");
    return MatchOperand_ParseFail;
  }

  if (getLexer().isNot(AsmToken::RParen)) {
    Error(getLoc(), "expected ')'");
    return MatchOperand_ParseFail;
  }

  Operands.push_back(CSKYOperand::createToken(")", getLoc()));

  getParser().Lex(); // Eat ')'

  return MatchOperand_Success;
}

OperandMatchResultTy CSKYAsmParser::parseImmediate(OperandVector &Operands) {
  switch (getLexer().getKind()) {
  default:
    return MatchOperand_NoMatch;
  case AsmToken::LParen:
  case AsmToken::Minus:
  case AsmToken::Plus:
  case AsmToken::Integer:
  case AsmToken::String:
    break;
  }

  const MCExpr *IdVal;
  SMLoc S = getLoc();
  if (getParser().parseExpression(IdVal)) {
    Error(getLoc(), "unknown expression");
    return MatchOperand_ParseFail;
  }

  SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
  Operands.push_back(CSKYOperand::createImm(IdVal, S, E));
  return MatchOperand_Success;
}

/// Looks at a token type and creates the relevant operand from this
/// information, adding to Operands. If operand was parsed, returns false, else
/// true.
bool CSKYAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
  // Check if the current operand has a custom associated parser, if so, try to
  // custom parse the operand, or fallback to the general approach.
  OperandMatchResultTy Result =
      MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true);
  if (Result == MatchOperand_Success)
    return false;
  if (Result == MatchOperand_ParseFail)
    return true;

  // Attempt to parse token as register
  auto Res = parseRegister(Operands);
  if (Res == MatchOperand_Success)
    return false;
  else if (Res == MatchOperand_ParseFail)
    return true;

  // Attempt to parse token as (register, imm)
  if (getLexer().is(AsmToken::LParen)) {
    Res = parseBaseRegImm(Operands);
    if (Res == MatchOperand_Success)
      return false;
    else if (Res == MatchOperand_ParseFail)
      return true;
  }

  Res = parseImmediate(Operands);
  if (Res == MatchOperand_Success)
    return false;
  else if (Res == MatchOperand_ParseFail)
    return true;

  // Finally we have exhausted all options and must declare defeat.
  Error(getLoc(), "unknown operand");
  return true;
}

OperandMatchResultTy CSKYAsmParser::parseCSKYSymbol(OperandVector &Operands) {
  SMLoc S = getLoc();
  SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
  const MCExpr *Res;

  if (getLexer().getKind() != AsmToken::Identifier)
    return MatchOperand_NoMatch;

  StringRef Identifier;
  AsmToken Tok = getLexer().getTok();

  if (getParser().parseIdentifier(Identifier)) {
    Error(getLoc(), "unknown identifier");
    return MatchOperand_ParseFail;
  }

  CSKYMCExpr::VariantKind Kind = CSKYMCExpr::VK_CSKY_None;
  if (Identifier.consume_back("@GOT"))
    Kind = CSKYMCExpr::VK_CSKY_GOT;
  else if (Identifier.consume_back("@GOTOFF"))
    Kind = CSKYMCExpr::VK_CSKY_GOTOFF;
  else if (Identifier.consume_back("@PLT"))
    Kind = CSKYMCExpr::VK_CSKY_PLT;
  else if (Identifier.consume_back("@GOTPC"))
    Kind = CSKYMCExpr::VK_CSKY_GOTPC;
  else if (Identifier.consume_back("@TLSGD32"))
    Kind = CSKYMCExpr::VK_CSKY_TLSGD;
  else if (Identifier.consume_back("@GOTTPOFF"))
    Kind = CSKYMCExpr::VK_CSKY_TLSIE;
  else if (Identifier.consume_back("@TPOFF"))
    Kind = CSKYMCExpr::VK_CSKY_TLSLE;
  else if (Identifier.consume_back("@TLSLDM32"))
    Kind = CSKYMCExpr::VK_CSKY_TLSLDM;
  else if (Identifier.consume_back("@TLSLDO32"))
    Kind = CSKYMCExpr::VK_CSKY_TLSLDO;

  MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier);

  if (!Sym)
    Sym = getContext().getOrCreateSymbol(Identifier);

  if (Sym->isVariable()) {
    const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false);
    if (!isa<MCSymbolRefExpr>(V)) {
      getLexer().UnLex(Tok); // Put back if it's not a bare symbol.
      Error(getLoc(), "unknown symbol");
      return MatchOperand_ParseFail;
    }
    Res = V;
  } else
    Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());

  MCBinaryExpr::Opcode Opcode;
  switch (getLexer().getKind()) {
  default:
    if (Kind != CSKYMCExpr::VK_CSKY_None)
      Res = CSKYMCExpr::create(Res, Kind, getContext());

    Operands.push_back(CSKYOperand::createImm(Res, S, E));
    return MatchOperand_Success;
  case AsmToken::Plus:
    Opcode = MCBinaryExpr::Add;
    break;
  case AsmToken::Minus:
    Opcode = MCBinaryExpr::Sub;
    break;
  }

  getLexer().Lex(); // eat + or -

  const MCExpr *Expr;
  if (getParser().parseExpression(Expr)) {
    Error(getLoc(), "unknown expression");
    return MatchOperand_ParseFail;
  }
  Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext());
  Operands.push_back(CSKYOperand::createImm(Res, S, E));
  return MatchOperand_Success;
}

OperandMatchResultTy CSKYAsmParser::parseDataSymbol(OperandVector &Operands) {
  SMLoc S = getLoc();
  SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
  const MCExpr *Res;

  if (getLexer().getKind() != AsmToken::LBrac)
    return MatchOperand_NoMatch;

  getLexer().Lex(); // Eat '['.

  if (getLexer().getKind() != AsmToken::Identifier) {
    const MCExpr *Expr;
    if (getParser().parseExpression(Expr)) {
      Error(getLoc(), "unknown expression");
      return MatchOperand_ParseFail;
    }

    if (getLexer().getKind() != AsmToken::RBrac) {
      Error(getLoc(), "expected ]");
      return MatchOperand_ParseFail;
    }

    getLexer().Lex(); // Eat ']'.

    Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E));
    return MatchOperand_Success;
  }

  AsmToken Tok = getLexer().getTok();
  StringRef Identifier;

  if (getParser().parseIdentifier(Identifier)) {
    Error(getLoc(), "unknown identifier " + Identifier);
    return MatchOperand_ParseFail;
  }

  CSKYMCExpr::VariantKind Kind = CSKYMCExpr::VK_CSKY_None;
  if (Identifier.consume_back("@GOT"))
    Kind = CSKYMCExpr::VK_CSKY_GOT_IMM18_BY4;
  else if (Identifier.consume_back("@PLT"))
    Kind = CSKYMCExpr::VK_CSKY_PLT_IMM18_BY4;

  MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier);

  if (!Sym)
    Sym = getContext().getOrCreateSymbol(Identifier);

  if (Sym->isVariable()) {
    const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false);
    if (!isa<MCSymbolRefExpr>(V)) {
      getLexer().UnLex(Tok); // Put back if it's not a bare symbol.
      Error(getLoc(), "unknown symbol");
      return MatchOperand_ParseFail;
    }
    Res = V;
  } else {
    Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
  }

  MCBinaryExpr::Opcode Opcode;
  switch (getLexer().getKind()) {
  default:
    Error(getLoc(), "unknown symbol");
    return MatchOperand_ParseFail;
  case AsmToken::RBrac:

    getLexer().Lex(); // Eat ']'.

    if (Kind != CSKYMCExpr::VK_CSKY_None)
      Res = CSKYMCExpr::create(Res, Kind, getContext());

    Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));
    return MatchOperand_Success;
  case AsmToken::Plus:
    Opcode = MCBinaryExpr::Add;
    break;
  case AsmToken::Minus:
    Opcode = MCBinaryExpr::Sub;
    break;
  }

  getLexer().Lex(); // eat + or -

  const MCExpr *Expr;
  if (getParser().parseExpression(Expr)) {
    Error(getLoc(), "unknown expression");
    return MatchOperand_ParseFail;
  }

  if (getLexer().getKind() != AsmToken::RBrac) {
    Error(getLoc(), "expected ']'");
    return MatchOperand_ParseFail;
  }

  getLexer().Lex(); // Eat ']'.

  Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext());
  Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));
  return MatchOperand_Success;
}

OperandMatchResultTy
CSKYAsmParser::parseConstpoolSymbol(OperandVector &Operands) {
  SMLoc S = getLoc();
  SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
  const MCExpr *Res;

  if (getLexer().getKind() != AsmToken::LBrac)
    return MatchOperand_NoMatch;

  getLexer().Lex(); // Eat '['.

  if (getLexer().getKind() != AsmToken::Identifier) {
    const MCExpr *Expr;
    if (getParser().parseExpression(Expr)) {
      Error(getLoc(), "unknown expression");
      return MatchOperand_ParseFail;
    }

    if (getLexer().getKind() != AsmToken::RBrac) {
      Error(getLoc(), "expected ']'");
      return MatchOperand_ParseFail;
    }

    getLexer().Lex(); // Eat ']'.

    Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E));
    return MatchOperand_Success;
  }

  AsmToken Tok = getLexer().getTok();
  StringRef Identifier;

  if (getParser().parseIdentifier(Identifier)) {
    Error(getLoc(), "unknown identifier");
    return MatchOperand_ParseFail;
  }

  MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier);

  if (!Sym)
    Sym = getContext().getOrCreateSymbol(Identifier);

  if (Sym->isVariable()) {
    const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false);
    if (!isa<MCSymbolRefExpr>(V)) {
      getLexer().UnLex(Tok); // Put back if it's not a bare symbol.
      Error(getLoc(), "unknown symbol");
      return MatchOperand_ParseFail;
    }
    Res = V;
  } else {
    Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
  }

  MCBinaryExpr::Opcode Opcode;
  switch (getLexer().getKind()) {
  default:
    Error(getLoc(), "unknown symbol");
    return MatchOperand_ParseFail;
  case AsmToken::RBrac:

    getLexer().Lex(); // Eat ']'.

    Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));
    return MatchOperand_Success;
  case AsmToken::Plus:
    Opcode = MCBinaryExpr::Add;
    break;
  case AsmToken::Minus:
    Opcode = MCBinaryExpr::Sub;
    break;
  }

  getLexer().Lex(); // eat + or -

  const MCExpr *Expr;
  if (getParser().parseExpression(Expr)) {
    Error(getLoc(), "unknown expression");
    return MatchOperand_ParseFail;
  }

  if (getLexer().getKind() != AsmToken::RBrac) {
    Error(getLoc(), "expected ']'");
    return MatchOperand_ParseFail;
  }

  getLexer().Lex(); // Eat ']'.

  Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext());
  Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));
  return MatchOperand_Success;
}

OperandMatchResultTy CSKYAsmParser::parsePSRFlag(OperandVector &Operands) {
  SMLoc S = getLoc();
  SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);

  unsigned Flag = 0;

  while (getLexer().isNot(AsmToken::EndOfStatement)) {
    StringRef Identifier;
    if (getParser().parseIdentifier(Identifier)) {
      Error(getLoc(), "unknown identifier " + Identifier);
      return MatchOperand_ParseFail;
    }

    if (Identifier == "sie")
      Flag = (1 << 4) | Flag;
    else if (Identifier == "ee")
      Flag = (1 << 3) | Flag;
    else if (Identifier == "ie")
      Flag = (1 << 2) | Flag;
    else if (Identifier == "fe")
      Flag = (1 << 1) | Flag;
    else if (Identifier == "af")
      Flag = (1 << 0) | Flag;
    else {
      Error(getLoc(), "expected " + Identifier);
      return MatchOperand_ParseFail;
    }

    if (getLexer().is(AsmToken::EndOfStatement))
      break;

    if (getLexer().is(AsmToken::Comma)) {
      getLexer().Lex(); // eat ','
    } else {
      Error(getLoc(), "expected ,");
      return MatchOperand_ParseFail;
    }
  }

  Operands.push_back(
      CSKYOperand::createImm(MCConstantExpr::create(Flag, getContext()), S, E));
  return MatchOperand_Success;
}

OperandMatchResultTy CSKYAsmParser::parseRegSeq(OperandVector &Operands) {
  SMLoc S = getLoc();

  if (parseRegister(Operands) != MatchOperand_Success)
    return MatchOperand_NoMatch;

  auto Ry = Operands.back()->getReg();
  Operands.pop_back();

  if (getLexer().isNot(AsmToken::Minus)) {
    Error(getLoc(), "expected '-'");
    return MatchOperand_ParseFail;
  }

  getLexer().Lex(); // eat '-'

  if (parseRegister(Operands) != MatchOperand_Success) {
    Error(getLoc(), "invalid register");
    return MatchOperand_ParseFail;
  }

  auto Rz = Operands.back()->getReg();
  Operands.pop_back();

  Operands.push_back(CSKYOperand::createRegSeq(Ry, Rz, S));
  return MatchOperand_Success;
}

OperandMatchResultTy CSKYAsmParser::parseRegList(OperandVector &Operands) {
  SMLoc S = getLoc();

  SmallVector<unsigned, 4> reglist;

  while (true) {

    if (parseRegister(Operands) != MatchOperand_Success) {
      Error(getLoc(), "invalid register");
      return MatchOperand_ParseFail;
    }

    auto Ry = Operands.back()->getReg();
    Operands.pop_back();

    if (getLexer().is(AsmToken::Minus)) {
      getLexer().Lex(); // eat '-'

      if (parseRegister(Operands) != MatchOperand_Success) {
        Error(getLoc(), "invalid register");
        return MatchOperand_ParseFail;
      }

      auto Rz = Operands.back()->getReg();
      Operands.pop_back();

      reglist.push_back(Ry);
      reglist.push_back(Rz);

      if (getLexer().is(AsmToken::Comma))
        getLexer().Lex(); // eat ','
      else if (getLexer().is(AsmToken::EndOfStatement))
        break;

    } else if (getLexer().is(AsmToken::Comma)) {
      reglist.push_back(Ry);
      reglist.push_back(Ry);

      getLexer().Lex(); // eat ','
    } else if (getLexer().is(AsmToken::EndOfStatement)) {
      reglist.push_back(Ry);
      reglist.push_back(Ry);
      break;
    } else {
      Error(getLoc(), "invalid register list");
      return MatchOperand_ParseFail;
    }
  }

  Operands.push_back(CSKYOperand::createRegList(reglist, S));
  return MatchOperand_Success;
}

bool CSKYAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
                                     SMLoc NameLoc, OperandVector &Operands) {
  // First operand is token for instruction.
  Operands.push_back(CSKYOperand::createToken(Name, NameLoc));

  // If there are no more operands, then finish.
  if (getLexer().is(AsmToken::EndOfStatement))
    return false;

  // Parse first operand.
  if (parseOperand(Operands, Name))
    return true;

  // Parse until end of statement, consuming commas between operands.
  while (getLexer().is(AsmToken::Comma)) {
    // Consume comma token.
    getLexer().Lex();

    // Parse next operand.
    if (parseOperand(Operands, Name))
      return true;
  }

  if (getLexer().isNot(AsmToken::EndOfStatement)) {
    SMLoc Loc = getLexer().getLoc();
    getParser().eatToEndOfStatement();
    return Error(Loc, "unexpected token");
  }

  getParser().Lex(); // Consume the EndOfStatement.
  return false;
}

OperandMatchResultTy CSKYAsmParser::tryParseRegister(MCRegister &RegNo,
                                                     SMLoc &StartLoc,
                                                     SMLoc &EndLoc) {
  const AsmToken &Tok = getParser().getTok();
  StartLoc = Tok.getLoc();
  EndLoc = Tok.getEndLoc();

  StringRef Name = getLexer().getTok().getIdentifier();

  if (matchRegisterNameHelper(getSTI(), (MCRegister &)RegNo, Name))
    return MatchOperand_NoMatch;

  getParser().Lex(); // Eat identifier token.
  return MatchOperand_Success;
}

bool CSKYAsmParser::ParseDirective(AsmToken DirectiveID) {
  // This returns false if this function recognizes the directive
  // regardless of whether it is successfully handles or reports an
  // error. Otherwise it returns true to give the generic parser a
  // chance at recognizing it.
  StringRef IDVal = DirectiveID.getString();

  if (IDVal == ".csky_attribute")
    return parseDirectiveAttribute();

  return true;
}

/// parseDirectiveAttribute
///  ::= .attribute expression ',' ( expression | "string" )
bool CSKYAsmParser::parseDirectiveAttribute() {
  MCAsmParser &Parser = getParser();
  int64_t Tag;
  SMLoc TagLoc;
  TagLoc = Parser.getTok().getLoc();
  if (Parser.getTok().is(AsmToken::Identifier)) {
    StringRef Name = Parser.getTok().getIdentifier();
    std::optional<unsigned> Ret =
        ELFAttrs::attrTypeFromString(Name, CSKYAttrs::getCSKYAttributeTags());
    if (!Ret) {
      Error(TagLoc, "attribute name not recognised: " + Name);
      return false;
    }
    Tag = *Ret;
    Parser.Lex();
  } else {
    const MCExpr *AttrExpr;

    TagLoc = Parser.getTok().getLoc();
    if (Parser.parseExpression(AttrExpr))
      return true;

    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr);
    if (check(!CE, TagLoc, "expected numeric constant"))
      return true;

    Tag = CE->getValue();
  }

  if (Parser.parseToken(AsmToken::Comma, "comma expected"))
    return true;

  StringRef StringValue;
  int64_t IntegerValue = 0;
  bool IsIntegerValue = ((Tag != CSKYAttrs::CSKY_ARCH_NAME) &&
                         (Tag != CSKYAttrs::CSKY_CPU_NAME) &&
                         (Tag != CSKYAttrs::CSKY_FPU_NUMBER_MODULE));

  SMLoc ValueExprLoc = Parser.getTok().getLoc();
  if (IsIntegerValue) {
    const MCExpr *ValueExpr;
    if (Parser.parseExpression(ValueExpr))
      return true;

    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr);
    if (!CE)
      return Error(ValueExprLoc, "expected numeric constant");
    IntegerValue = CE->getValue();
  } else {
    if (Parser.getTok().isNot(AsmToken::String))
      return Error(Parser.getTok().getLoc(), "expected string constant");

    StringValue = Parser.getTok().getStringContents();
    Parser.Lex();
  }

  if (Parser.parseEOL())
    return true;

  if (IsIntegerValue)
    getTargetStreamer().emitAttribute(Tag, IntegerValue);
  else if (Tag != CSKYAttrs::CSKY_ARCH_NAME && Tag != CSKYAttrs::CSKY_CPU_NAME)
    getTargetStreamer().emitTextAttribute(Tag, StringValue);
  else {
    CSKY::ArchKind ID = (Tag == CSKYAttrs::CSKY_ARCH_NAME)
                            ? CSKY::parseArch(StringValue)
                            : CSKY::parseCPUArch(StringValue);
    if (ID == CSKY::ArchKind::INVALID)
      return Error(ValueExprLoc, (Tag == CSKYAttrs::CSKY_ARCH_NAME)
                                     ? "unknown arch name"
                                     : "unknown cpu name");

    getTargetStreamer().emitTextAttribute(Tag, StringValue);
  }

  return false;
}

unsigned CSKYAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
                                                   unsigned Kind) {
  CSKYOperand &Op = static_cast<CSKYOperand &>(AsmOp);

  if (!Op.isReg())
    return Match_InvalidOperand;

  MCRegister Reg = Op.getReg();

  if (CSKYMCRegisterClasses[CSKY::FPR32RegClassID].contains(Reg)) {
    // As the parser couldn't differentiate an FPR64 from an FPR32, coerce the
    // register from FPR32 to FPR64 if necessary.
    if (Kind == MCK_FPR64 || Kind == MCK_sFPR64) {
      Op.Reg.RegNum = convertFPR32ToFPR64(Reg);
      if (Kind == MCK_sFPR64 &&
          (Op.Reg.RegNum < CSKY::F0_64 || Op.Reg.RegNum > CSKY::F15_64))
        return Match_InvalidRegOutOfRange;
      if (Kind == MCK_FPR64 &&
          (Op.Reg.RegNum < CSKY::F0_64 || Op.Reg.RegNum > CSKY::F31_64))
        return Match_InvalidRegOutOfRange;
      return Match_Success;
    }
  }

  if (CSKYMCRegisterClasses[CSKY::GPRRegClassID].contains(Reg)) {
    if (Kind == MCK_GPRPair) {
      Op.Reg.RegNum = MRI->getEncodingValue(Reg) + CSKY::R0_R1;
      return Match_Success;
    }
  }

  return Match_InvalidOperand;
}

void CSKYAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) {
  MCInst CInst;
  bool Res = false;
  if (EnableCompressedInst)
    Res = compressInst(CInst, Inst, getSTI());
  if (Res)
    ++CSKYNumInstrsCompressed;
  S.emitInstruction((Res ? CInst : Inst), getSTI());
}

extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYAsmParser() {
  RegisterMCAsmParser<CSKYAsmParser> X(getTheCSKYTarget());
}
