//===-- M68kInstrInfo.cpp - M68k Instruction Information --------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file contains the M68k declaration of the TargetInstrInfo class.
///
//===----------------------------------------------------------------------===//

#include "M68kInstrInfo.h"

#include "M68kInstrBuilder.h"
#include "M68kMachineFunction.h"
#include "M68kTargetMachine.h"
#include "MCTargetDesc/M68kMCCodeEmitter.h"

#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/CodeGen/LivePhysRegs.h"
#include "llvm/CodeGen/LiveVariables.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Regex.h"

#include <functional>

using namespace llvm;

#define DEBUG_TYPE "M68k-instr-info"

#define GET_INSTRINFO_CTOR_DTOR
#include "M68kGenInstrInfo.inc"

// Pin the vtable to this file.
void M68kInstrInfo::anchor() {}

M68kInstrInfo::M68kInstrInfo(const M68kSubtarget &STI)
    : M68kGenInstrInfo(M68k::ADJCALLSTACKDOWN, M68k::ADJCALLSTACKUP, 0,
                       M68k::RET),
      Subtarget(STI), RI(STI) {}

static M68k::CondCode getCondFromBranchOpc(unsigned BrOpc) {
  switch (BrOpc) {
  default:
    return M68k::COND_INVALID;
  case M68k::Beq8:
    return M68k::COND_EQ;
  case M68k::Bne8:
    return M68k::COND_NE;
  case M68k::Blt8:
    return M68k::COND_LT;
  case M68k::Ble8:
    return M68k::COND_LE;
  case M68k::Bgt8:
    return M68k::COND_GT;
  case M68k::Bge8:
    return M68k::COND_GE;
  case M68k::Bcs8:
    return M68k::COND_CS;
  case M68k::Bls8:
    return M68k::COND_LS;
  case M68k::Bhi8:
    return M68k::COND_HI;
  case M68k::Bcc8:
    return M68k::COND_CC;
  case M68k::Bmi8:
    return M68k::COND_MI;
  case M68k::Bpl8:
    return M68k::COND_PL;
  case M68k::Bvs8:
    return M68k::COND_VS;
  case M68k::Bvc8:
    return M68k::COND_VC;
  }
}

