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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements a target parser to recognise hardware features 10 // 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_ENUM 19 #define GET_SUBTARGETFEATURES_KV 20 #include "llvm/TargetParser/PPCGenTargetFeatures.inc" 21 22 namespace llvm { 23 namespace PPC { 24 25 struct CPUInfo { 26 StringLiteral Name; 27 // FIXME: add the features field for this CPU. 28 }; 29 30 constexpr 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 37 static const CPUInfo *getCPUInfoByName(StringRef CPU) { 38 for (auto &C : PPCCPUInfo) 39 if (C.Name == CPU) 40 return &C; 41 return nullptr; 42 } 43 44 StringRef normalizeCPUName(StringRef CPUName) { 45 // Clang/LLVM does not actually support code generation 46 // for the 405 CPU. However, there are uses of this CPU ID 47 // in projects that previously used GCC and rely on Clang 48 // accepting it. Clang has always ignored it and passed the 49 // 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 78 void fillValidCPUList(SmallVectorImpl<StringRef> &Values) { 79 for (const auto &C : PPCCPUInfo) 80 Values.emplace_back(C.Name); 81 } 82 83 void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) { 84 for (const auto &C : PPCCPUInfo) 85 Values.emplace_back(C.Name); 86 } 87 88 bool isValidCPU(StringRef CPU) { 89 const CPUInfo *Info = getCPUInfoByName(CPU); 90 if (!Info) 91 return false; 92 return true; 93 } 94 95 StringRef 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, we 109 // 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 120 StringRef getNormalizedPPCTuneCPU(const Triple &T, StringRef CPUName) { 121 return getNormalizedPPCTargetCPU(T, CPUName); 122 } 123 124 std::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 backend 134 // does not support this processor. When this processor model is implemented 135 // 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-bit 140 // POWER8 and above. 141 if (Features.find("quadword-atomics") != Features.end() && !T.isArch64Bit()) 142 Features["quadword-atomics"] = false; 143 return Features; 144 } 145 } // namespace PPC 146 } // namespace llvm 147