forked from OSchip/llvm-project
179 lines
4.6 KiB
C++
179 lines
4.6 KiB
C++
//===-- 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_sf");
|
|
Features.push_back("+fpuv3_df");
|
|
break;
|
|
case FK_FPV3_HF:
|
|
Features.push_back("+fpuv3_hf");
|
|
break;
|
|
case FK_FPV3_HSF:
|
|
Features.push_back("+fpuv3_hf");
|
|
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;
|
|
}
|