//===-- M68kSubtarget.cpp - M68k Subtarget 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 implements the M68k specific subclass of TargetSubtargetInfo.
///
//===----------------------------------------------------------------------===//

#include "M68kSubtarget.h"
#include "GISel/M68kCallLowering.h"
#include "GISel/M68kLegalizerInfo.h"
#include "GISel/M68kRegisterBankInfo.h"

#include "M68k.h"
#include "M68kMachineFunction.h"
#include "M68kRegisterInfo.h"
#include "M68kTargetMachine.h"

#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/Function.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"

using namespace llvm;

#define DEBUG_TYPE "m68k-subtarget"

#define GET_SUBTARGETINFO_TARGET_DESC
#define GET_SUBTARGETINFO_CTOR
#include "M68kGenSubtargetInfo.inc"

extern bool FixGlobalBaseReg;

/// Select the M68k CPU for the given triple and cpu name.
static StringRef selectM68kCPU(Triple TT, StringRef CPU) {
  if (CPU.empty() || CPU == "generic") {
    CPU = "M68000";
  }
  return CPU;
}

void M68kSubtarget::anchor() {}

M68kSubtarget::M68kSubtarget(const Triple &TT, StringRef CPU, StringRef FS,
                             const M68kTargetMachine &TM)
    : M68kGenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS), TM(TM), TSInfo(),
      InstrInfo(initializeSubtargetDependencies(CPU, TT, FS, TM)),
      FrameLowering(*this, this->getStackAlignment()), TLInfo(TM, *this),
      TargetTriple(TT) {
  CallLoweringInfo.reset(new M68kCallLowering(*getTargetLowering()));
  Legalizer.reset(new M68kLegalizerInfo(*this));

  auto *RBI = new M68kRegisterBankInfo(*getRegisterInfo());
  RegBankInfo.reset(RBI);
  InstSelector.reset(createM68kInstructionSelector(TM, *this, *RBI));
}

const CallLowering *M68kSubtarget::getCallLowering() const {
  return CallLoweringInfo.get();
}

InstructionSelector *M68kSubtarget::getInstructionSelector() const {
  return InstSelector.get();
}

const LegalizerInfo *M68kSubtarget::getLegalizerInfo() const {
  return Legalizer.get();
}

const RegisterBankInfo *M68kSubtarget::getRegBankInfo() const {
  return RegBankInfo.get();
}

bool M68kSubtarget::isPositionIndependent() const {
  return TM.isPositionIndependent();
}

bool M68kSubtarget::isLegalToCallImmediateAddr() const { return true; }

bool M68kSubtarget::abiUsesSoftFloat() const { return true; }

M68kSubtarget &M68kSubtarget::initializeSubtargetDependencies(
    StringRef CPU, Triple TT, StringRef FS, const M68kTargetMachine &TM) {
  std::string CPUName = selectM68kCPU(TT, CPU).str();

  // Parse features string.
  ParseSubtargetFeatures(CPUName, CPUName, FS);

  // Initialize scheduling itinerary for the specified CPU.
  InstrItins = getInstrItineraryForCPU(CPUName);

  stackAlignment = 8;

  return *this;
}

//===----------------------------------------------------------------------===//
// Code Model
//
// Key assumptions:
//  - Whenever possible we use pc-rel encoding since it is smaller(16 bit) than
//    absolute(32 bit).
//  - GOT is reachable within 16 bit offset for both Small and Medium models.
//  - Code section is reachable within 16 bit offset for both models.
//
//  ---------------------+-------------------------+--------------------------
//                       |          Small          |          Medium
//                       +-------------------------+------------+-------------
//                       |   Static   |    PIC     |   Static   |    PIC
//  ---------------------+------------+------------+------------+-------------
//                branch |   pc-rel   |   pc-rel   |   pc-rel   |   pc-rel
//  ---------------------+------------+------------+------------+-------------
//           call global |    @PLT    |    @PLT    |    @PLT    |    @PLT
//  ---------------------+------------+------------+------------+-------------
//         call internal |   pc-rel   |   pc-rel   |   pc-rel   |   pc-rel
//  ---------------------+------------+------------+------------+-------------
//            data local |   pc-rel   |   pc-rel   |  ~pc-rel   |  ^pc-rel
//  ---------------------+------------+------------+------------+-------------
//       data local big* |   pc-rel   |   pc-rel   |  absolute  |  @GOTOFF
//  ---------------------+------------+------------+------------+-------------
//           data global |   pc-rel   |  @GOTPCREL |  ~pc-rel   |  @GOTPCREL
//  ---------------------+------------+------------+------------+-------------
//      data global big* |   pc-rel   |  @GOTPCREL |  absolute  |  @GOTPCREL
//  ---------------------+------------+------------+------------+-------------
//
// * Big data potentially cannot be reached within 16 bit offset and requires
//   special handling for old(x00 and x10) CPUs. Normally these symbols go into
//   separate .ldata section which mapped after normal .data and .text, but I
//   don't really know how this must be done for M68k atm... will try to dig
//   this info out from GCC. For now CPUs prior to M68020 will use static ref
//   for Static Model and @GOT based references for PIC.
//
// ~ These are absolute for older CPUs for now.
// ^ These are @GOTOFF for older CPUs for now.
//===----------------------------------------------------------------------===//

