//===---- M68kAsmParser.cpp - Parse M68k 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 "M68kInstrInfo.h"
#include "M68kRegisterInfo.h"
#include "TargetInfo/M68kTargetInfo.h"

#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/TargetRegistry.h"

#include <sstream>

#define DEBUG_TYPE "m68k-asm-parser"

using namespace llvm;

static cl::opt<bool> RegisterPrefixOptional(
    "m68k-register-prefix-optional", cl::Hidden,
    cl::desc("Enable specifying registers without the % prefix"),
    cl::init(false));

namespace {
/// Parses M68k assembly from a stream.
class M68kAsmParser : public MCTargetAsmParser {
  const MCSubtargetInfo &STI;
  MCAsmParser &Parser;
  const MCRegisterInfo *MRI;

#define GET_ASSEMBLER_HEADER
#include "M68kGenAsmMatcher.inc"

  // Helpers for Match&Emit.
  bool invalidOperand(const SMLoc &Loc, const OperandVector &Operands,
                      const uint64_t &ErrorInfo);
  bool missingFeature(const SMLoc &Loc, const uint64_t &ErrorInfo);
  bool emit(MCInst &Inst, SMLoc const &Loc, MCStreamer &Out) const;
  bool parseRegisterName(unsigned int &RegNo, SMLoc Loc,
                         StringRef RegisterName);
  OperandMatchResultTy parseRegister(unsigned int &RegNo);

  // Parser functions.
  void eatComma();

  bool isExpr();
  OperandMatchResultTy parseImm(OperandVector &Operands);
  OperandMatchResultTy parseMemOp(OperandVector &Operands);
  OperandMatchResultTy parseRegOrMoveMask(OperandVector &Operands);

public:
  M68kAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
                const MCInstrInfo &MII, const MCTargetOptions &Options)
      : MCTargetAsmParser(Options, STI, MII), STI(STI), Parser(Parser) {
    MCAsmParserExtension::Initialize(Parser);
    MRI = getContext().getRegisterInfo();

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

  unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
                                      unsigned Kind) override;
  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
  OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc,
                                        SMLoc &EndLoc) override;
  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
                        SMLoc NameLoc, OperandVector &Operands) override;
  bool ParseDirective(AsmToken DirectiveID) override;
  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
                               OperandVector &Operands, MCStreamer &Out,
                               uint64_t &ErrorInfo,
                               bool MatchingInlineAsm) override;
};

struct M68kMemOp {
  enum class Kind {
    Addr,
    RegMask,
    Reg,
    RegIndirect,
    RegPostIncrement,
    RegPreDecrement,
    RegIndirectDisplacement,
    RegIndirectDisplacementIndex,
  };

  // These variables are used for the following forms:
  // Addr: (OuterDisp)
  // RegMask: RegMask (as register mask)
  // Reg: %OuterReg
  // RegIndirect: (%OuterReg)
  // RegPostIncrement: (%OuterReg)+
  // RegPreDecrement: -(%OuterReg)
  // RegIndirectDisplacement: OuterDisp(%OuterReg)
  // RegIndirectDisplacementIndex:
  //   OuterDisp(%OuterReg, %InnerReg.Size * Scale, InnerDisp)

  Kind Op;
  unsigned OuterReg;
  unsigned InnerReg;
  const MCExpr *OuterDisp;
  const MCExpr *InnerDisp;
  uint8_t Size : 4;
  uint8_t Scale : 4;
  const MCExpr *Expr;
  uint16_t RegMask;

  M68kMemOp() {}
  M68kMemOp(Kind Op) : Op(Op) {}

  void print(raw_ostream &OS) const;
};

/// An parsed M68k assembly operand.
class M68kOperand : public MCParsedAsmOperand {
  typedef MCParsedAsmOperand Base;

  enum class KindTy {
    Invalid,
    Token,
    Imm,
    MemOp,
  };

  KindTy Kind;
  SMLoc Start, End;
  union {
    StringRef Token;
    int64_t Imm;
    const MCExpr *Expr;
    M68kMemOp MemOp;
  };

