1 1.1 joerg //===--- PPC.cpp - PPC Helpers for Tools ------------------------*- C++ -*-===// 2 1.1 joerg // 3 1.1 joerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 1.1 joerg // See https://llvm.org/LICENSE.txt for license information. 5 1.1 joerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 1.1 joerg // 7 1.1 joerg //===----------------------------------------------------------------------===// 8 1.1 joerg 9 1.1 joerg #include "PPC.h" 10 1.1 joerg #include "ToolChains/CommonArgs.h" 11 1.1 joerg #include "clang/Driver/Driver.h" 12 1.1 joerg #include "clang/Driver/DriverDiagnostic.h" 13 1.1 joerg #include "clang/Driver/Options.h" 14 1.1 joerg #include "llvm/ADT/StringSwitch.h" 15 1.1 joerg #include "llvm/Option/ArgList.h" 16 1.1 joerg #include "llvm/Support/Host.h" 17 1.1 joerg 18 1.1 joerg using namespace clang::driver; 19 1.1 joerg using namespace clang::driver::tools; 20 1.1 joerg using namespace clang; 21 1.1 joerg using namespace llvm::opt; 22 1.1 joerg 23 1.1 joerg /// getPPCTargetCPU - Get the (LLVM) name of the PowerPC cpu we are targeting. 24 1.1 joerg std::string ppc::getPPCTargetCPU(const ArgList &Args) { 25 1.1 joerg if (Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ)) { 26 1.1 joerg StringRef CPUName = A->getValue(); 27 1.1 joerg 28 1.1 joerg if (CPUName == "native") { 29 1.1.1.2 joerg std::string CPU = std::string(llvm::sys::getHostCPUName()); 30 1.1 joerg if (!CPU.empty() && CPU != "generic") 31 1.1 joerg return CPU; 32 1.1 joerg else 33 1.1 joerg return ""; 34 1.1 joerg } 35 1.1 joerg 36 1.1 joerg return llvm::StringSwitch<const char *>(CPUName) 37 1.1 joerg .Case("common", "generic") 38 1.1 joerg .Case("440", "440") 39 1.1 joerg .Case("440fp", "440") 40 1.1 joerg .Case("450", "450") 41 1.1 joerg .Case("601", "601") 42 1.1 joerg .Case("602", "602") 43 1.1 joerg .Case("603", "603") 44 1.1 joerg .Case("603e", "603e") 45 1.1 joerg .Case("603ev", "603ev") 46 1.1 joerg .Case("604", "604") 47 1.1 joerg .Case("604e", "604e") 48 1.1 joerg .Case("620", "620") 49 1.1 joerg .Case("630", "pwr3") 50 1.1 joerg .Case("G3", "g3") 51 1.1 joerg .Case("7400", "7400") 52 1.1 joerg .Case("G4", "g4") 53 1.1 joerg .Case("7450", "7450") 54 1.1 joerg .Case("G4+", "g4+") 55 1.1 joerg .Case("750", "750") 56 1.1.1.2 joerg .Case("8548", "e500") 57 1.1 joerg .Case("970", "970") 58 1.1 joerg .Case("G5", "g5") 59 1.1 joerg .Case("a2", "a2") 60 1.1.1.2 joerg .Case("e500", "e500") 61 1.1 joerg .Case("e500mc", "e500mc") 62 1.1 joerg .Case("e5500", "e5500") 63 1.1 joerg .Case("power3", "pwr3") 64 1.1 joerg .Case("power4", "pwr4") 65 1.1 joerg .Case("power5", "pwr5") 66 1.1 joerg .Case("power5x", "pwr5x") 67 1.1 joerg .Case("power6", "pwr6") 68 1.1 joerg .Case("power6x", "pwr6x") 69 1.1 joerg .Case("power7", "pwr7") 70 1.1 joerg .Case("power8", "pwr8") 71 1.1 joerg .Case("power9", "pwr9") 72 1.1.1.2 joerg .Case("power10", "pwr10") 73 1.1.1.2 joerg .Case("future", "future") 74 1.1 joerg .Case("pwr3", "pwr3") 75 1.1 joerg .Case("pwr4", "pwr4") 76 1.1 joerg .Case("pwr5", "pwr5") 77 1.1 joerg .Case("pwr5x", "pwr5x") 78 1.1 joerg .Case("pwr6", "pwr6") 79 1.1 joerg .Case("pwr6x", "pwr6x") 80 1.1 joerg .Case("pwr7", "pwr7") 81 1.1 joerg .Case("pwr8", "pwr8") 82 1.1 joerg .Case("pwr9", "pwr9") 83 1.1.1.2 joerg .Case("pwr10", "pwr10") 84 1.1 joerg .Case("powerpc", "ppc") 85 1.1 joerg .Case("powerpc64", "ppc64") 86 1.1 joerg .Case("powerpc64le", "ppc64le") 87 1.1 joerg .Default(""); 88 1.1 joerg } 89 1.1 joerg 90 1.1 joerg return ""; 91 1.1 joerg } 92 1.1 joerg 93 1.1 joerg const char *ppc::getPPCAsmModeForCPU(StringRef Name) { 94 1.1 joerg return llvm::StringSwitch<const char *>(Name) 95 1.1.1.2 joerg .Case("pwr7", "-mpower7") 96 1.1.1.2 joerg .Case("power7", "-mpower7") 97 1.1.1.2 joerg .Case("pwr8", "-mpower8") 98 1.1.1.2 joerg .Case("power8", "-mpower8") 99 1.1.1.2 joerg .Case("ppc64le", "-mpower8") 100 1.1.1.2 joerg .Case("pwr9", "-mpower9") 101 1.1.1.2 joerg .Case("power9", "-mpower9") 102 1.1.1.2 joerg .Case("pwr10", "-mpower10") 103 1.1.1.2 joerg .Case("power10", "-mpower10") 104 1.1.1.2 joerg .Default("-many"); 105 1.1 joerg } 106 1.1 joerg 107 1.1 joerg void ppc::getPPCTargetFeatures(const Driver &D, const llvm::Triple &Triple, 108 1.1 joerg const ArgList &Args, 109 1.1 joerg std::vector<StringRef> &Features) { 110 1.1.1.2 joerg if (Triple.getSubArch() == llvm::Triple::PPCSubArch_spe) 111 1.1.1.2 joerg Features.push_back("+spe"); 112 1.1.1.2 joerg 113 1.1 joerg handleTargetFeaturesGroup(Args, Features, options::OPT_m_ppc_Features_Group); 114 1.1 joerg 115 1.1 joerg ppc::FloatABI FloatABI = ppc::getPPCFloatABI(D, Args); 116 1.1 joerg if (FloatABI == ppc::FloatABI::Soft) 117 1.1 joerg Features.push_back("-hard-float"); 118 1.1 joerg 119 1.1 joerg ppc::ReadGOTPtrMode ReadGOT = ppc::getPPCReadGOTPtrMode(D, Triple, Args); 120 1.1 joerg if (ReadGOT == ppc::ReadGOTPtrMode::SecurePlt) 121 1.1 joerg Features.push_back("+secure-plt"); 122 1.1 joerg } 123 1.1 joerg 124 1.1 joerg ppc::ReadGOTPtrMode ppc::getPPCReadGOTPtrMode(const Driver &D, const llvm::Triple &Triple, 125 1.1 joerg const ArgList &Args) { 126 1.1 joerg if (Args.getLastArg(options::OPT_msecure_plt)) 127 1.1 joerg return ppc::ReadGOTPtrMode::SecurePlt; 128 1.1 joerg if ((Triple.isOSFreeBSD() && Triple.getOSMajorVersion() >= 13) || 129 1.1 joerg Triple.isOSNetBSD() || Triple.isOSOpenBSD() || Triple.isMusl()) 130 1.1 joerg return ppc::ReadGOTPtrMode::SecurePlt; 131 1.1 joerg else 132 1.1 joerg return ppc::ReadGOTPtrMode::Bss; 133 1.1 joerg } 134 1.1 joerg 135 1.1 joerg ppc::FloatABI ppc::getPPCFloatABI(const Driver &D, const ArgList &Args) { 136 1.1 joerg ppc::FloatABI ABI = ppc::FloatABI::Invalid; 137 1.1 joerg if (Arg *A = 138 1.1 joerg Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float, 139 1.1 joerg options::OPT_mfloat_abi_EQ)) { 140 1.1 joerg if (A->getOption().matches(options::OPT_msoft_float)) 141 1.1 joerg ABI = ppc::FloatABI::Soft; 142 1.1 joerg else if (A->getOption().matches(options::OPT_mhard_float)) 143 1.1 joerg ABI = ppc::FloatABI::Hard; 144 1.1 joerg else { 145 1.1 joerg ABI = llvm::StringSwitch<ppc::FloatABI>(A->getValue()) 146 1.1 joerg .Case("soft", ppc::FloatABI::Soft) 147 1.1 joerg .Case("hard", ppc::FloatABI::Hard) 148 1.1 joerg .Default(ppc::FloatABI::Invalid); 149 1.1 joerg if (ABI == ppc::FloatABI::Invalid && !StringRef(A->getValue()).empty()) { 150 1.1 joerg D.Diag(clang::diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args); 151 1.1 joerg ABI = ppc::FloatABI::Hard; 152 1.1 joerg } 153 1.1 joerg } 154 1.1 joerg } 155 1.1 joerg 156 1.1 joerg // If unspecified, choose the default based on the platform. 157 1.1 joerg if (ABI == ppc::FloatABI::Invalid) { 158 1.1 joerg ABI = ppc::FloatABI::Hard; 159 1.1 joerg } 160 1.1 joerg 161 1.1 joerg return ABI; 162 1.1 joerg } 163 1.1 joerg 164 1.1 joerg bool ppc::hasPPCAbiArg(const ArgList &Args, const char *Value) { 165 1.1 joerg Arg *A = Args.getLastArg(options::OPT_mabi_EQ); 166 1.1 joerg return A && (A->getValue() == StringRef(Value)); 167 1.1 joerg } 168