/// Classify a blockaddress reference for the current subtarget according to how
/// we should reference it in a non-pcrel context.
unsigned char M68kSubtarget::classifyBlockAddressReference() const {
  // Unless we start to support Large Code Model branching is always pc-rel
  return M68kII::MO_PC_RELATIVE_ADDRESS;
}

unsigned char
M68kSubtarget::classifyLocalReference(const GlobalValue *GV) const {
  switch (TM.getCodeModel()) {
  default:
    llvm_unreachable("Unsupported code model");
  case CodeModel::Small:
  case CodeModel::Kernel: {
    return M68kII::MO_PC_RELATIVE_ADDRESS;
  }
  case CodeModel::Medium: {
    if (isPositionIndependent()) {
      // On M68020 and better we can fit big any data offset into dips field.
      if (atLeastM68020()) {
        return M68kII::MO_PC_RELATIVE_ADDRESS;
      }
      // Otherwise we could check the data size and make sure it will fit into
      // 16 bit offset. For now we will be conservative and go with @GOTOFF
      return M68kII::MO_GOTOFF;
    } else {
      if (atLeastM68020()) {
        return M68kII::MO_PC_RELATIVE_ADDRESS;
      }
      return M68kII::MO_ABSOLUTE_ADDRESS;
    }
  }
  }
}

unsigned char M68kSubtarget::classifyExternalReference(const Module &M) const {
  if (TM.shouldAssumeDSOLocal(M, nullptr))
    return classifyLocalReference(nullptr);

  if (isPositionIndependent())
    return M68kII::MO_GOTPCREL;

  return M68kII::MO_GOT;
}

unsigned char
M68kSubtarget::classifyGlobalReference(const GlobalValue *GV) const {
  return classifyGlobalReference(GV, *GV->getParent());
}

unsigned char M68kSubtarget::classifyGlobalReference(const GlobalValue *GV,
                                                     const Module &M) const {
  if (TM.shouldAssumeDSOLocal(M, GV))
    return classifyLocalReference(GV);

  switch (TM.getCodeModel()) {
  default:
    llvm_unreachable("Unsupported code model");
  case CodeModel::Small:
  case CodeModel::Kernel: {
    if (isPositionIndependent())
      return M68kII::MO_GOTPCREL;
    return M68kII::MO_PC_RELATIVE_ADDRESS;
  }
  case CodeModel::Medium: {
    if (isPositionIndependent())
      return M68kII::MO_GOTPCREL;

    if (atLeastM68020())
      return M68kII::MO_PC_RELATIVE_ADDRESS;

    return M68kII::MO_ABSOLUTE_ADDRESS;
  }
  }
}

unsigned M68kSubtarget::getJumpTableEncoding() const {
  if (isPositionIndependent()) {
    // The only time we want to use GOTOFF(used when with EK_Custom32) is when
    // the potential delta between the jump target and table base can be larger
    // than displacement field, which is True for older CPUs(16 bit disp)
    // in Medium model(can have large data way beyond 16 bit).
    if (TM.getCodeModel() == CodeModel::Medium && !atLeastM68020())
      return MachineJumpTableInfo::EK_Custom32;

    return MachineJumpTableInfo::EK_LabelDifference32;
  }

  // In non-pic modes, just use the address of a block.
  return MachineJumpTableInfo::EK_BlockAddress;
}

unsigned char
M68kSubtarget::classifyGlobalFunctionReference(const GlobalValue *GV) const {
  return classifyGlobalFunctionReference(GV, *GV->getParent());
}

unsigned char
M68kSubtarget::classifyGlobalFunctionReference(const GlobalValue *GV,
                                               const Module &M) const {
  // local always use pc-rel referencing
  if (TM.shouldAssumeDSOLocal(M, GV))
    return M68kII::MO_NO_FLAG;

  // If the function is marked as non-lazy, generate an indirect call
  // which loads from the GOT directly. This avoids run-time overhead
  // at the cost of eager binding.
  auto *F = dyn_cast_or_null<Function>(GV);
  if (F && F->hasFnAttribute(Attribute::NonLazyBind)) {
    return M68kII::MO_GOTPCREL;
  }

  // otherwise linker will figure this out
  return M68kII::MO_PLT;
}