  template <unsigned N> bool isAddrN() const;

public:
  M68kOperand(KindTy Kind, SMLoc Start, SMLoc End)
      : Base(), Kind(Kind), Start(Start), End(End) {}

  SMLoc getStartLoc() const override { return Start; }
  SMLoc getEndLoc() const override { return End; }

  void print(raw_ostream &OS) const override;

  bool isMem() const override { return false; }
  bool isMemOp() const { return Kind == KindTy::MemOp; }

  static void addExpr(MCInst &Inst, const MCExpr *Expr);

  // Reg
  bool isReg() const override;
  bool isAReg() const;
  bool isDReg() const;
  unsigned getReg() const override;
  void addRegOperands(MCInst &Inst, unsigned N) const;

  static std::unique_ptr<M68kOperand> createMemOp(M68kMemOp MemOp, SMLoc Start,
                                                  SMLoc End);

  // Token
  bool isToken() const override;
  StringRef getToken() const;
  static std::unique_ptr<M68kOperand> createToken(StringRef Token, SMLoc Start,
                                                  SMLoc End);

  // Imm
  bool isImm() const override;
  void addImmOperands(MCInst &Inst, unsigned N) const;

  static std::unique_ptr<M68kOperand> createImm(const MCExpr *Expr, SMLoc Start,
                                                SMLoc End);

  // MoveMask
  bool isMoveMask() const;
  void addMoveMaskOperands(MCInst &Inst, unsigned N) const;

  // Addr
  bool isAddr() const;
  bool isAddr8() const { return isAddrN<8>(); }
  bool isAddr16() const { return isAddrN<16>(); }
  bool isAddr32() const { return isAddrN<32>(); }
  void addAddrOperands(MCInst &Inst, unsigned N) const;

  // ARI
  bool isARI() const;
  void addARIOperands(MCInst &Inst, unsigned N) const;

  // ARID
  bool isARID() const;
  void addARIDOperands(MCInst &Inst, unsigned N) const;

  // ARII
  bool isARII() const;
  void addARIIOperands(MCInst &Inst, unsigned N) const;

  // ARIPD
  bool isARIPD() const;
  void addARIPDOperands(MCInst &Inst, unsigned N) const;

  // ARIPI
  bool isARIPI() const;
  void addARIPIOperands(MCInst &Inst, unsigned N) const;

  // PCD
  bool isPCD() const;
  void addPCDOperands(MCInst &Inst, unsigned N) const;

  // PCI
  bool isPCI() const;
  void addPCIOperands(MCInst &Inst, unsigned N) const;
};

} // end anonymous namespace.

extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeM68kAsmParser() {
  RegisterMCAsmParser<M68kAsmParser> X(getTheM68kTarget());
}

#define GET_MATCHER_IMPLEMENTATION
#include "M68kGenAsmMatcher.inc"

static inline unsigned getRegisterByIndex(unsigned RegisterIndex) {
  static unsigned RegistersByIndex[] = {
      M68k::D0, M68k::D1, M68k::D2, M68k::D3, M68k::D4, M68k::D5,
      M68k::D6, M68k::D7, M68k::A0, M68k::A1, M68k::A2, M68k::A3,
      M68k::A4, M68k::A5, M68k::A6, M68k::SP,
  };
  assert(RegisterIndex <=
         sizeof(RegistersByIndex) / sizeof(RegistersByIndex[0]));
  return RegistersByIndex[RegisterIndex];
}

static inline unsigned getRegisterIndex(unsigned Register) {
  if (Register >= M68k::D0 && Register <= M68k::D7)
    return Register - M68k::D0;
  if (Register >= M68k::A0 && Register <= M68k::A6)
    return Register - M68k::A0 + 8;

  switch (Register) {
  case M68k::SP:
    // SP is sadly not contiguous with the rest of the An registers
    return 15;

  case M68k::PC:
  case M68k::CCR:
    return 16;

  default:
    llvm_unreachable("unexpected register number");
  }
}