bool M68kInstrInfo::AnalyzeBranchImpl(MachineBasicBlock &MBB,
                                      MachineBasicBlock *&TBB,
                                      MachineBasicBlock *&FBB,
                                      SmallVectorImpl<MachineOperand> &Cond,
                                      bool AllowModify) const {

  auto UncondBranch =
      std::pair<MachineBasicBlock::reverse_iterator, MachineBasicBlock *>{
          MBB.rend(), nullptr};

  // Erase any instructions if allowed at the end of the scope.
  std::vector<std::reference_wrapper<llvm::MachineInstr>> EraseList;
  auto FinalizeOnReturn = llvm::make_scope_exit([&EraseList] {
    std::for_each(EraseList.begin(), EraseList.end(),
                  [](auto &ref) { ref.get().eraseFromParent(); });
  });

  // Start from the bottom of the block and work up, examining the
  // terminator instructions.
  for (auto iter = MBB.rbegin(); iter != MBB.rend(); iter = std::next(iter)) {

    unsigned Opcode = iter->getOpcode();

    if (iter->isDebugInstr())
      continue;

    // Working from the bottom, when we see a non-terminator instruction, we're
    // done.
    if (!isUnpredicatedTerminator(*iter))
      break;

    // A terminator that isn't a branch can't easily be handled by this
    // analysis.
    if (!iter->isBranch())
      return true;

    // Handle unconditional branches.
    if (Opcode == M68k::BRA8 || Opcode == M68k::BRA16) {
      if (!iter->getOperand(0).isMBB())
        return true;
      UncondBranch = {iter, iter->getOperand(0).getMBB()};

      // TBB is used to indicate the unconditional destination.
      TBB = UncondBranch.second;

      if (!AllowModify)
        continue;

      // If the block has any instructions after a JMP, erase them.
      EraseList.insert(EraseList.begin(), MBB.rbegin(), iter);

      Cond.clear();
      FBB = nullptr;

      // Erase the JMP if it's equivalent to a fall-through.
      if (MBB.isLayoutSuccessor(UncondBranch.second)) {
        TBB = nullptr;
        EraseList.push_back(*iter);
        UncondBranch = {MBB.rend(), nullptr};
      }

      continue;
    }

    // Handle conditional branches.
    auto BranchCode = M68k::GetCondFromBranchOpc(Opcode);

    // Can't handle indirect branch.
    if (BranchCode == M68k::COND_INVALID)
      return true;

    // In practice we should never have an undef CCR operand, if we do
    // abort here as we are not prepared to preserve the flag.
    // ??? Is this required?
    // if (iter->getOperand(1).isUndef())
    //   return true;

    // Working from the bottom, handle the first conditional branch.
    if (Cond.empty()) {
      if (!iter->getOperand(0).isMBB())
        return true;
      MachineBasicBlock *CondBranchTarget = iter->getOperand(0).getMBB();

      // If we see something like this:
      //
      //     bcc l1
      //     bra l2
      //     ...
      //   l1:
      //     ...
      //   l2:
      if (UncondBranch.first != MBB.rend()) {

        assert(std::next(UncondBranch.first) == iter && "Wrong block layout.");

        // And we are allowed to modify the block and the target block of the
        // conditional branch is the direct successor of this block:
        //
        //     bcc l1
        //     bra l2
        //   l1:
        //     ...
        //   l2:
        //
        // we change it to this if allowed:
        //
        //     bncc l2
        //   l1:
        //     ...
        //   l2:
        //
        // Which is a bit more efficient.
        if (AllowModify && MBB.isLayoutSuccessor(CondBranchTarget)) {

          BranchCode = GetOppositeBranchCondition(BranchCode);
          unsigned BNCC = GetCondBranchFromCond(BranchCode);

          BuildMI(MBB, *UncondBranch.first, MBB.rfindDebugLoc(iter), get(BNCC))
              .addMBB(UncondBranch.second);

          EraseList.push_back(*iter);
          EraseList.push_back(*UncondBranch.first);

          TBB = UncondBranch.second;
          FBB = nullptr;
          Cond.push_back(MachineOperand::CreateImm(BranchCode));

          // Otherwise preserve TBB, FBB and Cond as requested
        } else {
          TBB = CondBranchTarget;
          FBB = UncondBranch.second;
          Cond.push_back(MachineOperand::CreateImm(BranchCode));
        }

        UncondBranch = {MBB.rend(), nullptr};
        continue;
      }

      TBB = CondBranchTarget;
      FBB = nullptr;
      Cond.push_back(MachineOperand::CreateImm(BranchCode));

      continue;
    }

    // Handle subsequent conditional branches. Only handle the case where all
    // conditional branches branch to the same destination and their condition
    // opcodes fit one of the special multi-branch idioms.
    assert(Cond.size() == 1);
    assert(TBB);

    // If the conditions are the same, we can leave them alone.
    auto OldBranchCode = static_cast<M68k::CondCode>(Cond[0].getImm());
    if (!iter->getOperand(0).isMBB())
      return true;
    auto NewTBB = iter->getOperand(0).getMBB();
    if (OldBranchCode == BranchCode && TBB == NewTBB)
      continue;

    // If they differ we cannot do much here.
    return true;
  }

  return false;
}

bool M68kInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
                                  MachineBasicBlock *&TBB,
                                  MachineBasicBlock *&FBB,
                                  SmallVectorImpl<MachineOperand> &Cond,
                                  bool AllowModify) const {
  return AnalyzeBranchImpl(MBB, TBB, FBB, Cond, AllowModify);
}

unsigned M68kInstrInfo::removeBranch(MachineBasicBlock &MBB,
                                     int *BytesRemoved) const {
  assert(!BytesRemoved && "code size not handled");

  MachineBasicBlock::iterator I = MBB.end();
  unsigned Count = 0;

  while (I != MBB.begin()) {
    --I;
    if (I->isDebugValue())
      continue;
    if (I->getOpcode() != M68k::BRA8 &&
        getCondFromBranchOpc(I->getOpcode()) == M68k::COND_INVALID)
      break;
    // Remove the branch.
    I->eraseFromParent();
    I = MBB.end();
    ++Count;
  }

  return Count;
}

