//===-- 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 <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;
  unsigned Dst = MIB->getOperand(0).getReg();
  unsigned 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;

  unsigned Dst = MIB->getOperand(0).getReg();
  unsigned 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 ");

  unsigned 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.");
  unsigned 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());
  const auto *MI = MO.getParent();
  const uint8_t *Beads = M68k::getMCInstrBeads(MI->getOpcode());
  assert(*Beads);

  // Only addressing mode k has (non-pc) register with PCRel
  // So we're looking for EA Beads equal to
  // `3Bits<011>_1Bit<1>_2Bits<11>`
  // FIXME: There is an important caveat and two assumptions
  // here: The caveat is that EA encoding always sit on the LSB.
  // Where the assumptions are that if there are more than one
  // operands, the EA encoding for the source operand always sit
  // on the LSB. At the same time, k addressing mode can not be used
  // on destination operand.
  // The last assumption is kinda dirty so we need to find a way around
  // it
  const uint8_t EncEAk[3] = {0b011, 0b1, 0b11};
  for (const uint8_t Pat : EncEAk) {
    uint8_t Bead = *(Beads++);
    if (!Bead)
      return false;

    switch (Bead & 0xF) {
    default:
      return false;
    case M68kBeads::Bits1:
    case M68kBeads::Bits2:
    case M68kBeads::Bits3: {
      uint8_t Val = (Bead & 0xF0) >> 4;
      if (Val != Pat)
        return false;
    }
    }
  }
  return true;
}

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::MOVM8mp_P : M68k::MOVM8pm_P;
    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) const {
  const MachineFunction &MF = *MBB.getParent();
  assert(MF.getFrameInfo().getObjectSize(FrameIndex) == 4 &&
         "Stack slot too small for 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) const {
  const MachineFunction &MF = *MBB.getParent();
  assert(MF.getFrameInfo().getObjectSize(FrameIndex) == 4 &&
         "Stack slot too small for store");
  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 makeArrayRef(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(); }