void M68kMemOp::print(raw_ostream &OS) const {
  switch (Op) {
  case Kind::Addr:
    OS << OuterDisp;
    break;
  case Kind::RegMask:
    OS << "RegMask(" << format("%04x", RegMask) << ")";
    break;
  case Kind::Reg:
    OS << '%' << OuterReg;
    break;
  case Kind::RegIndirect:
    OS << "(%" << OuterReg << ')';
    break;
  case Kind::RegPostIncrement:
    OS << "(%" << OuterReg << ")+";
    break;
  case Kind::RegPreDecrement:
    OS << "-(%" << OuterReg << ")";
    break;
  case Kind::RegIndirectDisplacement:
    OS << OuterDisp << "(%" << OuterReg << ")";
    break;
  case Kind::RegIndirectDisplacementIndex:
    OS << OuterDisp << "(%" << OuterReg << ", " << InnerReg << "." << Size
       << ", " << InnerDisp << ")";
    break;
  }
}

void M68kOperand::addExpr(MCInst &Inst, const MCExpr *Expr) {
  if (auto Const = dyn_cast<MCConstantExpr>(Expr)) {
    Inst.addOperand(MCOperand::createImm(Const->getValue()));
    return;
  }

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

// Reg
bool M68kOperand::isReg() const {
  return Kind == KindTy::MemOp && MemOp.Op == M68kMemOp::Kind::Reg;
}

unsigned M68kOperand::getReg() const {
  assert(isReg());
  return MemOp.OuterReg;
}

void M68kOperand::addRegOperands(MCInst &Inst, unsigned N) const {
  assert(isReg() && "wrong operand kind");
  assert((N == 1) && "can only handle one register operand");

  Inst.addOperand(MCOperand::createReg(getReg()));
}

std::unique_ptr<M68kOperand> M68kOperand::createMemOp(M68kMemOp MemOp,
                                                      SMLoc Start, SMLoc End) {
  auto Op = std::make_unique<M68kOperand>(KindTy::MemOp, Start, End);
  Op->MemOp = MemOp;
  return Op;
}

// Token
bool M68kOperand::isToken() const { return Kind == KindTy::Token; }
StringRef M68kOperand::getToken() const {
  assert(isToken());
  return Token;
}

std::unique_ptr<M68kOperand> M68kOperand::createToken(StringRef Token,
                                                      SMLoc Start, SMLoc End) {
  auto Op = std::make_unique<M68kOperand>(KindTy::Token, Start, End);
  Op->Token = Token;
  return Op;
}

// Imm
bool M68kOperand::isImm() const { return Kind == KindTy::Imm; }
void M68kOperand::addImmOperands(MCInst &Inst, unsigned N) const {
  assert(isImm() && "wrong operand kind");
  assert((N == 1) && "can only handle one register operand");

  M68kOperand::addExpr(Inst, Expr);
}

std::unique_ptr<M68kOperand> M68kOperand::createImm(const MCExpr *Expr,
                                                    SMLoc Start, SMLoc End) {
  auto Op = std::make_unique<M68kOperand>(KindTy::Imm, Start, End);
  Op->Expr = Expr;
  return Op;
}

// MoveMask
bool M68kOperand::isMoveMask() const {
  if (!isMemOp())
    return false;

  if (MemOp.Op == M68kMemOp::Kind::RegMask)
    return true;

  if (MemOp.Op != M68kMemOp::Kind::Reg)
    return false;

  // Only regular address / data registers are allowed to be used
  // in register masks.
  return getRegisterIndex(MemOp.OuterReg) < 16;
}

void M68kOperand::addMoveMaskOperands(MCInst &Inst, unsigned N) const {
  assert(isMoveMask() && "wrong operand kind");
  assert((N == 1) && "can only handle one immediate operand");

  uint16_t MoveMask = MemOp.RegMask;
  if (MemOp.Op == M68kMemOp::Kind::Reg)
    MoveMask = 1 << getRegisterIndex(MemOp.OuterReg);

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

// Addr
bool M68kOperand::isAddr() const {
  return isMemOp() && MemOp.Op == M68kMemOp::Kind::Addr;
}
// TODO: Maybe we can also store the size of OuterDisp
// in Size?
template <unsigned N> bool M68kOperand::isAddrN() const {
  if (isAddr()) {
    int64_t Res;
    if (MemOp.OuterDisp->evaluateAsAbsolute(Res))
      return isInt<N>(Res);
    return true;
  }
  return false;
}
void M68kOperand::addAddrOperands(MCInst &Inst, unsigned N) const {
  M68kOperand::addExpr(Inst, MemOp.OuterDisp);
}

// ARI
bool M68kOperand::isARI() const {
  return isMemOp() && MemOp.Op == M68kMemOp::Kind::RegIndirect &&
         M68k::AR32RegClass.contains(MemOp.OuterReg);
}
void M68kOperand::addARIOperands(MCInst &Inst, unsigned N) const {
  Inst.addOperand(MCOperand::createReg(MemOp.OuterReg));
}

// ARID
bool M68kOperand::isARID() const {
  return isMemOp() && MemOp.Op == M68kMemOp::Kind::RegIndirectDisplacement &&
         M68k::AR32RegClass.contains(MemOp.OuterReg);
}
void M68kOperand::addARIDOperands(MCInst &Inst, unsigned N) const {
  M68kOperand::addExpr(Inst, MemOp.OuterDisp);
  Inst.addOperand(MCOperand::createReg(MemOp.OuterReg));
}

// ARII
bool M68kOperand::isARII() const {
  return isMemOp() &&
         MemOp.Op == M68kMemOp::Kind::RegIndirectDisplacementIndex &&
         M68k::AR32RegClass.contains(MemOp.OuterReg);
}
void M68kOperand::addARIIOperands(MCInst &Inst, unsigned N) const {
  M68kOperand::addExpr(Inst, MemOp.OuterDisp);
  Inst.addOperand(MCOperand::createReg(MemOp.OuterReg));
  Inst.addOperand(MCOperand::createReg(MemOp.InnerReg));
}

// ARIPD
bool M68kOperand::isARIPD() const {
  return isMemOp() && MemOp.Op == M68kMemOp::Kind::RegPreDecrement &&
         M68k::AR32RegClass.contains(MemOp.OuterReg);
}
void M68kOperand::addARIPDOperands(MCInst &Inst, unsigned N) const {
  Inst.addOperand(MCOperand::createReg(MemOp.OuterReg));
}

// ARIPI
bool M68kOperand::isARIPI() const {
  return isMemOp() && MemOp.Op == M68kMemOp::Kind::RegPostIncrement &&
         M68k::AR32RegClass.contains(MemOp.OuterReg);
}
void M68kOperand::addARIPIOperands(MCInst &Inst, unsigned N) const {
  Inst.addOperand(MCOperand::createReg(MemOp.OuterReg));
}

// PCD
bool M68kOperand::isPCD() const {
  return isMemOp() && MemOp.Op == M68kMemOp::Kind::RegIndirectDisplacement &&
         MemOp.OuterReg == M68k::PC;
}
void M68kOperand::addPCDOperands(MCInst &Inst, unsigned N) const {
  M68kOperand::addExpr(Inst, MemOp.OuterDisp);
}

// PCI
bool M68kOperand::isPCI() const {
  return isMemOp() &&
         MemOp.Op == M68kMemOp::Kind::RegIndirectDisplacementIndex &&
         MemOp.OuterReg == M68k::PC;
}
void M68kOperand::addPCIOperands(MCInst &Inst, unsigned N) const {
  M68kOperand::addExpr(Inst, MemOp.OuterDisp);
  Inst.addOperand(MCOperand::createReg(MemOp.InnerReg));
}

static inline bool checkRegisterClass(unsigned RegNo, bool Data, bool Address,
                                      bool SP) {
  switch (RegNo) {
  case M68k::A0:
  case M68k::A1:
  case M68k::A2:
  case M68k::A3:
  case M68k::A4:
  case M68k::A5:
  case M68k::A6:
    return Address;

  case M68k::SP:
    return SP;

  case M68k::D0:
  case M68k::D1:
  case M68k::D2:
  case M68k::D3:
  case M68k::D4:
  case M68k::D5:
  case M68k::D6:
  case M68k::D7:
    return Data;

  case M68k::SR:
  case M68k::CCR:
    return false;

  default:
    llvm_unreachable("unexpected register type");
    return false;
  }
}

bool M68kOperand::isAReg() const {
  return isReg() && checkRegisterClass(getReg(),
                                       /*Data=*/false,
                                       /*Address=*/true, /*SP=*/true);
}

bool M68kOperand::isDReg() const {
  return isReg() && checkRegisterClass(getReg(),
                                       /*Data=*/true,
                                       /*Address=*/false, /*SP=*/false);
}

unsigned M68kAsmParser::validateTargetOperandClass(MCParsedAsmOperand &Op,
                                                   unsigned Kind) {
  M68kOperand &Operand = (M68kOperand &)Op;

  switch (Kind) {
  case MCK_XR16:
  case MCK_SPILL:
    if (Operand.isReg() &&
        checkRegisterClass(Operand.getReg(), true, true, true)) {
      return Match_Success;
    }
    break;

  case MCK_AR16:
  case MCK_AR32:
    if (Operand.isReg() &&
        checkRegisterClass(Operand.getReg(), false, true, true)) {
      return Match_Success;
    }
    break;

  case MCK_AR32_NOSP:
    if (Operand.isReg() &&
        checkRegisterClass(Operand.getReg(), false, true, false)) {
      return Match_Success;
    }
    break;

  case MCK_DR8:
  case MCK_DR16:
  case MCK_DR32:
    if (Operand.isReg() &&
        checkRegisterClass(Operand.getReg(), true, false, false)) {
      return Match_Success;
    }
    break;

  case MCK_AR16_TC:
    if (Operand.isReg() &&
        ((Operand.getReg() == M68k::A0) || (Operand.getReg() == M68k::A1))) {
      return Match_Success;
    }
    break;

  case MCK_DR16_TC:
    if (Operand.isReg() &&
        ((Operand.getReg() == M68k::D0) || (Operand.getReg() == M68k::D1))) {
      return Match_Success;
    }
    break;

  case MCK_XR16_TC:
    if (Operand.isReg() &&
        ((Operand.getReg() == M68k::D0) || (Operand.getReg() == M68k::D1) ||
         (Operand.getReg() == M68k::A0) || (Operand.getReg() == M68k::A1))) {
      return Match_Success;
    }
    break;
  }

  return Match_InvalidOperand;
}

bool M68kAsmParser::parseRegisterName(unsigned &RegNo, SMLoc Loc,
                                      StringRef RegisterName) {
  auto RegisterNameLower = RegisterName.lower();

  // CCR register
  if (RegisterNameLower == "ccr") {
    RegNo = M68k::CCR;
    return true;
  }

  // Parse simple general-purpose registers.
  if (RegisterNameLower.size() == 2) {

    switch (RegisterNameLower[0]) {
    case 'd':
    case 'a': {
      if (isdigit(RegisterNameLower[1])) {
        unsigned IndexOffset = (RegisterNameLower[0] == 'a') ? 8 : 0;
        unsigned RegIndex = (unsigned)(RegisterNameLower[1] - '0');
        if (RegIndex < 8) {
          RegNo = getRegisterByIndex(IndexOffset + RegIndex);
          return true;
        }
      }
      break;
    }

    case 's':
      if (RegisterNameLower[1] == 'p') {
        RegNo = M68k::SP;
        return true;
      } else if (RegisterNameLower[1] == 'r') {
        RegNo = M68k::SR;
        return true;
      }
      break;

    case 'p':
      if (RegisterNameLower[1] == 'c') {
        RegNo = M68k::PC;
        return true;
      }
      break;
    }
  }

  return false;
}

OperandMatchResultTy M68kAsmParser::parseRegister(unsigned &RegNo) {
  bool HasPercent = false;
  AsmToken PercentToken;

  LLVM_DEBUG(dbgs() << "parseRegister "; getTok().dump(dbgs()); dbgs() << "\n");

  if (getTok().is(AsmToken::Percent)) {
    HasPercent = true;
    PercentToken = Lex();
  } else if (!RegisterPrefixOptional.getValue()) {
    return MatchOperand_NoMatch;
  }

  if (!Parser.getTok().is(AsmToken::Identifier)) {
    if (HasPercent) {
      getLexer().UnLex(PercentToken);
    }
    return MatchOperand_NoMatch;
  }

  auto RegisterName = Parser.getTok().getString();
  if (!parseRegisterName(RegNo, Parser.getLexer().getLoc(), RegisterName)) {
    if (HasPercent) {
      getLexer().UnLex(PercentToken);
    }
    return MatchOperand_NoMatch;
  }

  Parser.Lex();
  return MatchOperand_Success;
}

bool M68kAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
                                  SMLoc &EndLoc) {
  auto Result = tryParseRegister(RegNo, StartLoc, EndLoc);
  if (Result != MatchOperand_Success) {
    return Error(StartLoc, "expected register");
  }

  return false;
}

OperandMatchResultTy M68kAsmParser::tryParseRegister(unsigned &RegNo,
                                                     SMLoc &StartLoc,
                                                     SMLoc &EndLoc) {
  StartLoc = getLexer().getLoc();
  auto Result = parseRegister(RegNo);
  EndLoc = getLexer().getLoc();
  return Result;
}

bool M68kAsmParser::isExpr() {
  switch (Parser.getTok().getKind()) {
  case AsmToken::Identifier:
  case AsmToken::Integer:
    return true;
  case AsmToken::Minus:
    return getLexer().peekTok().getKind() == AsmToken::Integer;

  default:
    return false;
  }
}

OperandMatchResultTy M68kAsmParser::parseImm(OperandVector &Operands) {
  if (getLexer().isNot(AsmToken::Hash)) {
    return MatchOperand_NoMatch;
  }
  SMLoc Start = getLexer().getLoc();
  Parser.Lex();

  SMLoc End;
  const MCExpr *Expr;

  if (getParser().parseExpression(Expr, End)) {
    return MatchOperand_ParseFail;
  }

  Operands.push_back(M68kOperand::createImm(Expr, Start, End));
  return MatchOperand_Success;
}

OperandMatchResultTy M68kAsmParser::parseMemOp(OperandVector &Operands) {
  SMLoc Start = getLexer().getLoc();
  bool IsPD = false;
  M68kMemOp MemOp;

  // Check for a plain register or register mask.
  auto Result = parseRegOrMoveMask(Operands);
  if (Result != llvm::MatchOperand_NoMatch) {
    return Result;
  }

  // Check for pre-decrement & outer displacement.
  bool HasDisplacement = false;
  if (getLexer().is(AsmToken::Minus)) {
    IsPD = true;
    Parser.Lex();
  } else if (isExpr()) {
    if (Parser.parseExpression(MemOp.OuterDisp)) {
      return MatchOperand_ParseFail;
    }
    HasDisplacement = true;
  }

  if (getLexer().isNot(AsmToken::LParen)) {
    if (HasDisplacement) {
      MemOp.Op = M68kMemOp::Kind::Addr;
      Operands.push_back(
          M68kOperand::createMemOp(MemOp, Start, getLexer().getLoc()));
      return MatchOperand_Success;
    } else if (IsPD) {
      Error(getLexer().getLoc(), "expected (");
      return MatchOperand_ParseFail;
    }

    return MatchOperand_NoMatch;
  }
  Parser.Lex();

  // Check for constant dereference & MIT-style displacement
  if (!HasDisplacement && isExpr()) {
    if (Parser.parseExpression(MemOp.OuterDisp)) {
      return MatchOperand_ParseFail;
    }
    HasDisplacement = true;

    // If we're not followed by a comma, we're a constant dereference.
    if (getLexer().isNot(AsmToken::Comma)) {
      MemOp.Op = M68kMemOp::Kind::Addr;
      Operands.push_back(
          M68kOperand::createMemOp(MemOp, Start, getLexer().getLoc()));
      return MatchOperand_Success;
    }

    Parser.Lex();
  }

  Result = parseRegister(MemOp.OuterReg);
  if (Result == MatchOperand_ParseFail) {
    return MatchOperand_ParseFail;
  }

  if (Result != MatchOperand_Success) {
    Error(getLexer().getLoc(), "expected register");
    return MatchOperand_ParseFail;
  }

  // Check for Index.
  bool HasIndex = false;
  if (Parser.getTok().is(AsmToken::Comma)) {
    Parser.Lex();

    Result = parseRegister(MemOp.InnerReg);
    if (Result == MatchOperand_ParseFail) {
      return Result;
    }

    if (Result == MatchOperand_NoMatch) {
      Error(getLexer().getLoc(), "expected register");
      return MatchOperand_ParseFail;
    }

    // TODO: parse size, scale and inner displacement.
    MemOp.Size = 4;
    MemOp.Scale = 1;
    MemOp.InnerDisp = MCConstantExpr::create(0, Parser.getContext(), true, 4);
    HasIndex = true;
  }

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

  bool IsPI = false;
  if (!IsPD && Parser.getTok().is(AsmToken::Plus)) {
    Parser.Lex();
    IsPI = true;
  }

  SMLoc End = getLexer().getLoc();

  unsigned OpCount = IsPD + IsPI + (HasIndex || HasDisplacement);
  if (OpCount > 1) {
    Error(Start, "only one of post-increment, pre-decrement or displacement "
                 "can be used");
    return MatchOperand_ParseFail;
  }

  if (IsPD) {
    MemOp.Op = M68kMemOp::Kind::RegPreDecrement;
  } else if (IsPI) {
    MemOp.Op = M68kMemOp::Kind::RegPostIncrement;
  } else if (HasIndex) {
    MemOp.Op = M68kMemOp::Kind::RegIndirectDisplacementIndex;
  } else if (HasDisplacement) {
    MemOp.Op = M68kMemOp::Kind::RegIndirectDisplacement;
  } else {
    MemOp.Op = M68kMemOp::Kind::RegIndirect;
  }

  Operands.push_back(M68kOperand::createMemOp(MemOp, Start, End));
  return MatchOperand_Success;
}

OperandMatchResultTy
M68kAsmParser::parseRegOrMoveMask(OperandVector &Operands) {
  SMLoc Start = getLexer().getLoc();
  M68kMemOp MemOp(M68kMemOp::Kind::RegMask);
  MemOp.RegMask = 0;

  for (;;) {
    bool IsFirstRegister =
        (MemOp.Op == M68kMemOp::Kind::RegMask) && (MemOp.RegMask == 0);

    unsigned FirstRegister;
    auto Result = parseRegister(FirstRegister);
    if (IsFirstRegister && (Result == llvm::MatchOperand_NoMatch)) {
      return MatchOperand_NoMatch;
    }
    if (Result != llvm::MatchOperand_Success) {
      Error(getLexer().getLoc(), "expected start register");
      return MatchOperand_ParseFail;
    }

    unsigned LastRegister = FirstRegister;
    if (getLexer().is(AsmToken::Minus)) {
      getLexer().Lex();
      Result = parseRegister(LastRegister);
      if (Result != llvm::MatchOperand_Success) {
        Error(getLexer().getLoc(), "expected end register");
        return MatchOperand_ParseFail;
      }
    }

    unsigned FirstRegisterIndex = getRegisterIndex(FirstRegister);
    unsigned LastRegisterIndex = getRegisterIndex(LastRegister);

    uint16_t NumNewBits = LastRegisterIndex - FirstRegisterIndex + 1;
    uint16_t NewMaskBits = ((1 << NumNewBits) - 1) << FirstRegisterIndex;

    if (IsFirstRegister && (FirstRegister == LastRegister)) {
      // First register range is a single register, simplify to just Reg
      // so that it matches more operands.
      MemOp.Op = M68kMemOp::Kind::Reg;
      MemOp.OuterReg = FirstRegister;
    } else {
      if (MemOp.Op == M68kMemOp::Kind::Reg) {
        // This is the second register being specified - expand the Reg operand
        // into a mask first.
        MemOp.Op = M68kMemOp::Kind::RegMask;
        MemOp.RegMask = 1 << getRegisterIndex(MemOp.OuterReg);

        if (MemOp.RegMask == 0) {
          Error(getLexer().getLoc(),
                "special registers cannot be used in register masks");
          return MatchOperand_ParseFail;
        }
      }

      if ((FirstRegisterIndex >= 16) || (LastRegisterIndex >= 16)) {
        Error(getLexer().getLoc(),
              "special registers cannot be used in register masks");
        return MatchOperand_ParseFail;
      }

      if (NewMaskBits & MemOp.RegMask) {
        Error(getLexer().getLoc(), "conflicting masked registers");
        return MatchOperand_ParseFail;
      }

      MemOp.RegMask |= NewMaskBits;
    }

    if (getLexer().isNot(AsmToken::Slash)) {
      break;
    }

    getLexer().Lex();
  }

  Operands.push_back(
      M68kOperand::createMemOp(MemOp, Start, getLexer().getLoc()));
  return MatchOperand_Success;
}

void M68kAsmParser::eatComma() {
  if (Parser.getTok().is(AsmToken::Comma)) {
    Parser.Lex();
  }
}

bool M68kAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
                                     SMLoc NameLoc, OperandVector &Operands) {
  SMLoc Start = getLexer().getLoc();
  Operands.push_back(M68kOperand::createToken(Name, Start, Start));

  bool First = true;
  while (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
    if (!First) {
      eatComma();
    } else {
      First = false;
    }

    auto MatchResult = MatchOperandParserImpl(Operands, Name);
    if (MatchResult == MatchOperand_Success) {
      continue;
    }

    // Add custom operand formats here...
    SMLoc Loc = getLexer().getLoc();
    Parser.eatToEndOfStatement();
    return Error(Loc, "unexpected token parsing operands");
  }

  // Eat EndOfStatement.
  Parser.Lex();
  return false;
}

