blob: 493f253cd716bdd93108d4eeb6345d1e990a3617 [file] [log] [blame]
//===-- 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/TargetParser/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/TargetParser/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;
}