Path: blob/main/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/PPC.cpp
35294 views
//===--- PPC.cpp - PPC Helpers for Tools ------------------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "PPC.h"9#include "ToolChains/CommonArgs.h"10#include "clang/Driver/Driver.h"11#include "clang/Driver/DriverDiagnostic.h"12#include "clang/Driver/Options.h"13#include "llvm/ADT/StringSwitch.h"14#include "llvm/Option/ArgList.h"15#include "llvm/TargetParser/Host.h"1617using namespace clang::driver;18using namespace clang::driver::tools;19using namespace clang;20using namespace llvm::opt;2122static std::string getPPCGenericTargetCPU(const llvm::Triple &T) {23// LLVM may default to generating code for the native CPU,24// but, like gcc, we default to a more generic option for25// each architecture. (except on AIX)26if (T.isOSAIX())27return "pwr7";28else if (T.getArch() == llvm::Triple::ppc64le)29return "ppc64le";30else if (T.getArch() == llvm::Triple::ppc64)31return "ppc64";32else33return "ppc";34}3536static std::string normalizeCPUName(StringRef CPUName, const llvm::Triple &T) {37// Clang/LLVM does not actually support code generation38// for the 405 CPU. However, there are uses of this CPU ID39// in projects that previously used GCC and rely on Clang40// accepting it. Clang has always ignored it and passed the41// generic CPU ID to the back end.42if (CPUName == "generic" || CPUName == "405")43return getPPCGenericTargetCPU(T);4445if (CPUName == "native") {46std::string CPU = std::string(llvm::sys::getHostCPUName());47if (!CPU.empty() && CPU != "generic")48return CPU;49else50return getPPCGenericTargetCPU(T);51}5253return llvm::StringSwitch<const char *>(CPUName)54.Case("common", "generic")55.Case("440fp", "440")56.Case("630", "pwr3")57.Case("G3", "g3")58.Case("G4", "g4")59.Case("G4+", "g4+")60.Case("8548", "e500")61.Case("G5", "g5")62.Case("power3", "pwr3")63.Case("power4", "pwr4")64.Case("power5", "pwr5")65.Case("power5x", "pwr5x")66.Case("power6", "pwr6")67.Case("power6x", "pwr6x")68.Case("power7", "pwr7")69.Case("power8", "pwr8")70.Case("power9", "pwr9")71.Case("power10", "pwr10")72.Case("power11", "pwr11")73.Case("future", "future")74.Case("powerpc", "ppc")75.Case("powerpc64", "ppc64")76.Case("powerpc64le", "ppc64le")77.Default(CPUName.data());78}7980/// Get the (LLVM) name of the PowerPC cpu we are tuning for.81std::string ppc::getPPCTuneCPU(const ArgList &Args, const llvm::Triple &T) {82if (Arg *A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ))83return normalizeCPUName(A->getValue(), T);84return getPPCGenericTargetCPU(T);85}8687/// Get the (LLVM) name of the PowerPC cpu we are targeting.88std::string ppc::getPPCTargetCPU(const Driver &D, const ArgList &Args,89const llvm::Triple &T) {90if (Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ))91return normalizeCPUName(A->getValue(), T);92return getPPCGenericTargetCPU(T);93}9495const char *ppc::getPPCAsmModeForCPU(StringRef Name) {96return llvm::StringSwitch<const char *>(Name)97.Case("pwr7", "-mpower7")98.Case("power7", "-mpower7")99.Case("pwr8", "-mpower8")100.Case("power8", "-mpower8")101.Case("ppc64le", "-mpower8")102.Case("pwr9", "-mpower9")103.Case("power9", "-mpower9")104.Case("pwr10", "-mpower10")105.Case("power10", "-mpower10")106.Case("pwr11", "-mpower11")107.Case("power11", "-mpower11")108.Default("-many");109}110111void ppc::getPPCTargetFeatures(const Driver &D, const llvm::Triple &Triple,112const ArgList &Args,113std::vector<StringRef> &Features) {114if (Triple.getSubArch() == llvm::Triple::PPCSubArch_spe)115Features.push_back("+spe");116117handleTargetFeaturesGroup(D, Triple, Args, Features,118options::OPT_m_ppc_Features_Group);119120ppc::FloatABI FloatABI = ppc::getPPCFloatABI(D, Args);121if (FloatABI == ppc::FloatABI::Soft)122Features.push_back("-hard-float");123124ppc::ReadGOTPtrMode ReadGOT = ppc::getPPCReadGOTPtrMode(D, Triple, Args);125if (ReadGOT == ppc::ReadGOTPtrMode::SecurePlt)126Features.push_back("+secure-plt");127128bool UseSeparateSections = isUseSeparateSections(Triple);129bool HasDefaultDataSections = Triple.isOSBinFormatXCOFF();130if (Args.hasArg(options::OPT_maix_small_local_exec_tls) ||131Args.hasArg(options::OPT_maix_small_local_dynamic_tls)) {132if (!Triple.isOSAIX() || !Triple.isArch64Bit())133D.Diag(diag::err_opt_not_valid_on_target)134<< "-maix-small-local-[exec|dynamic]-tls";135136// The -maix-small-local-[exec|dynamic]-tls option should only be used with137// -fdata-sections, as having data sections turned off with this option138// is not ideal for performance. Moreover, the139// small-local-[exec|dynamic]-tls region is a limited resource, and should140// not be used for variables that may be replaced.141if (!Args.hasFlag(options::OPT_fdata_sections,142options::OPT_fno_data_sections,143UseSeparateSections || HasDefaultDataSections))144D.Diag(diag::err_drv_argument_only_allowed_with)145<< "-maix-small-local-[exec|dynamic]-tls" << "-fdata-sections";146}147}148149ppc::ReadGOTPtrMode ppc::getPPCReadGOTPtrMode(const Driver &D, const llvm::Triple &Triple,150const ArgList &Args) {151if (Args.getLastArg(options::OPT_msecure_plt))152return ppc::ReadGOTPtrMode::SecurePlt;153if (Triple.isPPC32SecurePlt())154return ppc::ReadGOTPtrMode::SecurePlt;155else156return ppc::ReadGOTPtrMode::Bss;157}158159ppc::FloatABI ppc::getPPCFloatABI(const Driver &D, const ArgList &Args) {160ppc::FloatABI ABI = ppc::FloatABI::Invalid;161if (Arg *A =162Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,163options::OPT_mfloat_abi_EQ)) {164if (A->getOption().matches(options::OPT_msoft_float))165ABI = ppc::FloatABI::Soft;166else if (A->getOption().matches(options::OPT_mhard_float))167ABI = ppc::FloatABI::Hard;168else {169ABI = llvm::StringSwitch<ppc::FloatABI>(A->getValue())170.Case("soft", ppc::FloatABI::Soft)171.Case("hard", ppc::FloatABI::Hard)172.Default(ppc::FloatABI::Invalid);173if (ABI == ppc::FloatABI::Invalid && !StringRef(A->getValue()).empty()) {174D.Diag(clang::diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);175ABI = ppc::FloatABI::Hard;176}177}178}179180// If unspecified, choose the default based on the platform.181if (ABI == ppc::FloatABI::Invalid) {182ABI = ppc::FloatABI::Hard;183}184185return ABI;186}187188bool ppc::hasPPCAbiArg(const ArgList &Args, const char *Value) {189Arg *A = Args.getLastArg(options::OPT_mabi_EQ);190return A && (A->getValue() == StringRef(Value));191}192193194