bool M68kAsmParser::ParseDirective(AsmToken DirectiveID) { return true; }

bool M68kAsmParser::invalidOperand(SMLoc const &Loc,
                                   OperandVector const &Operands,
                                   uint64_t const &ErrorInfo) {
  SMLoc ErrorLoc = Loc;
  char const *Diag = 0;

  if (ErrorInfo != ~0U) {
    if (ErrorInfo >= Operands.size()) {
      Diag = "too few operands for instruction.";
    } else {
      auto const &Op = (M68kOperand const &)*Operands[ErrorInfo];
      if (Op.getStartLoc() != SMLoc()) {
        ErrorLoc = Op.getStartLoc();
      }
    }
  }

  if (!Diag) {
    Diag = "invalid operand for instruction";
  }

  return Error(ErrorLoc, Diag);
}

bool M68kAsmParser::missingFeature(llvm::SMLoc const &Loc,
                                   uint64_t const &ErrorInfo) {
  return Error(Loc, "instruction requires a CPU feature not currently enabled");
}

bool M68kAsmParser::emit(MCInst &Inst, SMLoc const &Loc,
                         MCStreamer &Out) const {
  Inst.setLoc(Loc);
  Out.emitInstruction(Inst, STI);

  return false;
}

bool M68kAsmParser::MatchAndEmitInstruction(SMLoc Loc, unsigned &Opcode,
                                            OperandVector &Operands,
                                            MCStreamer &Out,
                                            uint64_t &ErrorInfo,
                                            bool MatchingInlineAsm) {
  MCInst Inst;
  unsigned MatchResult =
      MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);

  switch (MatchResult) {
  case Match_Success:
    return emit(Inst, Loc, Out);
  case Match_MissingFeature:
    return missingFeature(Loc, ErrorInfo);
  case Match_InvalidOperand:
    return invalidOperand(Loc, Operands, ErrorInfo);
  case Match_MnemonicFail:
    return Error(Loc, "invalid instruction");
  default:
    return true;
  }
}

void M68kOperand::print(raw_ostream &OS) const {
  switch (Kind) {
  case KindTy::Invalid:
    OS << "invalid";
    break;

  case KindTy::Token:
    OS << "token '" << Token << "'";
    break;

  case KindTy::Imm:
    OS << "immediate " << Imm;
    break;

  case KindTy::MemOp:
    MemOp.print(OS);
    break;
  }
}