unsigned M68kInstrInfo::insertBranch(
    MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB,
    ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded) const {
  // Shouldn't be a fall through.
  assert(TBB && "InsertBranch must not be told to insert a fallthrough");
  assert((Cond.size() == 1 || Cond.size() == 0) &&
         "M68k branch conditions have one component!");
  assert(!BytesAdded && "code size not handled");

  if (Cond.empty()) {
    // Unconditional branch?
    assert(!FBB && "Unconditional branch with multiple successors!");
    BuildMI(&MBB, DL, get(M68k::BRA8)).addMBB(TBB);
    return 1;
  }

  // If FBB is null, it is implied to be a fall-through block.
  bool FallThru = FBB == nullptr;

  // Conditional branch.
  unsigned Count = 0;
  M68k::CondCode CC = (M68k::CondCode)Cond[0].getImm();
  unsigned Opc = GetCondBranchFromCond(CC);
  BuildMI(&MBB, DL, get(Opc)).addMBB(TBB);
  ++Count;
  if (!FallThru) {
    // Two-way Conditional branch. Insert the second branch.
    BuildMI(&MBB, DL, get(M68k::BRA8)).addMBB(FBB);
    ++Count;
  }
  return Count;
}

void M68kInstrInfo::AddSExt(MachineBasicBlock &MBB,
                            MachineBasicBlock::iterator I, DebugLoc DL,
                            unsigned Reg, MVT From, MVT To) const {
  if (From == MVT::i8) {
    unsigned R = Reg;
    // EXT16 requires i16 register
    if (To == MVT::i32) {
      R = RI.getSubReg(Reg, M68k::MxSubRegIndex16Lo);
      assert(R && "No viable SUB register available");
    }
    BuildMI(MBB, I, DL, get(M68k::EXT16), R).addReg(R);
  }

  if (To == MVT::i32)
    BuildMI(MBB, I, DL, get(M68k::EXT32), Reg).addReg(Reg);
}

void M68kInstrInfo::AddZExt(MachineBasicBlock &MBB,
                            MachineBasicBlock::iterator I, DebugLoc DL,
                            unsigned Reg, MVT From, MVT To) const {

  unsigned Mask, And;
  if (From == MVT::i8)
    Mask = 0xFF;
  else
    Mask = 0xFFFF;

  if (To == MVT::i16)
    And = M68k::AND16di;
  else // i32
    And = M68k::AND32di;

  // TODO use xor r,r to decrease size
  BuildMI(MBB, I, DL, get(And), Reg).addReg(Reg).addImm(Mask);
}

bool M68kInstrInfo::ExpandMOVX_RR(MachineInstrBuilder &MIB, MVT MVTDst,
                                  MVT MVTSrc) const {
  unsigned Move = MVTDst == MVT::i16 ? M68k::MOV16rr : M68k::MOV32rr;
  Register Dst = MIB->getOperand(0).getReg();
  Register Src = MIB->getOperand(1).getReg();

  assert(Dst != Src && "You cannot use the same Regs with MOVX_RR");

  const auto &TRI = getRegisterInfo();

  const auto *RCDst = TRI.getMaximalPhysRegClass(Dst, MVTDst);
  const auto *RCSrc = TRI.getMaximalPhysRegClass(Src, MVTSrc);

  assert(RCDst && RCSrc && "Wrong use of MOVX_RR");
  assert(RCDst != RCSrc && "You cannot use the same Reg Classes with MOVX_RR");

  // We need to find the super source register that matches the size of Dst
  unsigned SSrc = RI.getMatchingMegaReg(Src, RCDst);
  assert(SSrc && "No viable MEGA register available");

  DebugLoc DL = MIB->getDebugLoc();

  // If it happens to that super source register is the destination register
  // we do nothing
  if (Dst == SSrc) {
    LLVM_DEBUG(dbgs() << "Remove " << *MIB.getInstr() << '\n');
    MIB->eraseFromParent();
  } else { // otherwise we need to MOV
    LLVM_DEBUG(dbgs() << "Expand " << *MIB.getInstr() << " to MOV\n");
    MIB->setDesc(get(Move));
    MIB->getOperand(1).setReg(SSrc);
  }

  return true;
}

