150 lines · cpp
1//===---- PPCTargetParser.cpp - Parser for target features ------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements a target parser to recognise hardware features10// for PPC CPUs.11//12//===----------------------------------------------------------------------===//13 14#include "llvm/TargetParser/PPCTargetParser.h"15#include "llvm/ADT/StringSwitch.h"16#include "llvm/TargetParser/Host.h"17 18#define GET_SUBTARGETFEATURES_ENUM19#define GET_SUBTARGETFEATURES_KV20#include "llvm/TargetParser/PPCGenTargetFeatures.inc"21 22namespace llvm {23namespace PPC {24 25struct CPUInfo {26 StringLiteral Name;27 // FIXME: add the features field for this CPU.28};29 30constexpr CPUInfo PPCCPUInfo[] = {31#define PPC_CPU(Name, Linux_SUPPORT_METHOD, LinuxID, AIX_SUPPORT_METHOD, \32 AIXID) \33 {Name},34#include "llvm/TargetParser/PPCTargetParser.def"35};36 37static const CPUInfo *getCPUInfoByName(StringRef CPU) {38 for (auto &C : PPCCPUInfo)39 if (C.Name == CPU)40 return &C;41 return nullptr;42}43 44StringRef normalizeCPUName(StringRef CPUName) {45 // Clang/LLVM does not actually support code generation46 // for the 405 CPU. However, there are uses of this CPU ID47 // in projects that previously used GCC and rely on Clang48 // accepting it. Clang has always ignored it and passed the49 // generic CPU ID to the back end.50 return StringSwitch<StringRef>(CPUName)51 .Cases({"common", "405"}, "generic")52 .Cases({"ppc440", "440fp"}, "440")53 .Cases({"630", "power3"}, "pwr3")54 .Case("G3", "g3")55 .Case("G4", "g4")56 .Case("G4+", "g4+")57 .Case("8548", "e500")58 .Case("ppc970", "970")59 .Case("G5", "g5")60 .Case("ppca2", "a2")61 .Case("power4", "pwr4")62 .Case("power5", "pwr5")63 .Case("power5x", "pwr5x")64 .Case("power5+", "pwr5+")65 .Case("power6", "pwr6")66 .Case("power6x", "pwr6x")67 .Case("power7", "pwr7")68 .Case("power8", "pwr8")69 .Case("power9", "pwr9")70 .Case("power10", "pwr10")71 .Case("power11", "pwr11")72 .Cases({"powerpc", "powerpc32"}, "ppc")73 .Case("powerpc64", "ppc64")74 .Case("powerpc64le", "ppc64le")75 .Default(CPUName);76}77 78void fillValidCPUList(SmallVectorImpl<StringRef> &Values) {79 for (const auto &C : PPCCPUInfo)80 Values.emplace_back(C.Name);81}82 83void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) {84 for (const auto &C : PPCCPUInfo)85 Values.emplace_back(C.Name);86}87 88bool isValidCPU(StringRef CPU) {89 const CPUInfo *Info = getCPUInfoByName(CPU);90 if (!Info)91 return false;92 return true;93}94 95StringRef getNormalizedPPCTargetCPU(const Triple &T, StringRef CPUName) {96 if (!CPUName.empty()) {97 if (CPUName == "native") {98 StringRef CPU = sys::getHostCPUName();99 if (!CPU.empty() && CPU != "generic")100 return CPU;101 }102 103 StringRef CPU = normalizeCPUName(CPUName);104 if (CPU != "generic" && CPU != "native")105 return CPU;106 }107 108 // LLVM may default to generating code for the native CPU, but, like gcc, we109 // default to a more generic option for each architecture. (except on AIX)110 if (T.isOSAIX())111 return "pwr7";112 else if (T.getArch() == Triple::ppc64le)113 return "ppc64le";114 else if (T.getArch() == Triple::ppc64)115 return "ppc64";116 117 return "ppc";118}119 120StringRef getNormalizedPPCTuneCPU(const Triple &T, StringRef CPUName) {121 return getNormalizedPPCTargetCPU(T, CPUName);122}123 124std::optional<StringMap<bool>> getPPCDefaultTargetFeatures(const Triple &T,125 StringRef CPU) {126 std::optional<StringMap<bool>> FeaturesOpt =127 getCPUDefaultTargetFeatures(CPU, BasicPPCSubTypeKV, BasicPPCFeatureKV);128 129 if (!FeaturesOpt.has_value())130 return std::nullopt;131 132 StringMap<bool> Features = FeaturesOpt.value();133 // FIXME: We need to check for the processor model 8548, since the backend134 // does not support this processor. When this processor model is implemented135 // within the backend, the following code can be removed.136 if (CPU == "8548")137 Features["spe"] = true;138 139 // The target feature `quadword-atomics` is only supported for 64-bit140 // POWER8 and above.141 if (!T.isArch64Bit()) {142 auto It = Features.find("quadword-atomics");143 if (It != Features.end())144 It->second = false;145 }146 return Features;147}148} // namespace PPC149} // namespace llvm150