blob: 422d758c772e1486b39709af49721f12a237272b [file] [log] [blame]
//===---- PPCTargetParser.cpp - Parser for target features ------*- 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
//
//===----------------------------------------------------------------------===//
//
// This file implements a target parser to recognise hardware features
// for PPC CPUs.
//
//===----------------------------------------------------------------------===//
#include "llvm/TargetParser/PPCTargetParser.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/TargetParser/Host.h"
namespace llvm {
namespace PPC {
struct CPUInfo {
StringLiteral Name;
// FIXME: add the features field for this CPU.
};
constexpr CPUInfo PPCCPUInfo[] = {
#define PPC_CPU(Name, Linux_SUPPORT_METHOD, LinuxID, AIX_SUPPORT_METHOD, \
AIXID) \
{Name},
#include "llvm/TargetParser/PPCTargetParser.def"
};
static const CPUInfo *getCPUInfoByName(StringRef CPU) {
for (auto &C : PPCCPUInfo)
if (C.Name == CPU)
return &C;
return nullptr;
}
StringRef normalizeCPUName(StringRef CPUName) {
// Clang/LLVM does not actually support code generation
// for the 405 CPU. However, there are uses of this CPU ID
// in projects that previously used GCC and rely on Clang
// accepting it. Clang has always ignored it and passed the
// generic CPU ID to the back end.
return StringSwitch<StringRef>(CPUName)
.Cases("common", "405", "generic")
.Cases("ppc440", "440fp", "440")
.Cases("630", "power3", "pwr3")
.Case("G3", "g3")
.Case("G4", "g4")
.Case("G4+", "g4+")
.Case("8548", "e500")
.Case("ppc970", "970")
.Case("G5", "g5")
.Case("ppca2", "a2")
.Case("power4", "pwr4")
.Case("power5", "pwr5")
.Case("power5x", "pwr5x")
.Case("power5+", "pwr5+")
.Case("power6", "pwr6")
.Case("power6x", "pwr6x")
.Case("power7", "pwr7")
.Case("power8", "pwr8")
.Case("power9", "pwr9")
.Case("power10", "pwr10")
.Case("power11", "pwr11")
.Cases("powerpc", "powerpc32", "ppc")
.Case("powerpc64", "ppc64")
.Case("powerpc64le", "ppc64le")
.Default(CPUName);
}
void fillValidCPUList(SmallVectorImpl<StringRef> &Values) {
for (const auto &C : PPCCPUInfo)
Values.emplace_back(C.Name);
}
void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) {
for (const auto &C : PPCCPUInfo)
Values.emplace_back(C.Name);
}
bool isValidCPU(StringRef CPU) {
const CPUInfo *Info = getCPUInfoByName(CPU);
if (!Info)
return false;
return true;
}
StringRef getNormalizedPPCTargetCPU(const Triple &T, StringRef CPUName) {
if (!CPUName.empty()) {
if (CPUName == "native") {
StringRef CPU = sys::getHostCPUName();
if (!CPU.empty() && CPU != "generic")
return CPU;
}
StringRef CPU = normalizeCPUName(CPUName);
if (CPU != "generic" && CPU != "native")
return CPU;
}
// LLVM may default to generating code for the native CPU, but, like gcc, we
// default to a more generic option for each architecture. (except on AIX)
if (T.isOSAIX())
return "pwr7";
else if (T.getArch() == Triple::ppc64le)
return "ppc64le";
else if (T.getArch() == Triple::ppc64)
return "ppc64";
return "ppc";
}
StringRef getNormalizedPPCTuneCPU(const Triple &T, StringRef CPUName) {
return getNormalizedPPCTargetCPU(T, CPUName);
}
} // namespace PPC
} // namespace llvm