/// Expand SExt MOVE pseudos into a MOV and a EXT if the operands are two
/// different registers or just EXT if it is the same register
bool M68kInstrInfo::ExpandMOVSZX_RR(MachineInstrBuilder &MIB, bool IsSigned,
                                    MVT MVTDst, MVT MVTSrc) const {
  LLVM_DEBUG(dbgs() << "Expand " << *MIB.getInstr() << " to ");

  unsigned Move;

  if (MVTDst == MVT::i16)
    Move = M68k::MOV16rr;
  else // i32
    Move = M68k::MOV32rr;

  Register Dst = MIB->getOperand(0).getReg();
  Register Src = MIB->getOperand(1).getReg();

  assert(Dst != Src && "You cannot use the same Regs with MOVSX_RR");

  const auto &TRI = getRegisterInfo();

  const auto *RCDst = TRI.getMaximalPhysRegClass(Dst, MVTDst);
  const auto *RCSrc = TRI.getMaximalPhysRegClass(Src, MVTSrc);

  assert(RCDst && RCSrc && "Wrong use of MOVSX_RR");
  assert(RCDst != RCSrc && "You cannot use the same Reg Classes with MOVSX_RR");

  // We need to find the super source register that matches the size of Dst
  unsigned SSrc = RI.getMatchingMegaReg(Src, RCDst);
  assert(SSrc && "No viable MEGA register available");

  MachineBasicBlock &MBB = *MIB->getParent();
  DebugLoc DL = MIB->getDebugLoc();

  if (Dst != SSrc) {
    LLVM_DEBUG(dbgs() << "Move and " << '\n');
    BuildMI(MBB, MIB.getInstr(), DL, get(Move), Dst).addReg(SSrc);
  }

  if (IsSigned) {
    LLVM_DEBUG(dbgs() << "Sign Extend" << '\n');
    AddSExt(MBB, MIB.getInstr(), DL, Dst, MVTSrc, MVTDst);
  } else {
    LLVM_DEBUG(dbgs() << "Zero Extend" << '\n');
    AddZExt(MBB, MIB.getInstr(), DL, Dst, MVTSrc, MVTDst);
  }

  MIB->eraseFromParent();

  return true;
}

bool M68kInstrInfo::ExpandMOVSZX_RM(MachineInstrBuilder &MIB, bool IsSigned,
                                    const MCInstrDesc &Desc, MVT MVTDst,
                                    MVT MVTSrc) const {
  LLVM_DEBUG(dbgs() << "Expand " << *MIB.getInstr() << " to LOAD and ");

  Register Dst = MIB->getOperand(0).getReg();

  // We need the subreg of Dst to make instruction verifier happy because the
  // real machine instruction consumes and produces values of the same size and
  // the registers the will be used here fall into different classes and this
  // makes IV cry. We could use a bigger operation, but this will put some
  // pressure on cache and memory, so no.
  unsigned SubDst =
      RI.getSubReg(Dst, MVTSrc == MVT::i8 ? M68k::MxSubRegIndex8Lo
                                          : M68k::MxSubRegIndex16Lo);
  assert(SubDst && "No viable SUB register available");

  // Make this a plain move
  MIB->setDesc(Desc);
  MIB->getOperand(0).setReg(SubDst);

  MachineBasicBlock::iterator I = MIB.getInstr();
  I++;
  MachineBasicBlock &MBB = *MIB->getParent();
  DebugLoc DL = MIB->getDebugLoc();

  if (IsSigned) {
    LLVM_DEBUG(dbgs() << "Sign Extend" << '\n');
    AddSExt(MBB, I, DL, Dst, MVTSrc, MVTDst);
  } else {
    LLVM_DEBUG(dbgs() << "Zero Extend" << '\n');
    AddZExt(MBB, I, DL, Dst, MVTSrc, MVTDst);
  }

  return true;
}

