//===- MipsArchTree.cpp --------------------------------------------------===//
//
// 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
//
//===---------------------------------------------------------------------===//
//
// This file contains a helper function for the Writer.
//
//===---------------------------------------------------------------------===//

#include "InputFiles.h"
#include "SymbolTable.h"
#include "Writer.h"

#include "lld/Common/ErrorHandler.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/Object/ELF.h"
#include "llvm/Support/MipsABIFlags.h"

using namespace llvm;
using namespace llvm::object;
using namespace llvm::ELF;

namespace lld {
namespace elf {

namespace {
struct ArchTreeEdge {
  uint32_t child;
  uint32_t parent;
};

struct FileFlags {
  InputFile *file;
  uint32_t flags;
};
} // namespace

static StringRef getAbiName(uint32_t flags) {
  switch (flags) {
  case 0:
    return "n64";
  case EF_MIPS_ABI2:
    return "n32";
  case EF_MIPS_ABI_O32:
    return "o32";
  case EF_MIPS_ABI_O64:
    return "o64";
  case EF_MIPS_ABI_EABI32:
    return "eabi32";
  case EF_MIPS_ABI_EABI64:
    return "eabi64";
  default:
    return "unknown";
  }
}

static StringRef getNanName(bool isNan2008) {
  return isNan2008 ? "2008" : "legacy";
}

static StringRef getFpName(bool isFp64) { return isFp64 ? "64" : "32"; }

static void checkFlags(ArrayRef<FileFlags> files) {
  assert(!files.empty() && "expected non-empty file list");

  uint32_t abi = files[0].flags & (EF_MIPS_ABI | EF_MIPS_ABI2);
  bool nan = files[0].flags & EF_MIPS_NAN2008;
  bool fp = files[0].flags & EF_MIPS_FP64;

  for (const FileFlags &f : files) {
    if (config->is64 && f.flags & EF_MIPS_MICROMIPS)
      error(toString(f.file) + ": microMIPS 64-bit is not supported");

    uint32_t abi2 = f.flags & (EF_MIPS_ABI | EF_MIPS_ABI2);
    if (abi != abi2)
      error(toString(f.file) + ": ABI '" + getAbiName(abi2) +
            "' is incompatible with target ABI '" + getAbiName(abi) + "'");

    bool nan2 = f.flags & EF_MIPS_NAN2008;
    if (nan != nan2)
      error(toString(f.file) + ": -mnan=" + getNanName(nan2) +
            " is incompatible with target -mnan=" + getNanName(nan));

    bool fp2 = f.flags & EF_MIPS_FP64;
    if (fp != fp2)
      error(toString(f.file) + ": -mfp" + getFpName(fp2) +
            " is incompatible with target -mfp" + getFpName(fp));
  }
}

static uint32_t getMiscFlags(ArrayRef<FileFlags> files) {
  uint32_t ret = 0;
  for (const FileFlags &f : files)
    ret |= f.flags &
           (EF_MIPS_ABI | EF_MIPS_ABI2 | EF_MIPS_ARCH_ASE | EF_MIPS_NOREORDER |
            EF_MIPS_MICROMIPS | EF_MIPS_NAN2008 | EF_MIPS_32BITMODE);
  return ret;
}

static uint32_t getPicFlags(ArrayRef<FileFlags> files) {
  // Check PIC/non-PIC compatibility.
  bool isPic = files[0].flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
  for (const FileFlags &f : files.slice(1)) {
    bool isPic2 = f.flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
    if (isPic && !isPic2)
      warn(toString(f.file) +
           ": linking non-abicalls code with abicalls code " +
           toString(files[0].file));
    if (!isPic && isPic2)
      warn(toString(f.file) +
           ": linking abicalls code with non-abicalls code " +
           toString(files[0].file));
  }

  // Compute the result PIC/non-PIC flag.
  uint32_t ret = files[0].flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
  for (const FileFlags &f : files.slice(1))
    ret &= f.flags & (EF_MIPS_PIC | EF_MIPS_CPIC);

  // PIC code is inherently CPIC and may not set CPIC flag explicitly.
  if (ret & EF_MIPS_PIC)
    ret |= EF_MIPS_CPIC;
  return ret;
}

static ArchTreeEdge archTree[] = {
    // MIPS32R6 and MIPS64R6 are not compatible with other extensions
    // MIPS64R2 extensions.
    {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON3, EF_MIPS_ARCH_64R2},
    {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON2, EF_MIPS_ARCH_64R2},
    {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON, EF_MIPS_ARCH_64R2},
    {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_LS3A, EF_MIPS_ARCH_64R2},
    // MIPS64 extensions.
    {EF_MIPS_ARCH_64 | EF_MIPS_MACH_SB1, EF_MIPS_ARCH_64},
    {EF_MIPS_ARCH_64 | EF_MIPS_MACH_XLR, EF_MIPS_ARCH_64},
    {EF_MIPS_ARCH_64R2, EF_MIPS_ARCH_64},
    // MIPS V extensions.
    {EF_MIPS_ARCH_64, EF_MIPS_ARCH_5},
    // R5000 extensions.
    {EF_MIPS_ARCH_4 | EF_MIPS_MACH_5500, EF_MIPS_ARCH_4 | EF_MIPS_MACH_5400},
    // MIPS IV extensions.
    {EF_MIPS_ARCH_4 | EF_MIPS_MACH_5400, EF_MIPS_ARCH_4},
    {EF_MIPS_ARCH_4 | EF_MIPS_MACH_9000, EF_MIPS_ARCH_4},
    {EF_MIPS_ARCH_5, EF_MIPS_ARCH_4},
    // VR4100 extensions.
    {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4111, EF_MIPS_ARCH_3 | EF_MIPS_MACH_4100},
    {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4120, EF_MIPS_ARCH_3 | EF_MIPS_MACH_4100},
    // MIPS III extensions.
    {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4010, EF_MIPS_ARCH_3},
    {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4100, EF_MIPS_ARCH_3},
    {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4650, EF_MIPS_ARCH_3},
    {EF_MIPS_ARCH_3 | EF_MIPS_MACH_5900, EF_MIPS_ARCH_3},
    {EF_MIPS_ARCH_3 | EF_MIPS_MACH_LS2E, EF_MIPS_ARCH_3},
    {EF_MIPS_ARCH_3 | EF_MIPS_MACH_LS2F, EF_MIPS_ARCH_3},
    {EF_MIPS_ARCH_4, EF_MIPS_ARCH_3},
    // MIPS32 extensions.
    {EF_MIPS_ARCH_32R2, EF_MIPS_ARCH_32},
    // MIPS II extensions.
    {EF_MIPS_ARCH_3, EF_MIPS_ARCH_2},
    {EF_MIPS_ARCH_32, EF_MIPS_ARCH_2},
    // MIPS I extensions.
    {EF_MIPS_ARCH_1 | EF_MIPS_MACH_3900, EF_MIPS_ARCH_1},
    {EF_MIPS_ARCH_2, EF_MIPS_ARCH_1},
};

static bool isArchMatched(uint32_t newFlags, uint32_t res) {
  if (newFlags == res)
    return true;
  if (newFlags == EF_MIPS_ARCH_32 && isArchMatched(EF_MIPS_ARCH_64, res))
    return true;
  if (newFlags == EF_MIPS_ARCH_32R2 && isArchMatched(EF_MIPS_ARCH_64R2, res))
    return true;
  for (const auto &edge : archTree) {
    if (res == edge.child) {
      res = edge.parent;
      if (res == newFlags)
        return true;
    }
  }
  return false;
}

static StringRef getMachName(uint32_t flags) {
  switch (flags & EF_MIPS_MACH) {
  case EF_MIPS_MACH_NONE:
    return "";
  case EF_MIPS_MACH_3900:
    return "r3900";
  case EF_MIPS_MACH_4010:
    return "r4010";
  case EF_MIPS_MACH_4100:
    return "r4100";
  case EF_MIPS_MACH_4650:
    return "r4650";
  case EF_MIPS_MACH_4120:
    return "r4120";
  case EF_MIPS_MACH_4111:
    return "r4111";
  case EF_MIPS_MACH_5400:
    return "vr5400";
  case EF_MIPS_MACH_5900:
    return "vr5900";
  case EF_MIPS_MACH_5500:
    return "vr5500";
  case EF_MIPS_MACH_9000:
    return "rm9000";
  case EF_MIPS_MACH_LS2E:
    return "loongson2e";
  case EF_MIPS_MACH_LS2F:
    return "loongson2f";
  case EF_MIPS_MACH_LS3A:
    return "loongson3a";
  case EF_MIPS_MACH_OCTEON:
    return "octeon";
  case EF_MIPS_MACH_OCTEON2:
    return "octeon2";
  case EF_MIPS_MACH_OCTEON3:
    return "octeon3";
  case EF_MIPS_MACH_SB1:
    return "sb1";
  case EF_MIPS_MACH_XLR:
    return "xlr";
  default:
    return "unknown machine";
  }
}

static StringRef getArchName(uint32_t flags) {
  switch (flags & EF_MIPS_ARCH) {
  case EF_MIPS_ARCH_1:
    return "mips1";
  case EF_MIPS_ARCH_2:
    return "mips2";
  case EF_MIPS_ARCH_3:
    return "mips3";
  case EF_MIPS_ARCH_4:
    return "mips4";
  case EF_MIPS_ARCH_5:
    return "mips5";
  case EF_MIPS_ARCH_32:
    return "mips32";
  case EF_MIPS_ARCH_64:
    return "mips64";
  case EF_MIPS_ARCH_32R2:
    return "mips32r2";
  case EF_MIPS_ARCH_64R2:
    return "mips64r2";
  case EF_MIPS_ARCH_32R6:
    return "mips32r6";
  case EF_MIPS_ARCH_64R6:
    return "mips64r6";
  default:
    return "unknown arch";
  }
}

static std::string getFullArchName(uint32_t flags) {
  StringRef arch = getArchName(flags);
  StringRef mach = getMachName(flags);
  if (mach.empty())
    return arch.str();
  return (arch + " (" + mach + ")").str();
}

// There are (arguably too) many MIPS ISAs out there. Their relationships
// can be represented as a forest. If all input files have ISAs which
// reachable by repeated proceeding from the single child to the parent,
// these input files are compatible. In that case we need to return "highest"
// ISA. If there are incompatible input files, we show an error.
// For example, mips1 is a "parent" of mips2 and such files are compatible.
// Output file gets EF_MIPS_ARCH_2 flag. From the other side mips3 and mips32
// are incompatible because nor mips3 is a parent for misp32, nor mips32
// is a parent for mips3.
static uint32_t getArchFlags(ArrayRef<FileFlags> files) {
  uint32_t ret = files[0].flags & (EF_MIPS_ARCH | EF_MIPS_MACH);

  for (const FileFlags &f : files.slice(1)) {
    uint32_t newFlags = f.flags & (EF_MIPS_ARCH | EF_MIPS_MACH);

    // Check ISA compatibility.
    if (isArchMatched(newFlags, ret))
      continue;
    if (!isArchMatched(ret, newFlags)) {
      error("incompatible target ISA:\n>>> " + toString(files[0].file) + ": " +
            getFullArchName(ret) + "\n>>> " + toString(f.file) + ": " +
            getFullArchName(newFlags));
      return 0;
    }
    ret = newFlags;
  }
  return ret;
}

template <class ELFT> uint32_t calcMipsEFlags() {
  std::vector<FileFlags> v;
  for (InputFile *f : objectFiles)
    v.push_back({f, cast<ObjFile<ELFT>>(f)->getObj().getHeader()->e_flags});
  if (v.empty()) {
    // If we don't have any input files, we'll have to rely on the information
    // we can derive from emulation information, since this at least gets us
    // ABI.
    if (config->emulation.empty() || config->is64)
      return 0;
    return config->mipsN32Abi ? EF_MIPS_ABI2 : EF_MIPS_ABI_O32;
  }
  checkFlags(v);
  return getMiscFlags(v) | getPicFlags(v) | getArchFlags(v);
}

static int compareMipsFpAbi(uint8_t fpA, uint8_t fpB) {
  if (fpA == fpB)
    return 0;
  if (fpB == Mips::Val_GNU_MIPS_ABI_FP_ANY)
    return 1;
  if (fpB == Mips::Val_GNU_MIPS_ABI_FP_64A &&
      fpA == Mips::Val_GNU_MIPS_ABI_FP_64)
    return 1;
  if (fpB != Mips::Val_GNU_MIPS_ABI_FP_XX)
    return -1;
  if (fpA == Mips::Val_GNU_MIPS_ABI_FP_DOUBLE ||
      fpA == Mips::Val_GNU_MIPS_ABI_FP_64 ||
      fpA == Mips::Val_GNU_MIPS_ABI_FP_64A)
    return 1;
  return -1;
}

static StringRef getMipsFpAbiName(uint8_t fpAbi) {
  switch (fpAbi) {
  case Mips::Val_GNU_MIPS_ABI_FP_ANY:
    return "any";
  case Mips::Val_GNU_MIPS_ABI_FP_DOUBLE:
    return "-mdouble-float";
  case Mips::Val_GNU_MIPS_ABI_FP_SINGLE:
    return "-msingle-float";
  case Mips::Val_GNU_MIPS_ABI_FP_SOFT:
    return "-msoft-float";
  case Mips::Val_GNU_MIPS_ABI_FP_OLD_64:
    return "-mgp32 -mfp64 (old)";
  case Mips::Val_GNU_MIPS_ABI_FP_XX:
    return "-mfpxx";
  case Mips::Val_GNU_MIPS_ABI_FP_64:
    return "-mgp32 -mfp64";
  case Mips::Val_GNU_MIPS_ABI_FP_64A:
    return "-mgp32 -mfp64 -mno-odd-spreg";
  default:
    return "unknown";
  }
}

uint8_t getMipsFpAbiFlag(uint8_t oldFlag, uint8_t newFlag, StringRef fileName) {
  if (compareMipsFpAbi(newFlag, oldFlag) >= 0)
    return newFlag;
  if (compareMipsFpAbi(oldFlag, newFlag) < 0)
    error(fileName + ": floating point ABI '" + getMipsFpAbiName(newFlag) +
          "' is incompatible with target floating point ABI '" +
          getMipsFpAbiName(oldFlag) + "'");
  return oldFlag;
}

template <class ELFT> static bool isN32Abi(const InputFile *f) {
  if (auto *ef = dyn_cast<ELFFileBase>(f))
    return ef->template getObj<ELFT>().getHeader()->e_flags & EF_MIPS_ABI2;
  return false;
}

bool isMipsN32Abi(const InputFile *f) {
  switch (config->ekind) {
  case ELF32LEKind:
    return isN32Abi<ELF32LE>(f);
  case ELF32BEKind:
    return isN32Abi<ELF32BE>(f);
  case ELF64LEKind:
    return isN32Abi<ELF64LE>(f);
  case ELF64BEKind:
    return isN32Abi<ELF64BE>(f);
  default:
    llvm_unreachable("unknown Config->EKind");
  }
}

bool isMicroMips() { return config->eflags & EF_MIPS_MICROMIPS; }

bool isMipsR6() {
  uint32_t arch = config->eflags & EF_MIPS_ARCH;
  return arch == EF_MIPS_ARCH_32R6 || arch == EF_MIPS_ARCH_64R6;
}

template uint32_t calcMipsEFlags<ELF32LE>();
template uint32_t calcMipsEFlags<ELF32BE>();
template uint32_t calcMipsEFlags<ELF64LE>();
template uint32_t calcMipsEFlags<ELF64BE>();

} // namespace elf
} // namespace lld
