Home | History | Annotate | Line # | Download | only in Arch
      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