bool M68kInstrInfo::ExpandPUSH_POP(MachineInstrBuilder &MIB,
                                   const MCInstrDesc &Desc, bool IsPush) const {
  MachineBasicBlock::iterator I = MIB.getInstr();
  I++;
  MachineBasicBlock &MBB = *MIB->getParent();
  MachineOperand MO = MIB->getOperand(0);
  DebugLoc DL = MIB->getDebugLoc();
  if (IsPush)
    BuildMI(MBB, I, DL, Desc).addReg(RI.getStackRegister()).add(MO);
  else
    BuildMI(MBB, I, DL, Desc, MO.getReg()).addReg(RI.getStackRegister());

  MIB->eraseFromParent();
  return true;
}

bool M68kInstrInfo::ExpandCCR(MachineInstrBuilder &MIB, bool IsToCCR) const {

  // Replace the pseudo instruction with the real one
  if (IsToCCR)
    MIB->setDesc(get(M68k::MOV16cd));
  else
    // FIXME M68010 or later is required
    MIB->setDesc(get(M68k::MOV16dc));

  // Promote used register to the next class
  auto &Opd = MIB->getOperand(1);
  Opd.setReg(getRegisterInfo().getMatchingSuperReg(
      Opd.getReg(), M68k::MxSubRegIndex8Lo, &M68k::DR16RegClass));

  return true;
}

bool M68kInstrInfo::ExpandMOVEM(MachineInstrBuilder &MIB,
                                const MCInstrDesc &Desc, bool IsRM) const {
  int Reg = 0, Offset = 0, Base = 0;
  auto XR32 = RI.getRegClass(M68k::XR32RegClassID);
  auto DL = MIB->getDebugLoc();
  auto MI = MIB.getInstr();
  auto &MBB = *MIB->getParent();

  if (IsRM) {
    Reg = MIB->getOperand(0).getReg();
    Offset = MIB->getOperand(1).getImm();
    Base = MIB->getOperand(2).getReg();
  } else {
    Offset = MIB->getOperand(0).getImm();
    Base = MIB->getOperand(1).getReg();
    Reg = MIB->getOperand(2).getReg();
  }

  // If the register is not in XR32 then it is smaller than 32 bit, we
  // implicitly promote it to 32
  if (!XR32->contains(Reg)) {
    Reg = RI.getMatchingMegaReg(Reg, XR32);
    assert(Reg && "Has not meaningful MEGA register");
  }

  unsigned Mask = 1 << RI.getSpillRegisterOrder(Reg);
  if (IsRM) {
    BuildMI(MBB, MI, DL, Desc)
        .addImm(Mask)
        .addImm(Offset)
        .addReg(Base)
        .addReg(Reg, RegState::ImplicitDefine)
        .copyImplicitOps(*MIB);
  } else {
    BuildMI(MBB, MI, DL, Desc)
        .addImm(Offset)
        .addReg(Base)
        .addImm(Mask)
        .addReg(Reg, RegState::Implicit)
        .copyImplicitOps(*MIB);
  }

  MIB->eraseFromParent();

  return true;
}

/// Expand a single-def pseudo instruction to a two-addr
/// instruction with two undef reads of the register being defined.
/// This is used for mapping:
///   %d0 = SETCS_C32d
/// to:
///   %d0 = SUBX32dd %d0<undef>, %d0<undef>
///
static bool Expand2AddrUndef(MachineInstrBuilder &MIB,
                             const MCInstrDesc &Desc) {
  assert(Desc.getNumOperands() == 3 && "Expected two-addr instruction.");
  Register Reg = MIB->getOperand(0).getReg();
  MIB->setDesc(Desc);

  // MachineInstr::addOperand() will insert explicit operands before any
  // implicit operands.
  MIB.addReg(Reg, RegState::Undef).addReg(Reg, RegState::Undef);
  // But we don't trust that.
  assert(MIB->getOperand(1).getReg() == Reg &&
         MIB->getOperand(2).getReg() == Reg && "Misplaced operand");
  return true;
}

