//===-- TargetParser - Parser for target features ---------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements a target parser to recognise CSKY hardware features
// such as CPU/ARCH names.
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/CSKYTargetParser.h"
#include "llvm/ADT/StringSwitch.h"

using namespace llvm;

bool CSKY::getFPUFeatures(CSKYFPUKind CSKYFPUKind,
                          std::vector<StringRef> &Features) {

  if (CSKYFPUKind >= FK_LAST || CSKYFPUKind == FK_INVALID)
    return false;

  switch (CSKYFPUKind) {
  case FK_AUTO:
    Features.push_back("+fpuv2_sf");
    Features.push_back("+fpuv2_df");
    Features.push_back("+fdivdu");
    break;
  case FK_FPV2:
    Features.push_back("+fpuv2_sf");
    Features.push_back("+fpuv2_df");
    break;
  case FK_FPV2_DIVD:
    Features.push_back("+fpuv2_sf");
    Features.push_back("+fpuv2_df");
    Features.push_back("+fdivdu");
    break;
  case FK_FPV2_SF:
    Features.push_back("+fpuv2_sf");
    break;
  case FK_FPV3:
    Features.push_back("+fpuv3_hf");
    Features.push_back("+fpuv3_hi");
    Features.push_back("+fpuv3_sf");
    Features.push_back("+fpuv3_df");
    break;
  case FK_FPV3_HF:
    Features.push_back("+fpuv3_hf");
    Features.push_back("+fpuv3_hi");
    break;
  case FK_FPV3_HSF:
    Features.push_back("+fpuv3_hf");
    Features.push_back("+fpuv3_hi");
    Features.push_back("+fpuv3_sf");
    break;
  case FK_FPV3_SDF:
    Features.push_back("+fpuv3_sf");
    Features.push_back("+fpuv3_df");
    break;
  default:
    llvm_unreachable("Unknown FPU Kind");
    return false;
  }

  return true;
}

// ======================================================= //
// Information by ID
// ======================================================= //

StringRef CSKY::getArchName(ArchKind AK) {
  return ARCHNames[static_cast<unsigned>(AK)].getName();
}

// The default cpu's name is same as arch name.
StringRef CSKY::getDefaultCPU(StringRef Arch) {
  ArchKind AK = parseArch(Arch);
  if (AK == CSKY::ArchKind::INVALID)
    return StringRef();

  return Arch;
}

// ======================================================= //
// Parsers
// ======================================================= //
CSKY::ArchKind CSKY::parseArch(StringRef Arch) {
  for (const auto A : ARCHNames) {
    if (A.getName() == Arch)
      return A.ID;
  }

  return CSKY::ArchKind::INVALID;
}

CSKY::ArchKind CSKY::parseCPUArch(StringRef CPU) {
  for (const auto C : CPUNames) {
    if (CPU == C.getName())
      return C.ArchID;
  }

  return CSKY::ArchKind::INVALID;
}

uint64_t CSKY::parseArchExt(StringRef ArchExt) {
  for (const auto &A : CSKYARCHExtNames) {
    if (ArchExt == A.getName())
      return A.ID;
  }
  return AEK_INVALID;
}

void CSKY::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values) {
  for (const CpuNames<CSKY::ArchKind> &Arch : CPUNames) {
    if (Arch.ArchID != CSKY::ArchKind::INVALID)
      Values.push_back(Arch.getName());
  }
}

StringRef CSKY::getFPUName(unsigned FPUKind) {
  if (FPUKind >= FK_LAST)
    return StringRef();
  return FPUNames[FPUKind].getName();
}

CSKY::FPUVersion CSKY::getFPUVersion(unsigned FPUKind) {
  if (FPUKind >= FK_LAST)
    return FPUVersion::NONE;
  return FPUNames[FPUKind].FPUVer;
}

uint64_t CSKY::getDefaultExtensions(StringRef CPU) {
  return StringSwitch<uint64_t>(CPU)
#define CSKY_CPU_NAME(NAME, ID, DEFAULT_EXT)                                   \
  .Case(NAME, ARCHNames[static_cast<unsigned>(ArchKind::ID)].archBaseExt |     \
                  DEFAULT_EXT)
#include "llvm/Support/CSKYTargetParser.def"
      .Default(CSKY::AEK_INVALID);
}

StringRef CSKY::getArchExtName(uint64_t ArchExtKind) {
  for (const auto &AE : CSKYARCHExtNames)
    if (ArchExtKind == AE.ID)
      return AE.getName();
  return StringRef();
}

static bool stripNegationPrefix(StringRef &Name) {
  if (Name.startswith("no")) {
    Name = Name.substr(2);
    return true;
  }
  return false;
}

StringRef CSKY::getArchExtFeature(StringRef ArchExt) {
  bool Negated = stripNegationPrefix(ArchExt);
  for (const auto &AE : CSKYARCHExtNames) {
    if (AE.Feature && ArchExt == AE.getName())
      return StringRef(Negated ? AE.NegFeature : AE.Feature);
  }

  return StringRef();
}

bool CSKY::getExtensionFeatures(uint64_t Extensions,
                                std::vector<StringRef> &Features) {
  if (Extensions == CSKY::AEK_INVALID)
    return false;

  for (const auto &AE : CSKYARCHExtNames) {
    if ((Extensions & AE.ID) == AE.ID && AE.Feature)
      Features.push_back(AE.Feature);
  }

  return true;
}
