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 namespace llvm { 19 namespace PPC { 20 21 struct CPUInfo { 22 StringLiteral Name; 23 // FIXME: add the features field for this CPU. 24 }; 25 26 constexpr CPUInfo PPCCPUInfo[] = { 27 #define PPC_CPU(Name, Linux_SUPPORT_METHOD, LinuxID, AIX_SUPPORT_METHOD, \ 28 AIXID) \ 29 {Name}, 30 #include "llvm/TargetParser/PPCTargetParser.def" 31 }; 32 33 static const CPUInfo *getCPUInfoByName(StringRef CPU) { 34 for (auto &C : PPCCPUInfo) 35 if (C.Name == CPU) 36 return &C; 37 return nullptr; 38 } 39 40 StringRef normalizeCPUName(StringRef CPUName) { 41 // Clang/LLVM does not actually support code generation 42 // for the 405 CPU. However, there are uses of this CPU ID 43 // in projects that previously used GCC and rely on Clang 44 // accepting it. Clang has always ignored it and passed the 45 // generic CPU ID to the back end. 46 return StringSwitch<StringRef>(CPUName) 47 .Cases("common", "405", "generic") 48 .Cases("ppc440", "440fp", "440") 49 .Cases("630", "power3", "pwr3") 50 .Case("G3", "g3") 51 .Case("G4", "g4") 52 .Case("G4+", "g4+") 53 .Case("8548", "e500") 54 .Case("ppc970", "970") 55 .Case("G5", "g5") 56 .Case("ppca2", "a2") 57 .Case("power4", "pwr4") 58 .Case("power5", "pwr5") 59 .Case("power5x", "pwr5x") 60 .Case("power5+", "pwr5+") 61 .Case("power6", "pwr6") 62 .Case("power6x", "pwr6x") 63 .Case("power7", "pwr7") 64 .Case("power8", "pwr8") 65 .Case("power9", "pwr9") 66 .Case("power10", "pwr10") 67 .Case("power11", "pwr11") 68 .Cases("powerpc", "powerpc32", "ppc") 69 .Case("powerpc64", "ppc64") 70 .Case("powerpc64le", "ppc64le") 71 .Default(CPUName); 72 } 73 74 void fillValidCPUList(SmallVectorImpl<StringRef> &Values) { 75 for (const auto &C : PPCCPUInfo) 76 Values.emplace_back(C.Name); 77 } 78 79 void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) { 80 for (const auto &C : PPCCPUInfo) 81 Values.emplace_back(C.Name); 82 } 83 84 bool isValidCPU(StringRef CPU) { 85 const CPUInfo *Info = getCPUInfoByName(CPU); 86 if (!Info) 87 return false; 88 return true; 89 } 90 91 StringRef getNormalizedPPCTargetCPU(const Triple &T, StringRef CPUName) { 92 if (!CPUName.empty()) { 93 if (CPUName == "native") { 94 StringRef CPU = sys::getHostCPUName(); 95 if (!CPU.empty() && CPU != "generic") 96 return CPU; 97 } 98 99 StringRef CPU = normalizeCPUName(CPUName); 100 if (CPU != "generic" && CPU != "native") 101 return CPU; 102 } 103 104 // LLVM may default to generating code for the native CPU, but, like gcc, we 105 // default to a more generic option for each architecture. (except on AIX) 106 if (T.isOSAIX()) 107 return "pwr7"; 108 else if (T.getArch() == Triple::ppc64le) 109 return "ppc64le"; 110 else if (T.getArch() == Triple::ppc64) 111 return "ppc64"; 112 113 return "ppc"; 114 } 115 116 StringRef getNormalizedPPCTuneCPU(const Triple &T, StringRef CPUName) { 117 return getNormalizedPPCTargetCPU(T, CPUName); 118 } 119 120 } // namespace PPC 121 } // namespace llvm 122