bool M68kInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
  MachineInstrBuilder MIB(*MI.getParent()->getParent(), MI);
  switch (MI.getOpcode()) {
  case M68k::PUSH8d:
    return ExpandPUSH_POP(MIB, get(M68k::MOV8ed), true);
  case M68k::PUSH16d:
    return ExpandPUSH_POP(MIB, get(M68k::MOV16er), true);
  case M68k::PUSH32r:
    return ExpandPUSH_POP(MIB, get(M68k::MOV32er), true);

  case M68k::POP8d:
    return ExpandPUSH_POP(MIB, get(M68k::MOV8do), false);
  case M68k::POP16d:
    return ExpandPUSH_POP(MIB, get(M68k::MOV16ro), false);
  case M68k::POP32r:
    return ExpandPUSH_POP(MIB, get(M68k::MOV32ro), false);

  case M68k::SETCS_C8d:
    return Expand2AddrUndef(MIB, get(M68k::SUBX8dd));
  case M68k::SETCS_C16d:
    return Expand2AddrUndef(MIB, get(M68k::SUBX16dd));
  case M68k::SETCS_C32d:
    return Expand2AddrUndef(MIB, get(M68k::SUBX32dd));
  }
  return false;
}

bool M68kInstrInfo::isPCRelRegisterOperandLegal(
    const MachineOperand &MO) const {
  assert(MO.isReg());

  // Check whether this MO belongs to an instruction with addressing mode 'k',
  // Refer to TargetInstrInfo.h for more information about this function.

  const MachineInstr *MI = MO.getParent();
  const unsigned NameIndices = M68kInstrNameIndices[MI->getOpcode()];
  StringRef InstrName(&M68kInstrNameData[NameIndices]);
  const unsigned OperandNo = MI->getOperandNo(&MO);

  // If this machine operand is the 2nd operand, then check
  // whether the instruction has destination addressing mode 'k'.
  if (OperandNo == 1)
    return Regex("[A-Z]+(8|16|32)k[a-z](_TC)?$").match(InstrName);

  // If this machine operand is the last one, then check
  // whether the instruction has source addressing mode 'k'.
  if (OperandNo == MI->getNumExplicitOperands() - 1)
    return Regex("[A-Z]+(8|16|32)[a-z]k(_TC)?$").match(InstrName);

  return false;
}

void M68kInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
                                MachineBasicBlock::iterator MI,
                                const DebugLoc &DL, MCRegister DstReg,
                                MCRegister SrcReg, bool KillSrc) const {
  unsigned Opc = 0;

  // First deal with the normal symmetric copies.
  if (M68k::XR32RegClass.contains(DstReg, SrcReg))
    Opc = M68k::MOV32rr;
  else if (M68k::XR16RegClass.contains(DstReg, SrcReg))
    Opc = M68k::MOV16rr;
  else if (M68k::DR8RegClass.contains(DstReg, SrcReg))
    Opc = M68k::MOV8dd;

  if (Opc) {
    BuildMI(MBB, MI, DL, get(Opc), DstReg)
        .addReg(SrcReg, getKillRegState(KillSrc));
    return;
  }

  // Now deal with asymmetrically sized copies. The cases that follow are upcast
  // moves.
  //
  // NOTE
  // These moves are not aware of type nature of these values and thus
  // won't do any SExt or ZExt and upper bits will basically contain garbage.
  MachineInstrBuilder MIB(*MBB.getParent(), MI);
  if (M68k::DR8RegClass.contains(SrcReg)) {
    if (M68k::XR16RegClass.contains(DstReg))
      Opc = M68k::MOVXd16d8;
    else if (M68k::XR32RegClass.contains(DstReg))
      Opc = M68k::MOVXd32d8;
  } else if (M68k::XR16RegClass.contains(SrcReg) &&
             M68k::XR32RegClass.contains(DstReg))
    Opc = M68k::MOVXd32d16;

  if (Opc) {
    BuildMI(MBB, MI, DL, get(Opc), DstReg)
        .addReg(SrcReg, getKillRegState(KillSrc));
    return;
  }

  bool FromCCR = SrcReg == M68k::CCR;
  bool FromSR = SrcReg == M68k::SR;
  bool ToCCR = DstReg == M68k::CCR;
  bool ToSR = DstReg == M68k::SR;

  if (FromCCR) {
    assert(M68k::DR8RegClass.contains(DstReg) &&
           "Need DR8 register to copy CCR");
    Opc = M68k::MOV8dc;
  } else if (ToCCR) {
    assert(M68k::DR8RegClass.contains(SrcReg) &&
           "Need DR8 register to copy CCR");
    Opc = M68k::MOV8cd;
  } else if (FromSR || ToSR)
    llvm_unreachable("Cannot emit SR copy instruction");

  if (Opc) {
    BuildMI(MBB, MI, DL, get(Opc), DstReg)
        .addReg(SrcReg, getKillRegState(KillSrc));
    return;
  }

  LLVM_DEBUG(dbgs() << "Cannot copy " << RI.getName(SrcReg) << " to "
                    << RI.getName(DstReg) << '\n');
  llvm_unreachable("Cannot emit physreg copy instruction");
}

