//===-- 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/MCAsmLexer.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(MCRegister &RegNo, SMLoc Loc, StringRef RegisterName);
  OperandMatchResultTy parseRegister(MCRegister &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(MCRegister &RegNo, SMLoc &StartLoc,
                     SMLoc &EndLoc) override;
  OperandMatchResultTy tryParseRegister(MCRegister &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;
  MCRegister OuterReg;
  MCRegister 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;
    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;
  bool isFPDReg() 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);

  // Imm for TRAP instruction
  bool isTrapImm() const;
  // Imm for BKPT instruction
  bool isBkptImm() const;

  // 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_REGISTER_MATCHER
#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,  M68k::FP0, M68k::FP1,
      M68k::FP2, M68k::FP3, M68k::FP4, M68k::FP5, M68k::FP6, M68k::FP7};
  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;
  if (Register >= M68k::FP0 && Register <= M68k::FP7)
    return Register - M68k::FP0 + 16;

  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;
}

bool M68kOperand::isTrapImm() const {
  int64_t Value;
  if (!isImm() || !Expr->evaluateAsAbsolute(Value))
    return false;

  return isUInt<4>(Value);
}

bool M68kOperand::isBkptImm() const {
  int64_t Value;
  if (!isImm() || !Expr->evaluateAsAbsolute(Value))
    return false;

  return isUInt<3>(Value);
}

// 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, bool FPDR = false) {
  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;

  case M68k::FP0:
  case M68k::FP1:
  case M68k::FP2:
  case M68k::FP3:
  case M68k::FP4:
  case M68k::FP5:
  case M68k::FP6:
  case M68k::FP7:
    return FPDR;

  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);
}

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

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(MCRegister &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;
    }
  } else if (StringRef(RegisterNameLower).starts_with("fp") &&
             RegisterNameLower.size() > 2) {
    // Floating point data register.
    auto RegIndex = unsigned(RegisterNameLower[2] - '0');
    if (RegIndex >= 8 || RegisterNameLower.size() > 3)
      return false;
    RegNo = getRegisterByIndex(16 + RegIndex);
    return true;
  }

  return false;
}

OperandMatchResultTy M68kAsmParser::parseRegister(MCRegister &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(MCRegister &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(MCRegister &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);

    MCRegister 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;
    }

    MCRegister 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: {
    int64_t Value;
    Expr->evaluateAsAbsolute(Value);
    OS << "immediate " << Value;
    break;
  }

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