//===---- 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(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 &Values) { for (const auto &C : PPCCPUInfo) Values.emplace_back(C.Name); } void fillValidTuneCPUList(SmallVectorImpl &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