namespace {
unsigned getLoadStoreRegOpcode(unsigned Reg, const TargetRegisterClass *RC,
                               const TargetRegisterInfo *TRI,
                               const M68kSubtarget &STI, bool load) {
  switch (TRI->getRegSizeInBits(*RC)) {
  default:
    llvm_unreachable("Unknown spill size");
  case 8:
    if (M68k::DR8RegClass.hasSubClassEq(RC))
      return load ? M68k::MOV8dp : M68k::MOV8pd;
    if (M68k::CCRCRegClass.hasSubClassEq(RC))
      return load ? M68k::MOV16cp : M68k::MOV16pc;

    llvm_unreachable("Unknown 1-byte regclass");
  case 16:
    assert(M68k::XR16RegClass.hasSubClassEq(RC) && "Unknown 2-byte regclass");
    return load ? M68k::MOVM16mp_P : M68k::MOVM16pm_P;
  case 32:
    assert(M68k::XR32RegClass.hasSubClassEq(RC) && "Unknown 4-byte regclass");
    return load ? M68k::MOVM32mp_P : M68k::MOVM32pm_P;
  }
}

unsigned getStoreRegOpcode(unsigned SrcReg, const TargetRegisterClass *RC,
                           const TargetRegisterInfo *TRI,
                           const M68kSubtarget &STI) {
  return getLoadStoreRegOpcode(SrcReg, RC, TRI, STI, false);
}

unsigned getLoadRegOpcode(unsigned DstReg, const TargetRegisterClass *RC,
                          const TargetRegisterInfo *TRI,
                          const M68kSubtarget &STI) {
  return getLoadStoreRegOpcode(DstReg, RC, TRI, STI, true);
}
} // end anonymous namespace

bool M68kInstrInfo::getStackSlotRange(const TargetRegisterClass *RC,
                                      unsigned SubIdx, unsigned &Size,
                                      unsigned &Offset,
                                      const MachineFunction &MF) const {
  // The slot size must be the maximum size so we can easily use MOVEM.L
  Size = 4;
  Offset = 0;
  return true;
}

void M68kInstrInfo::storeRegToStackSlot(
    MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register SrcReg,
    bool IsKill, int FrameIndex, const TargetRegisterClass *RC,
    const TargetRegisterInfo *TRI, Register VReg) const {
  const MachineFrameInfo &MFI = MBB.getParent()->getFrameInfo();
  assert(MFI.getObjectSize(FrameIndex) >= TRI->getSpillSize(*RC) &&
         "Stack slot is too small to store");

  unsigned Opc = getStoreRegOpcode(SrcReg, RC, TRI, Subtarget);
  DebugLoc DL = MBB.findDebugLoc(MI);
  // (0,FrameIndex) <- $reg
  M68k::addFrameReference(BuildMI(MBB, MI, DL, get(Opc)), FrameIndex)
      .addReg(SrcReg, getKillRegState(IsKill));
}

void M68kInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
                                         MachineBasicBlock::iterator MI,
                                         Register DstReg, int FrameIndex,
                                         const TargetRegisterClass *RC,
                                         const TargetRegisterInfo *TRI,
                                         Register VReg) const {
  const MachineFrameInfo &MFI = MBB.getParent()->getFrameInfo();
  assert(MFI.getObjectSize(FrameIndex) >= TRI->getSpillSize(*RC) &&
         "Stack slot is too small to load");

  unsigned Opc = getLoadRegOpcode(DstReg, RC, TRI, Subtarget);
  DebugLoc DL = MBB.findDebugLoc(MI);
  M68k::addFrameReference(BuildMI(MBB, MI, DL, get(Opc), DstReg), FrameIndex);
}

/// Return a virtual register initialized with the the global base register
/// value. Output instructions required to initialize the register in the
/// function entry block, if necessary.
///
/// TODO Move this function to M68kMachineFunctionInfo.
unsigned M68kInstrInfo::getGlobalBaseReg(MachineFunction *MF) const {
  M68kMachineFunctionInfo *MxFI = MF->getInfo<M68kMachineFunctionInfo>();
  unsigned GlobalBaseReg = MxFI->getGlobalBaseReg();
  if (GlobalBaseReg != 0)
    return GlobalBaseReg;

  // Create the register. The code to initialize it is inserted later,
  // by the CGBR pass (below).
  //
  // NOTE
  // Normally M68k uses A5 register as global base pointer but this will
  // create unnecessary spill if we use less then 4 registers in code; since A5
  // is callee-save anyway we could try to allocate caller-save first and if
  // lucky get one, otherwise it does not really matter which callee-save to
  // use.
  MachineRegisterInfo &RegInfo = MF->getRegInfo();
  GlobalBaseReg = RegInfo.createVirtualRegister(&M68k::AR32_NOSPRegClass);
  MxFI->setGlobalBaseReg(GlobalBaseReg);
  return GlobalBaseReg;
}

std::pair<unsigned, unsigned>
M68kInstrInfo::decomposeMachineOperandsTargetFlags(unsigned TF) const {
  return std::make_pair(TF, 0u);
}

ArrayRef<std::pair<unsigned, const char *>>
M68kInstrInfo::getSerializableDirectMachineOperandTargetFlags() const {
  using namespace M68kII;
  static const std::pair<unsigned, const char *> TargetFlags[] = {
      {MO_ABSOLUTE_ADDRESS, "m68k-absolute"},
      {MO_PC_RELATIVE_ADDRESS, "m68k-pcrel"},
      {MO_GOT, "m68k-got"},
      {MO_GOTOFF, "m68k-gotoff"},
      {MO_GOTPCREL, "m68k-gotpcrel"},
      {MO_PLT, "m68k-plt"}};
  return ArrayRef(TargetFlags);
}

namespace {
/// Create Global Base Reg pass. This initializes the PIC global base register
struct CGBR : public MachineFunctionPass {
  static char ID;
  CGBR() : MachineFunctionPass(ID) {}

  bool runOnMachineFunction(MachineFunction &MF) override {
    const M68kSubtarget &STI = MF.getSubtarget<M68kSubtarget>();
    M68kMachineFunctionInfo *MxFI = MF.getInfo<M68kMachineFunctionInfo>();

    unsigned GlobalBaseReg = MxFI->getGlobalBaseReg();

    // If we didn't need a GlobalBaseReg, don't insert code.
    if (GlobalBaseReg == 0)
      return false;

    // Insert the set of GlobalBaseReg into the first MBB of the function
    MachineBasicBlock &FirstMBB = MF.front();
    MachineBasicBlock::iterator MBBI = FirstMBB.begin();
    DebugLoc DL = FirstMBB.findDebugLoc(MBBI);
    const M68kInstrInfo *TII = STI.getInstrInfo();

    // Generate lea (__GLOBAL_OFFSET_TABLE_,%PC), %A5
    BuildMI(FirstMBB, MBBI, DL, TII->get(M68k::LEA32q), GlobalBaseReg)
        .addExternalSymbol("_GLOBAL_OFFSET_TABLE_", M68kII::MO_GOTPCREL);

    return true;
  }

  StringRef getPassName() const override {
    return "M68k PIC Global Base Reg Initialization";
  }

  void getAnalysisUsage(AnalysisUsage &AU) const override {
    AU.setPreservesCFG();
    MachineFunctionPass::getAnalysisUsage(AU);
  }
};
} // namespace

char CGBR::ID = 0;
FunctionPass *llvm::createM68kGlobalBaseRegPass() { return new CGBR(); }
