Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

View File

@ -0,0 +1,101 @@
//===--- AMDGPU.cpp - AMDGPU ToolChain Implementations ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "AMDGPU.h"
#include "CommonArgs.h"
#include "InputInfo.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "llvm/Option/ArgList.h"
using namespace clang::driver;
using namespace clang::driver::tools;
using namespace clang::driver::toolchains;
using namespace clang;
using namespace llvm::opt;
void amdgpu::Linker::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) const {
std::string Linker = getToolChain().GetProgramPath(getShortName());
ArgStringList CmdArgs;
AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
CmdArgs.push_back("-shared");
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Linker),
CmdArgs, Inputs));
}
void amdgpu::getAMDGPUTargetFeatures(const Driver &D,
const llvm::opt::ArgList &Args,
std::vector<StringRef> &Features) {
if (const Arg *dAbi = Args.getLastArg(options::OPT_mamdgpu_debugger_abi)) {
StringRef value = dAbi->getValue();
if (value == "1.0") {
Features.push_back("+amdgpu-debugger-insert-nops");
Features.push_back("+amdgpu-debugger-reserve-regs");
Features.push_back("+amdgpu-debugger-emit-prologue");
} else {
D.Diag(diag::err_drv_clang_unsupported) << dAbi->getAsString(Args);
}
}
handleTargetFeaturesGroup(
Args, Features, options::OPT_m_amdgpu_Features_Group);
}
/// AMDGPU Toolchain
AMDGPUToolChain::AMDGPUToolChain(const Driver &D, const llvm::Triple &Triple,
const ArgList &Args)
: Generic_ELF(D, Triple, Args),
OptionsDefault({{options::OPT_O, "3"},
{options::OPT_cl_std_EQ, "CL1.2"}}) {}
Tool *AMDGPUToolChain::buildLinker() const {
return new tools::amdgpu::Linker(*this);
}
DerivedArgList *
AMDGPUToolChain::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch,
Action::OffloadKind DeviceOffloadKind) const {
DerivedArgList *DAL =
Generic_ELF::TranslateArgs(Args, BoundArch, DeviceOffloadKind);
// Do nothing if not OpenCL (-x cl)
if (!Args.getLastArgValue(options::OPT_x).equals("cl"))
return DAL;
if (!DAL)
DAL = new DerivedArgList(Args.getBaseArgs());
for (auto *A : Args)
DAL->append(A);
const OptTable &Opts = getDriver().getOpts();
// Phase 1 (.cl -> .bc)
if (Args.hasArg(options::OPT_c) && Args.hasArg(options::OPT_emit_llvm)) {
DAL->AddFlagArg(nullptr, Opts.getOption(getTriple().isArch64Bit()
? options::OPT_m64
: options::OPT_m32));
// Have to check OPT_O4, OPT_O0 & OPT_Ofast separately
// as they defined that way in Options.td
if (!Args.hasArg(options::OPT_O, options::OPT_O0, options::OPT_O4,
options::OPT_Ofast))
DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_O),
getOptionDefault(options::OPT_O));
}
return DAL;
}

View File

@ -0,0 +1,70 @@
//===--- AMDGPU.h - AMDGPU ToolChain Implementations ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_AMDGPU_H
#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_AMDGPU_H
#include "Gnu.h"
#include "clang/Driver/Options.h"
#include "clang/Driver/Tool.h"
#include "clang/Driver/ToolChain.h"
#include <map>
namespace clang {
namespace driver {
namespace tools {
namespace amdgpu {
class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
public:
Linker(const ToolChain &TC) : GnuTool("amdgpu::Linker", "ld.lld", TC) {}
bool isLinkJob() const override { return true; }
bool hasIntegratedCPP() const override { return false; }
void ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output, const InputInfoList &Inputs,
const llvm::opt::ArgList &TCArgs,
const char *LinkingOutput) const override;
};
void getAMDGPUTargetFeatures(const Driver &D, const llvm::opt::ArgList &Args,
std::vector<StringRef> &Features);
} // end namespace amdgpu
} // end namespace tools
namespace toolchains {
class LLVM_LIBRARY_VISIBILITY AMDGPUToolChain : public Generic_ELF {
private:
const std::map<options::ID, const StringRef> OptionsDefault;
protected:
Tool *buildLinker() const override;
const StringRef getOptionDefault(options::ID OptID) const {
auto opt = OptionsDefault.find(OptID);
assert(opt != OptionsDefault.end() && "No Default for Option");
return opt->second;
}
public:
AMDGPUToolChain(const Driver &D, const llvm::Triple &Triple,
const llvm::opt::ArgList &Args);
unsigned GetDefaultDwarfVersion() const override { return 2; }
bool IsIntegratedAssemblerDefault() const override { return true; }
llvm::opt::DerivedArgList *
TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
Action::OffloadKind DeviceOffloadKind) const override;
};
} // end namespace toolchains
} // end namespace driver
} // end namespace clang
#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_AMDGPU_H

View File

@ -0,0 +1,44 @@
//===--- AVR.cpp - AVR ToolChain Implementations ----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "AVR.h"
#include "CommonArgs.h"
#include "InputInfo.h"
#include "clang/Driver/Compilation.h"
#include "llvm/Option/ArgList.h"
using namespace clang::driver;
using namespace clang::driver::toolchains;
using namespace clang::driver::tools;
using namespace clang;
using namespace llvm::opt;
/// AVR Toolchain
AVRToolChain::AVRToolChain(const Driver &D, const llvm::Triple &Triple,
const ArgList &Args)
: Generic_ELF(D, Triple, Args) { }
Tool *AVRToolChain::buildLinker() const {
return new tools::AVR::Linker(*this);
}
void AVR::Linker::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) const {
std::string Linker = getToolChain().GetProgramPath(getShortName());
ArgStringList CmdArgs;
AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Linker),
CmdArgs, Inputs));
}
// AVR tools end.

View File

@ -0,0 +1,49 @@
//===--- AVR.h - AVR Tool and ToolChain Implementations ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_AVR_H
#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_AVR_H
#include "Gnu.h"
#include "InputInfo.h"
#include "clang/Driver/ToolChain.h"
#include "clang/Driver/Tool.h"
namespace clang {
namespace driver {
namespace toolchains {
class LLVM_LIBRARY_VISIBILITY AVRToolChain : public Generic_ELF {
protected:
Tool *buildLinker() const override;
public:
AVRToolChain(const Driver &D, const llvm::Triple &Triple,
const llvm::opt::ArgList &Args);
};
} // end namespace toolchains
namespace tools {
namespace AVR {
class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
public:
Linker(const ToolChain &TC) : GnuTool("AVR::Linker", "avr-ld", TC) {}
bool hasIntegratedCPP() const override { return false; }
bool isLinkJob() const override { return true; }
void ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output, const InputInfoList &Inputs,
const llvm::opt::ArgList &TCArgs,
const char *LinkingOutput) const override;
};
} // end namespace AVR
} // end namespace tools
} // end namespace driver
} // end namespace clang
#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_AVR_H

View File

@ -0,0 +1,119 @@
//===--- Ananas.cpp - Ananas ToolChain Implementations ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "Ananas.h"
#include "InputInfo.h"
#include "CommonArgs.h"
#include "clang/Config/config.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/Options.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Support/Path.h"
using namespace clang::driver;
using namespace clang::driver::tools;
using namespace clang::driver::toolchains;
using namespace clang;
using namespace llvm::opt;
void ananas::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) const {
claimNoWarnArgs(Args);
ArgStringList CmdArgs;
Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
for (const auto &II : Inputs)
CmdArgs.push_back(II.getFilename());
const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
}
void ananas::Linker::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) const {
const ToolChain &ToolChain = getToolChain();
const Driver &D = ToolChain.getDriver();
ArgStringList CmdArgs;
// Silence warning for "clang -g foo.o -o foo"
Args.ClaimAllArgs(options::OPT_g_Group);
// and "clang -emit-llvm foo.o -o foo"
Args.ClaimAllArgs(options::OPT_emit_llvm);
// and for "clang -w foo.o -o foo". Other warning options are already
// handled somewhere else.
Args.ClaimAllArgs(options::OPT_w);
if (!D.SysRoot.empty())
CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
// Ananas only supports static linkage for now.
CmdArgs.push_back("-Bstatic");
if (Output.isFilename()) {
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
} else {
assert(Output.isNothing() && "Invalid output.");
}
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o")));
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtbegin.o")));
}
Args.AddAllArgs(CmdArgs, options::OPT_L);
ToolChain.AddFilePathLibArgs(Args, CmdArgs);
Args.AddAllArgs(CmdArgs,
{options::OPT_T_Group, options::OPT_e, options::OPT_s,
options::OPT_t, options::OPT_Z_Flag, options::OPT_r});
if (D.isUsingLTO())
AddGoldPlugin(ToolChain, Args, CmdArgs, D.getLTOMode() == LTOK_Thin, D);
AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
if (ToolChain.ShouldLinkCXXStdlib(Args))
ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs))
CmdArgs.push_back("-lc");
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o")));
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
}
const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());
C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
}
// Ananas - Ananas tool chain which can call as(1) and ld(1) directly.
Ananas::Ananas(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
: Generic_ELF(D, Triple, Args) {
getFilePaths().push_back(getDriver().SysRoot + "/usr/lib");
}
Tool *Ananas::buildAssembler() const {
return new tools::ananas::Assembler(*this);
}
Tool *Ananas::buildLinker() const { return new tools::ananas::Linker(*this); }

View File

@ -0,0 +1,67 @@
//===--- Ananas.h - Ananas ToolChain Implementations --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ANANAS_H
#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ANANAS_H
#include "Gnu.h"
#include "clang/Driver/Tool.h"
#include "clang/Driver/ToolChain.h"
namespace clang {
namespace driver {
namespace tools {
/// ananas -- Directly call GNU Binutils assembler and linker
namespace ananas {
class LLVM_LIBRARY_VISIBILITY Assembler : public GnuTool {
public:
Assembler(const ToolChain &TC)
: GnuTool("ananas::Assembler", "assembler", TC) {}
bool hasIntegratedCPP() const override { return false; }
void ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output, const InputInfoList &Inputs,
const llvm::opt::ArgList &TCArgs,
const char *LinkingOutput) const override;
};
class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool {
public:
Linker(const ToolChain &TC) : GnuTool("ananas::Linker", "linker", TC) {}
bool hasIntegratedCPP() const override { return false; }
bool isLinkJob() const override { return true; }
void ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output, const InputInfoList &Inputs,
const llvm::opt::ArgList &TCArgs,
const char *LinkingOutput) const override;
};
} // end namespace ananas
} // end namespace tools
namespace toolchains {
class LLVM_LIBRARY_VISIBILITY Ananas : public Generic_ELF {
public:
Ananas(const Driver &D, const llvm::Triple &Triple,
const llvm::opt::ArgList &Args);
protected:
Tool *buildAssembler() const override;
Tool *buildLinker() const override;
};
} // end namespace toolchains
} // end namespace driver
} // end namespace clang
#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ANANAS_H

View File

@ -0,0 +1,203 @@
//===--- AArch64.cpp - AArch64 (not ARM) Helpers for Tools ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "AArch64.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/Options.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Support/TargetParser.h"
using namespace clang::driver;
using namespace clang::driver::tools;
using namespace clang;
using namespace llvm::opt;
/// getAArch64TargetCPU - Get the (LLVM) name of the AArch64 cpu we are
/// targeting. Set \p A to the Arg corresponding to the -mcpu argument if it is
/// provided, or to nullptr otherwise.
std::string aarch64::getAArch64TargetCPU(const ArgList &Args, Arg *&A) {
std::string CPU;
// If we have -mcpu, use that.
if ((A = Args.getLastArg(options::OPT_mcpu_EQ))) {
StringRef Mcpu = A->getValue();
CPU = Mcpu.split("+").first.lower();
}
// Handle CPU name is 'native'.
if (CPU == "native")
return llvm::sys::getHostCPUName();
else if (CPU.size())
return CPU;
// Make sure we pick "cyclone" if -arch is used.
// FIXME: Should this be picked by checking the target triple instead?
if (Args.getLastArg(options::OPT_arch))
return "cyclone";
return "generic";
}
// Decode AArch64 features from string like +[no]featureA+[no]featureB+...
static bool DecodeAArch64Features(const Driver &D, StringRef text,
std::vector<StringRef> &Features) {
SmallVector<StringRef, 8> Split;
text.split(Split, StringRef("+"), -1, false);
for (StringRef Feature : Split) {
StringRef FeatureName = llvm::AArch64::getArchExtFeature(Feature);
if (!FeatureName.empty())
Features.push_back(FeatureName);
else if (Feature == "neon" || Feature == "noneon")
D.Diag(clang::diag::err_drv_no_neon_modifier);
else
return false;
}
return true;
}
// Check if the CPU name and feature modifiers in -mcpu are legal. If yes,
// decode CPU and feature.
static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, StringRef &CPU,
std::vector<StringRef> &Features) {
std::pair<StringRef, StringRef> Split = Mcpu.split("+");
CPU = Split.first;
if (CPU == "generic") {
Features.push_back("+neon");
} else {
llvm::AArch64::ArchKind ArchKind = llvm::AArch64::parseCPUArch(CPU);
if (!llvm::AArch64::getArchFeatures(ArchKind, Features))
return false;
unsigned Extension = llvm::AArch64::getDefaultExtensions(CPU, ArchKind);
if (!llvm::AArch64::getExtensionFeatures(Extension, Features))
return false;
}
if (Split.second.size() && !DecodeAArch64Features(D, Split.second, Features))
return false;
return true;
}
static bool
getAArch64ArchFeaturesFromMarch(const Driver &D, StringRef March,
const ArgList &Args,
std::vector<StringRef> &Features) {
std::string MarchLowerCase = March.lower();
std::pair<StringRef, StringRef> Split = StringRef(MarchLowerCase).split("+");
llvm::AArch64::ArchKind ArchKind = llvm::AArch64::parseArch(Split.first);
if (ArchKind == llvm::AArch64::ArchKind::INVALID ||
!llvm::AArch64::getArchFeatures(ArchKind, Features) ||
(Split.second.size() && !DecodeAArch64Features(D, Split.second, Features)))
return false;
return true;
}
static bool
getAArch64ArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu,
const ArgList &Args,
std::vector<StringRef> &Features) {
StringRef CPU;
std::string McpuLowerCase = Mcpu.lower();
if (!DecodeAArch64Mcpu(D, McpuLowerCase, CPU, Features))
return false;
return true;
}
static bool
getAArch64MicroArchFeaturesFromMtune(const Driver &D, StringRef Mtune,
const ArgList &Args,
std::vector<StringRef> &Features) {
std::string MtuneLowerCase = Mtune.lower();
// Check CPU name is valid
std::vector<StringRef> MtuneFeatures;
StringRef Tune;
if (!DecodeAArch64Mcpu(D, MtuneLowerCase, Tune, MtuneFeatures))
return false;
// Handle CPU name is 'native'.
if (MtuneLowerCase == "native")
MtuneLowerCase = llvm::sys::getHostCPUName();
if (MtuneLowerCase == "cyclone") {
Features.push_back("+zcm");
Features.push_back("+zcz");
}
return true;
}
static bool
getAArch64MicroArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu,
const ArgList &Args,
std::vector<StringRef> &Features) {
StringRef CPU;
std::vector<StringRef> DecodedFeature;
std::string McpuLowerCase = Mcpu.lower();
if (!DecodeAArch64Mcpu(D, McpuLowerCase, CPU, DecodedFeature))
return false;
return getAArch64MicroArchFeaturesFromMtune(D, CPU, Args, Features);
}
void aarch64::getAArch64TargetFeatures(const Driver &D, const ArgList &Args,
std::vector<StringRef> &Features) {
Arg *A;
bool success = true;
// Enable NEON by default.
Features.push_back("+neon");
if ((A = Args.getLastArg(options::OPT_march_EQ)))
success = getAArch64ArchFeaturesFromMarch(D, A->getValue(), Args, Features);
else if ((A = Args.getLastArg(options::OPT_mcpu_EQ)))
success = getAArch64ArchFeaturesFromMcpu(D, A->getValue(), Args, Features);
else if (Args.hasArg(options::OPT_arch))
success = getAArch64ArchFeaturesFromMcpu(D, getAArch64TargetCPU(Args, A),
Args, Features);
if (success && (A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ)))
success =
getAArch64MicroArchFeaturesFromMtune(D, A->getValue(), Args, Features);
else if (success && (A = Args.getLastArg(options::OPT_mcpu_EQ)))
success =
getAArch64MicroArchFeaturesFromMcpu(D, A->getValue(), Args, Features);
else if (success && Args.hasArg(options::OPT_arch))
success = getAArch64MicroArchFeaturesFromMcpu(
D, getAArch64TargetCPU(Args, A), Args, Features);
if (!success)
D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
if (Args.getLastArg(options::OPT_mgeneral_regs_only)) {
Features.push_back("-fp-armv8");
Features.push_back("-crypto");
Features.push_back("-neon");
}
// En/disable crc
if (Arg *A = Args.getLastArg(options::OPT_mcrc, options::OPT_mnocrc)) {
if (A->getOption().matches(options::OPT_mcrc))
Features.push_back("+crc");
else
Features.push_back("-crc");
}
if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access,
options::OPT_munaligned_access))
if (A->getOption().matches(options::OPT_mno_unaligned_access))
Features.push_back("+strict-align");
if (Args.hasArg(options::OPT_ffixed_x18))
Features.push_back("+reserve-x18");
if (Args.hasArg(options::OPT_mno_neg_immediates))
Features.push_back("+no-neg-immediates");
}

View File

@ -0,0 +1,35 @@
//===--- AArch64.h - AArch64-specific (not ARM) Tool Helpers ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_AARCH64_H
#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_AARCH64_H
#include "clang/Driver/Driver.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Option/Option.h"
#include <string>
#include <vector>
namespace clang {
namespace driver {
namespace tools {
namespace aarch64 {
void getAArch64TargetFeatures(const Driver &D, const llvm::opt::ArgList &Args,
std::vector<llvm::StringRef> &Features);
std::string getAArch64TargetCPU(const llvm::opt::ArgList &Args,
llvm::opt::Arg *&A);
} // end namespace aarch64
} // end namespace target
} // end namespace driver
} // end namespace clang
#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_AARCH64_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,67 @@
//===--- ARM.h - ARM-specific (not AArch64) Tool Helpers --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_ARM_H
#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_ARM_H
#include "clang/Driver/ToolChain.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Option/Option.h"
#include <string>
#include <vector>
namespace clang {
namespace driver {
namespace tools {
namespace arm {
std::string getARMTargetCPU(StringRef CPU, llvm::StringRef Arch,
const llvm::Triple &Triple);
const std::string getARMArch(llvm::StringRef Arch, const llvm::Triple &Triple);
StringRef getARMCPUForMArch(llvm::StringRef Arch, const llvm::Triple &Triple);
StringRef getLLVMArchSuffixForARM(llvm::StringRef CPU, llvm::StringRef Arch,
const llvm::Triple &Triple);
void appendEBLinkFlags(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs,
const llvm::Triple &Triple);
enum class ReadTPMode {
Invalid,
Soft,
Cp15,
};
enum class FloatABI {
Invalid,
Soft,
SoftFP,
Hard,
};
FloatABI getARMFloatABI(const ToolChain &TC, const llvm::opt::ArgList &Args);
ReadTPMode getReadTPMode(const ToolChain &TC, const llvm::opt::ArgList &Args);
bool useAAPCSForMachO(const llvm::Triple &T);
void getARMArchCPUFromArgs(const llvm::opt::ArgList &Args,
llvm::StringRef &Arch, llvm::StringRef &CPU,
bool FromAs = false);
void getARMTargetFeatures(const ToolChain &TC, const llvm::Triple &Triple,
const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs,
std::vector<llvm::StringRef> &Features, bool ForAS);
int getARMSubArchVersionNumber(const llvm::Triple &Triple);
bool isARMMProfile(const llvm::Triple &Triple);
} // end namespace arm
} // end namespace tools
} // end namespace driver
} // end namespace clang
#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_ARM_H

View File

@ -0,0 +1,488 @@
//===--- Mips.cpp - Tools Implementations -----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "Mips.h"
#include "ToolChains/CommonArgs.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/Options.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Option/ArgList.h"
using namespace clang::driver;
using namespace clang::driver::tools;
using namespace clang;
using namespace llvm::opt;
bool tools::isMipsArch(llvm::Triple::ArchType Arch) {
return Arch == llvm::Triple::mips || Arch == llvm::Triple::mipsel ||
Arch == llvm::Triple::mips64 || Arch == llvm::Triple::mips64el;
}
// Get CPU and ABI names. They are not independent
// so we have to calculate them together.
void mips::getMipsCPUAndABI(const ArgList &Args, const llvm::Triple &Triple,
StringRef &CPUName, StringRef &ABIName) {
const char *DefMips32CPU = "mips32r2";
const char *DefMips64CPU = "mips64r2";
// MIPS32r6 is the default for mips(el)?-img-linux-gnu and MIPS64r6 is the
// default for mips64(el)?-img-linux-gnu.
if (Triple.getVendor() == llvm::Triple::ImaginationTechnologies &&
Triple.isGNUEnvironment()) {
DefMips32CPU = "mips32r6";
DefMips64CPU = "mips64r6";
}
// MIPS64r6 is the default for Android MIPS64 (mips64el-linux-android).
if (Triple.isAndroid()) {
DefMips32CPU = "mips32";
DefMips64CPU = "mips64r6";
}
// MIPS3 is the default for mips64*-unknown-openbsd.
if (Triple.getOS() == llvm::Triple::OpenBSD)
DefMips64CPU = "mips3";
if (Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ,
options::OPT_mcpu_EQ))
CPUName = A->getValue();
if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
ABIName = A->getValue();
// Convert a GNU style Mips ABI name to the name
// accepted by LLVM Mips backend.
ABIName = llvm::StringSwitch<llvm::StringRef>(ABIName)
.Case("32", "o32")
.Case("64", "n64")
.Default(ABIName);
}
// Setup default CPU and ABI names.
if (CPUName.empty() && ABIName.empty()) {
switch (Triple.getArch()) {
default:
llvm_unreachable("Unexpected triple arch name");
case llvm::Triple::mips:
case llvm::Triple::mipsel:
CPUName = DefMips32CPU;
break;
case llvm::Triple::mips64:
case llvm::Triple::mips64el:
CPUName = DefMips64CPU;
break;
}
}
if (ABIName.empty() &&
(Triple.getVendor() == llvm::Triple::MipsTechnologies ||
Triple.getVendor() == llvm::Triple::ImaginationTechnologies)) {
ABIName = llvm::StringSwitch<const char *>(CPUName)
.Case("mips1", "o32")
.Case("mips2", "o32")
.Case("mips3", "n64")
.Case("mips4", "n64")
.Case("mips5", "n64")
.Case("mips32", "o32")
.Case("mips32r2", "o32")
.Case("mips32r3", "o32")
.Case("mips32r5", "o32")
.Case("mips32r6", "o32")
.Case("mips64", "n64")
.Case("mips64r2", "n64")
.Case("mips64r3", "n64")
.Case("mips64r5", "n64")
.Case("mips64r6", "n64")
.Case("octeon", "n64")
.Case("p5600", "o32")
.Default("");
}
if (ABIName.empty()) {
// Deduce ABI name from the target triple.
if (Triple.getArch() == llvm::Triple::mips ||
Triple.getArch() == llvm::Triple::mipsel)
ABIName = "o32";
else
ABIName = "n64";
}
if (CPUName.empty()) {
// Deduce CPU name from ABI name.
CPUName = llvm::StringSwitch<const char *>(ABIName)
.Case("o32", DefMips32CPU)
.Cases("n32", "n64", DefMips64CPU)
.Default("");
}
// FIXME: Warn on inconsistent use of -march and -mabi.
}
std::string mips::getMipsABILibSuffix(const ArgList &Args,
const llvm::Triple &Triple) {
StringRef CPUName, ABIName;
tools::mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
return llvm::StringSwitch<std::string>(ABIName)
.Case("o32", "")
.Case("n32", "32")
.Case("n64", "64");
}
// Convert ABI name to the GNU tools acceptable variant.
StringRef mips::getGnuCompatibleMipsABIName(StringRef ABI) {
return llvm::StringSwitch<llvm::StringRef>(ABI)
.Case("o32", "32")
.Case("n64", "64")
.Default(ABI);
}
// Select the MIPS float ABI as determined by -msoft-float, -mhard-float,
// and -mfloat-abi=.
mips::FloatABI mips::getMipsFloatABI(const Driver &D, const ArgList &Args) {
mips::FloatABI ABI = mips::FloatABI::Invalid;
if (Arg *A =
Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
options::OPT_mfloat_abi_EQ)) {
if (A->getOption().matches(options::OPT_msoft_float))
ABI = mips::FloatABI::Soft;
else if (A->getOption().matches(options::OPT_mhard_float))
ABI = mips::FloatABI::Hard;
else {
ABI = llvm::StringSwitch<mips::FloatABI>(A->getValue())
.Case("soft", mips::FloatABI::Soft)
.Case("hard", mips::FloatABI::Hard)
.Default(mips::FloatABI::Invalid);
if (ABI == mips::FloatABI::Invalid && !StringRef(A->getValue()).empty()) {
D.Diag(clang::diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
ABI = mips::FloatABI::Hard;
}
}
}
// If unspecified, choose the default based on the platform.
if (ABI == mips::FloatABI::Invalid) {
// Assume "hard", because it's a default value used by gcc.
// When we start to recognize specific target MIPS processors,
// we will be able to select the default more correctly.
ABI = mips::FloatABI::Hard;
}
assert(ABI != mips::FloatABI::Invalid && "must select an ABI");
return ABI;
}
void mips::getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple,
const ArgList &Args,
std::vector<StringRef> &Features) {
StringRef CPUName;
StringRef ABIName;
getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
ABIName = getGnuCompatibleMipsABIName(ABIName);
// Historically, PIC code for MIPS was associated with -mabicalls, a.k.a
// SVR4 abicalls. Static code does not use SVR4 calling sequences. An ABI
// extension was developed by Richard Sandiford & Code Sourcery to support
// static code calling PIC code (CPIC). For O32 and N32 this means we have
// several combinations of PIC/static and abicalls. Pure static, static
// with the CPIC extension, and pure PIC code.
// At final link time, O32 and N32 with CPIC will have another section
// added to the binary which contains the stub functions to perform
// any fixups required for PIC code.
// For N64, the situation is more regular: code can either be static
// (non-abicalls) or PIC (abicalls). GCC has traditionally picked PIC code
// code for N64. Since Clang has already built the relocation model portion
// of the commandline, we pick add +noabicalls feature in the N64 static
// case.
// The is another case to be accounted for: -msym32, which enforces that all
// symbols have 32 bits in size. In this case, N64 can in theory use CPIC
// but it is unsupported.
// The combinations for N64 are:
// a) Static without abicalls and 64bit symbols.
// b) Static with abicalls and 32bit symbols.
// c) PIC with abicalls and 64bit symbols.
// For case (a) we need to add +noabicalls for N64.
bool IsN64 = ABIName == "64";
bool NonPIC = false;
Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
options::OPT_fpic, options::OPT_fno_pic,
options::OPT_fPIE, options::OPT_fno_PIE,
options::OPT_fpie, options::OPT_fno_pie);
if (LastPICArg) {
Option O = LastPICArg->getOption();
NonPIC =
(O.matches(options::OPT_fno_PIC) || O.matches(options::OPT_fno_pic) ||
O.matches(options::OPT_fno_PIE) || O.matches(options::OPT_fno_pie));
}
bool UseAbiCalls = false;
Arg *ABICallsArg =
Args.getLastArg(options::OPT_mabicalls, options::OPT_mno_abicalls);
UseAbiCalls =
!ABICallsArg || ABICallsArg->getOption().matches(options::OPT_mabicalls);
if (UseAbiCalls && IsN64 && NonPIC) {
D.Diag(diag::warn_drv_unsupported_abicalls);
UseAbiCalls = false;
}
if (!UseAbiCalls)
Features.push_back("+noabicalls");
else
Features.push_back("-noabicalls");
if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
options::OPT_mno_long_calls)) {
if (A->getOption().matches(options::OPT_mno_long_calls))
Features.push_back("-long-calls");
else if (!UseAbiCalls)
Features.push_back("+long-calls");
else
D.Diag(diag::warn_drv_unsupported_longcalls) << (ABICallsArg ? 0 : 1);
}
mips::FloatABI FloatABI = mips::getMipsFloatABI(D, Args);
if (FloatABI == mips::FloatABI::Soft) {
// FIXME: Note, this is a hack. We need to pass the selected float
// mode to the MipsTargetInfoBase to define appropriate macros there.
// Now it is the only method.
Features.push_back("+soft-float");
}
if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) {
StringRef Val = StringRef(A->getValue());
if (Val == "2008") {
if (mips::getIEEE754Standard(CPUName) & mips::Std2008)
Features.push_back("+nan2008");
else {
Features.push_back("-nan2008");
D.Diag(diag::warn_target_unsupported_nan2008) << CPUName;
}
} else if (Val == "legacy") {
if (mips::getIEEE754Standard(CPUName) & mips::Legacy)
Features.push_back("-nan2008");
else {
Features.push_back("+nan2008");
D.Diag(diag::warn_target_unsupported_nanlegacy) << CPUName;
}
} else
D.Diag(diag::err_drv_unsupported_option_argument)
<< A->getOption().getName() << Val;
}
if (Arg *A = Args.getLastArg(options::OPT_mabs_EQ)) {
StringRef Val = StringRef(A->getValue());
if (Val == "2008") {
if (mips::getIEEE754Standard(CPUName) & mips::Std2008) {
Features.push_back("+abs2008");
} else {
Features.push_back("-abs2008");
D.Diag(diag::warn_target_unsupported_abs2008) << CPUName;
}
} else if (Val == "legacy") {
if (mips::getIEEE754Standard(CPUName) & mips::Legacy) {
Features.push_back("-abs2008");
} else {
Features.push_back("+abs2008");
D.Diag(diag::warn_target_unsupported_abslegacy) << CPUName;
}
} else {
D.Diag(diag::err_drv_unsupported_option_argument)
<< A->getOption().getName() << Val;
}
}
AddTargetFeature(Args, Features, options::OPT_msingle_float,
options::OPT_mdouble_float, "single-float");
AddTargetFeature(Args, Features, options::OPT_mips16, options::OPT_mno_mips16,
"mips16");
AddTargetFeature(Args, Features, options::OPT_mmicromips,
options::OPT_mno_micromips, "micromips");
AddTargetFeature(Args, Features, options::OPT_mdsp, options::OPT_mno_dsp,
"dsp");
AddTargetFeature(Args, Features, options::OPT_mdspr2, options::OPT_mno_dspr2,
"dspr2");
AddTargetFeature(Args, Features, options::OPT_mmsa, options::OPT_mno_msa,
"msa");
// Add the last -mfp32/-mfpxx/-mfp64, if none are given and the ABI is O32
// pass -mfpxx, or if none are given and fp64a is default, pass fp64 and
// nooddspreg.
if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx,
options::OPT_mfp64)) {
if (A->getOption().matches(options::OPT_mfp32))
Features.push_back("-fp64");
else if (A->getOption().matches(options::OPT_mfpxx)) {
Features.push_back("+fpxx");
Features.push_back("+nooddspreg");
} else
Features.push_back("+fp64");
} else if (mips::shouldUseFPXX(Args, Triple, CPUName, ABIName, FloatABI)) {
Features.push_back("+fpxx");
Features.push_back("+nooddspreg");
} else if (mips::isFP64ADefault(Triple, CPUName)) {
Features.push_back("+fp64");
Features.push_back("+nooddspreg");
}
AddTargetFeature(Args, Features, options::OPT_mno_odd_spreg,
options::OPT_modd_spreg, "nooddspreg");
AddTargetFeature(Args, Features, options::OPT_mno_madd4, options::OPT_mmadd4,
"nomadd4");
AddTargetFeature(Args, Features, options::OPT_mmt, options::OPT_mno_mt, "mt");
if (Arg *A = Args.getLastArg(options::OPT_mindirect_jump_EQ)) {
StringRef Val = StringRef(A->getValue());
if (Val == "hazard") {
Arg *B =
Args.getLastArg(options::OPT_mmicromips, options::OPT_mno_micromips);
Arg *C = Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16);
if (B && B->getOption().matches(options::OPT_mmicromips))
D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
<< "hazard" << "micromips";
else if (C && C->getOption().matches(options::OPT_mips16))
D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
<< "hazard" << "mips16";
else if (mips::supportsIndirectJumpHazardBarrier(CPUName))
Features.push_back("+use-indirect-jump-hazard");
else
D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
<< "hazard" << CPUName;
} else
D.Diag(diag::err_drv_unknown_indirect_jump_opt) << Val;
}
}
mips::IEEE754Standard mips::getIEEE754Standard(StringRef &CPU) {
// Strictly speaking, mips32r2 and mips64r2 do not conform to the
// IEEE754-2008 standard. Support for this standard was first introduced
// in Release 3. However, other compilers have traditionally allowed it
// for Release 2 so we should do the same.
return (IEEE754Standard)llvm::StringSwitch<int>(CPU)
.Case("mips1", Legacy)
.Case("mips2", Legacy)
.Case("mips3", Legacy)
.Case("mips4", Legacy)
.Case("mips5", Legacy)
.Case("mips32", Legacy)
.Case("mips32r2", Legacy | Std2008)
.Case("mips32r3", Legacy | Std2008)
.Case("mips32r5", Legacy | Std2008)
.Case("mips32r6", Std2008)
.Case("mips64", Legacy)
.Case("mips64r2", Legacy | Std2008)
.Case("mips64r3", Legacy | Std2008)
.Case("mips64r5", Legacy | Std2008)
.Case("mips64r6", Std2008)
.Default(Std2008);
}
bool mips::hasCompactBranches(StringRef &CPU) {
// mips32r6 and mips64r6 have compact branches.
return llvm::StringSwitch<bool>(CPU)
.Case("mips32r6", true)
.Case("mips64r6", true)
.Default(false);
}
bool mips::hasMipsAbiArg(const ArgList &Args, const char *Value) {
Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
return A && (A->getValue() == StringRef(Value));
}
bool mips::isUCLibc(const ArgList &Args) {
Arg *A = Args.getLastArg(options::OPT_m_libc_Group);
return A && A->getOption().matches(options::OPT_muclibc);
}
bool mips::isNaN2008(const ArgList &Args, const llvm::Triple &Triple) {
if (Arg *NaNArg = Args.getLastArg(options::OPT_mnan_EQ))
return llvm::StringSwitch<bool>(NaNArg->getValue())
.Case("2008", true)
.Case("legacy", false)
.Default(false);
// NaN2008 is the default for MIPS32r6/MIPS64r6.
return llvm::StringSwitch<bool>(getCPUName(Args, Triple))
.Cases("mips32r6", "mips64r6", true)
.Default(false);
return false;
}
bool mips::isFP64ADefault(const llvm::Triple &Triple, StringRef CPUName) {
if (!Triple.isAndroid())
return false;
// Android MIPS32R6 defaults to FP64A.
return llvm::StringSwitch<bool>(CPUName)
.Case("mips32r6", true)
.Default(false);
}
bool mips::isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName,
StringRef ABIName, mips::FloatABI FloatABI) {
if (Triple.getVendor() != llvm::Triple::ImaginationTechnologies &&
Triple.getVendor() != llvm::Triple::MipsTechnologies &&
!Triple.isAndroid())
return false;
if (ABIName != "32")
return false;
// FPXX shouldn't be used if either -msoft-float or -mfloat-abi=soft is
// present.
if (FloatABI == mips::FloatABI::Soft)
return false;
return llvm::StringSwitch<bool>(CPUName)
.Cases("mips2", "mips3", "mips4", "mips5", true)
.Cases("mips32", "mips32r2", "mips32r3", "mips32r5", true)
.Cases("mips64", "mips64r2", "mips64r3", "mips64r5", true)
.Default(false);
}
bool mips::shouldUseFPXX(const ArgList &Args, const llvm::Triple &Triple,
StringRef CPUName, StringRef ABIName,
mips::FloatABI FloatABI) {
bool UseFPXX = isFPXXDefault(Triple, CPUName, ABIName, FloatABI);
// FPXX shouldn't be used if -msingle-float is present.
if (Arg *A = Args.getLastArg(options::OPT_msingle_float,
options::OPT_mdouble_float))
if (A->getOption().matches(options::OPT_msingle_float))
UseFPXX = false;
return UseFPXX;
}
bool mips::supportsIndirectJumpHazardBarrier(StringRef &CPU) {
// Supporting the hazard barrier method of dealing with indirect
// jumps requires MIPSR2 support.
return llvm::StringSwitch<bool>(CPU)
.Case("mips32r2", true)
.Case("mips32r3", true)
.Case("mips32r5", true)
.Case("mips32r6", true)
.Case("mips64r2", true)
.Case("mips64r3", true)
.Case("mips64r5", true)
.Case("mips64r6", true)
.Case("octeon", true)
.Case("p5600", true)
.Default(false);
}

View File

@ -0,0 +1,63 @@
//===--- Mips.h - Mips-specific Tool Helpers ----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_MIPS_H
#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_MIPS_H
#include "clang/Driver/Driver.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Option/Option.h"
#include <string>
#include <vector>
namespace clang {
namespace driver {
namespace tools {
bool isMipsArch(llvm::Triple::ArchType Arch);
namespace mips {
typedef enum { Legacy = 1, Std2008 = 2 } IEEE754Standard;
enum class FloatABI {
Invalid,
Soft,
Hard,
};
IEEE754Standard getIEEE754Standard(StringRef &CPU);
bool hasCompactBranches(StringRef &CPU);
void getMipsCPUAndABI(const llvm::opt::ArgList &Args,
const llvm::Triple &Triple, StringRef &CPUName,
StringRef &ABIName);
void getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple,
const llvm::opt::ArgList &Args,
std::vector<StringRef> &Features);
StringRef getGnuCompatibleMipsABIName(StringRef ABI);
mips::FloatABI getMipsFloatABI(const Driver &D, const llvm::opt::ArgList &Args);
std::string getMipsABILibSuffix(const llvm::opt::ArgList &Args,
const llvm::Triple &Triple);
bool hasMipsAbiArg(const llvm::opt::ArgList &Args, const char *Value);
bool isUCLibc(const llvm::opt::ArgList &Args);
bool isNaN2008(const llvm::opt::ArgList &Args, const llvm::Triple &Triple);
bool isFP64ADefault(const llvm::Triple &Triple, StringRef CPUName);
bool isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName,
StringRef ABIName, mips::FloatABI FloatABI);
bool shouldUseFPXX(const llvm::opt::ArgList &Args, const llvm::Triple &Triple,
StringRef CPUName, StringRef ABIName,
mips::FloatABI FloatABI);
bool supportsIndirectJumpHazardBarrier(StringRef &CPU);
} // end namespace mips
} // end namespace target
} // end namespace driver
} // end namespace clang
#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_MIPS_H

View File

@ -0,0 +1,143 @@
//===--- PPC.cpp - PPC Helpers for Tools ------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "PPC.h"
#include "ToolChains/CommonArgs.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/Options.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Option/ArgList.h"
using namespace clang::driver;
using namespace clang::driver::tools;
using namespace clang;
using namespace llvm::opt;
/// getPPCTargetCPU - Get the (LLVM) name of the PowerPC cpu we are targeting.
std::string ppc::getPPCTargetCPU(const ArgList &Args) {
if (Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ)) {
StringRef CPUName = A->getValue();
if (CPUName == "native") {
std::string CPU = llvm::sys::getHostCPUName();
if (!CPU.empty() && CPU != "generic")
return CPU;
else
return "";
}
return llvm::StringSwitch<const char *>(CPUName)
.Case("common", "generic")
.Case("440", "440")
.Case("440fp", "440")
.Case("450", "450")
.Case("601", "601")
.Case("602", "602")
.Case("603", "603")
.Case("603e", "603e")
.Case("603ev", "603ev")
.Case("604", "604")
.Case("604e", "604e")
.Case("620", "620")
.Case("630", "pwr3")
.Case("G3", "g3")
.Case("7400", "7400")
.Case("G4", "g4")
.Case("7450", "7450")
.Case("G4+", "g4+")
.Case("750", "750")
.Case("970", "970")
.Case("G5", "g5")
.Case("a2", "a2")
.Case("a2q", "a2q")
.Case("e500mc", "e500mc")
.Case("e5500", "e5500")
.Case("power3", "pwr3")
.Case("power4", "pwr4")
.Case("power5", "pwr5")
.Case("power5x", "pwr5x")
.Case("power6", "pwr6")
.Case("power6x", "pwr6x")
.Case("power7", "pwr7")
.Case("power8", "pwr8")
.Case("power9", "pwr9")
.Case("pwr3", "pwr3")
.Case("pwr4", "pwr4")
.Case("pwr5", "pwr5")
.Case("pwr5x", "pwr5x")
.Case("pwr6", "pwr6")
.Case("pwr6x", "pwr6x")
.Case("pwr7", "pwr7")
.Case("pwr8", "pwr8")
.Case("pwr9", "pwr9")
.Case("powerpc", "ppc")
.Case("powerpc64", "ppc64")
.Case("powerpc64le", "ppc64le")
.Default("");
}
return "";
}
const char *ppc::getPPCAsmModeForCPU(StringRef Name) {
return llvm::StringSwitch<const char *>(Name)
.Case("pwr7", "-mpower7")
.Case("power7", "-mpower7")
.Case("pwr8", "-mpower8")
.Case("power8", "-mpower8")
.Case("ppc64le", "-mpower8")
.Case("pwr9", "-mpower9")
.Case("power9", "-mpower9")
.Default("-many");
}
void ppc::getPPCTargetFeatures(const Driver &D, const llvm::Triple &Triple,
const ArgList &Args,
std::vector<StringRef> &Features) {
handleTargetFeaturesGroup(Args, Features, options::OPT_m_ppc_Features_Group);
ppc::FloatABI FloatABI = ppc::getPPCFloatABI(D, Args);
if (FloatABI == ppc::FloatABI::Soft)
Features.push_back("-hard-float");
}
ppc::FloatABI ppc::getPPCFloatABI(const Driver &D, const ArgList &Args) {
ppc::FloatABI ABI = ppc::FloatABI::Invalid;
if (Arg *A =
Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
options::OPT_mfloat_abi_EQ)) {
if (A->getOption().matches(options::OPT_msoft_float))
ABI = ppc::FloatABI::Soft;
else if (A->getOption().matches(options::OPT_mhard_float))
ABI = ppc::FloatABI::Hard;
else {
ABI = llvm::StringSwitch<ppc::FloatABI>(A->getValue())
.Case("soft", ppc::FloatABI::Soft)
.Case("hard", ppc::FloatABI::Hard)
.Default(ppc::FloatABI::Invalid);
if (ABI == ppc::FloatABI::Invalid && !StringRef(A->getValue()).empty()) {
D.Diag(clang::diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
ABI = ppc::FloatABI::Hard;
}
}
}
// If unspecified, choose the default based on the platform.
if (ABI == ppc::FloatABI::Invalid) {
ABI = ppc::FloatABI::Hard;
}
return ABI;
}
bool ppc::hasPPCAbiArg(const ArgList &Args, const char *Value) {
Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
return A && (A->getValue() == StringRef(Value));
}

View File

@ -0,0 +1,46 @@
//===--- PPC.h - PPC-specific Tool Helpers ----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_PPC_H
#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_PPC_H
#include "clang/Driver/Driver.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Option/Option.h"
#include <string>
#include <vector>
namespace clang {
namespace driver {
namespace tools {
namespace ppc {
bool hasPPCAbiArg(const llvm::opt::ArgList &Args, const char *Value);
enum class FloatABI {
Invalid,
Soft,
Hard,
};
FloatABI getPPCFloatABI(const Driver &D, const llvm::opt::ArgList &Args);
std::string getPPCTargetCPU(const llvm::opt::ArgList &Args);
const char *getPPCAsmModeForCPU(StringRef Name);
void getPPCTargetFeatures(const Driver &D, const llvm::Triple &Triple,
const llvm::opt::ArgList &Args,
std::vector<llvm::StringRef> &Features);
} // end namespace ppc
} // end namespace target
} // end namespace driver
} // end namespace clang
#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_PPC_H

View File

@ -0,0 +1,100 @@
//===--- Sparc.cpp - Tools Implementations ----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "Sparc.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/Options.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Option/ArgList.h"
using namespace clang::driver;
using namespace clang::driver::tools;
using namespace clang;
using namespace llvm::opt;
const char *sparc::getSparcAsmModeForCPU(StringRef Name,
const llvm::Triple &Triple) {
if (Triple.getArch() == llvm::Triple::sparcv9) {
return llvm::StringSwitch<const char *>(Name)
.Case("niagara", "-Av9b")
.Case("niagara2", "-Av9b")
.Case("niagara3", "-Av9d")
.Case("niagara4", "-Av9d")
.Default("-Av9");
} else {
return llvm::StringSwitch<const char *>(Name)
.Case("v8", "-Av8")
.Case("supersparc", "-Av8")
.Case("sparclite", "-Asparclite")
.Case("f934", "-Asparclite")
.Case("hypersparc", "-Av8")
.Case("sparclite86x", "-Asparclite")
.Case("sparclet", "-Asparclet")
.Case("tsc701", "-Asparclet")
.Case("v9", "-Av8plus")
.Case("ultrasparc", "-Av8plus")
.Case("ultrasparc3", "-Av8plus")
.Case("niagara", "-Av8plusb")
.Case("niagara2", "-Av8plusb")
.Case("niagara3", "-Av8plusd")
.Case("niagara4", "-Av8plusd")
.Case("leon2", "-Av8")
.Case("at697e", "-Av8")
.Case("at697f", "-Av8")
.Case("leon3", "-Av8")
.Case("ut699", "-Av8")
.Case("gr712rc", "-Av8")
.Case("leon4", "-Av8")
.Case("gr740", "-Av8")
.Default("-Av8");
}
}
sparc::FloatABI sparc::getSparcFloatABI(const Driver &D,
const ArgList &Args) {
sparc::FloatABI ABI = sparc::FloatABI::Invalid;
if (Arg *A = Args.getLastArg(clang::driver::options::OPT_msoft_float,
options::OPT_mhard_float,
options::OPT_mfloat_abi_EQ)) {
if (A->getOption().matches(clang::driver::options::OPT_msoft_float))
ABI = sparc::FloatABI::Soft;
else if (A->getOption().matches(options::OPT_mhard_float))
ABI = sparc::FloatABI::Hard;
else {
ABI = llvm::StringSwitch<sparc::FloatABI>(A->getValue())
.Case("soft", sparc::FloatABI::Soft)
.Case("hard", sparc::FloatABI::Hard)
.Default(sparc::FloatABI::Invalid);
if (ABI == sparc::FloatABI::Invalid &&
!StringRef(A->getValue()).empty()) {
D.Diag(clang::diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
ABI = sparc::FloatABI::Hard;
}
}
}
// If unspecified, choose the default based on the platform.
// Only the hard-float ABI on Sparc is standardized, and it is the
// default. GCC also supports a nonstandard soft-float ABI mode, also
// implemented in LLVM. However as this is not standard we set the default
// to be hard-float.
if (ABI == sparc::FloatABI::Invalid) {
ABI = sparc::FloatABI::Hard;
}
return ABI;
}
void sparc::getSparcTargetFeatures(const Driver &D, const ArgList &Args,
std::vector<StringRef> &Features) {
sparc::FloatABI FloatABI = sparc::getSparcFloatABI(D, Args);
if (FloatABI == sparc::FloatABI::Soft)
Features.push_back("+soft-float");
}

View File

@ -0,0 +1,42 @@
//===--- Sparc.h - Sparc-specific Tool Helpers ----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_SPARC_H
#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_SPARC_H
#include "clang/Driver/Driver.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Option/Option.h"
#include <string>
#include <vector>
namespace clang {
namespace driver {
namespace tools {
namespace sparc {
enum class FloatABI {
Invalid,
Soft,
Hard,
};
FloatABI getSparcFloatABI(const Driver &D, const llvm::opt::ArgList &Args);
void getSparcTargetFeatures(const Driver &D, const llvm::opt::ArgList &Args,
std::vector<llvm::StringRef> &Features);
const char *getSparcAsmModeForCPU(llvm::StringRef Name,
const llvm::Triple &Triple);
} // end namespace sparc
} // end namespace target
} // end namespace driver
} // end namespace clang
#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_SPARC_H

View File

@ -0,0 +1,41 @@
//===--- SystemZ.cpp - SystemZ Helpers for Tools ----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "SystemZ.h"
#include "clang/Driver/Options.h"
#include "llvm/Option/ArgList.h"
using namespace clang::driver;
using namespace clang::driver::tools;
using namespace clang;
using namespace llvm::opt;
const char *systemz::getSystemZTargetCPU(const ArgList &Args) {
if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ))
return A->getValue();
return "z10";
}
void systemz::getSystemZTargetFeatures(const ArgList &Args,
std::vector<llvm::StringRef> &Features) {
// -m(no-)htm overrides use of the transactional-execution facility.
if (Arg *A = Args.getLastArg(options::OPT_mhtm, options::OPT_mno_htm)) {
if (A->getOption().matches(options::OPT_mhtm))
Features.push_back("+transactional-execution");
else
Features.push_back("-transactional-execution");
}
// -m(no-)vx overrides use of the vector facility.
if (Arg *A = Args.getLastArg(options::OPT_mvx, options::OPT_mno_vx)) {
if (A->getOption().matches(options::OPT_mvx))
Features.push_back("+vector");
else
Features.push_back("-vector");
}
}

View File

@ -0,0 +1,32 @@
//===--- SystemZ.h - SystemZ-specific Tool Helpers --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_SYSTEMZ_H
#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_SYSTEMZ_H
#include "llvm/ADT/StringRef.h"
#include "llvm/Option/Option.h"
#include <vector>
namespace clang {
namespace driver {
namespace tools {
namespace systemz {
const char *getSystemZTargetCPU(const llvm::opt::ArgList &Args);
void getSystemZTargetFeatures(const llvm::opt::ArgList &Args,
std::vector<llvm::StringRef> &Features);
} // end namespace systemz
} // end namespace target
} // end namespace driver
} // end namespace clang
#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_SYSTEMZ_H

View File

@ -0,0 +1,171 @@
//===--- X86.cpp - X86 Helpers for Tools ------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "X86.h"
#include "ToolChains/CommonArgs.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/Options.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Option/ArgList.h"
using namespace clang::driver;
using namespace clang::driver::tools;
using namespace clang;
using namespace llvm::opt;
const char *x86::getX86TargetCPU(const ArgList &Args,
const llvm::Triple &Triple) {
if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ)) {
if (StringRef(A->getValue()) != "native") {
if (Triple.isOSDarwin() && Triple.getArchName() == "x86_64h")
return "core-avx2";
return A->getValue();
}
// FIXME: Reject attempts to use -march=native unless the target matches
// the host.
//
// FIXME: We should also incorporate the detected target features for use
// with -native.
std::string CPU = llvm::sys::getHostCPUName();
if (!CPU.empty() && CPU != "generic")
return Args.MakeArgString(CPU);
}
if (const Arg *A = Args.getLastArg(options::OPT__SLASH_arch)) {
// Mapping built by referring to X86TargetInfo::getDefaultFeatures().
StringRef Arch = A->getValue();
const char *CPU;
if (Triple.getArch() == llvm::Triple::x86) {
CPU = llvm::StringSwitch<const char *>(Arch)
.Case("IA32", "i386")
.Case("SSE", "pentium3")
.Case("SSE2", "pentium4")
.Case("AVX", "sandybridge")
.Case("AVX2", "haswell")
.Default(nullptr);
} else {
CPU = llvm::StringSwitch<const char *>(Arch)
.Case("AVX", "sandybridge")
.Case("AVX2", "haswell")
.Default(nullptr);
}
if (CPU)
return CPU;
}
// Select the default CPU if none was given (or detection failed).
if (Triple.getArch() != llvm::Triple::x86_64 &&
Triple.getArch() != llvm::Triple::x86)
return nullptr; // This routine is only handling x86 targets.
bool Is64Bit = Triple.getArch() == llvm::Triple::x86_64;
// FIXME: Need target hooks.
if (Triple.isOSDarwin()) {
if (Triple.getArchName() == "x86_64h")
return "core-avx2";
// macosx10.12 drops support for all pre-Penryn Macs.
// Simulators can still run on 10.11 though, like Xcode.
if (Triple.isMacOSX() && !Triple.isOSVersionLT(10, 12))
return "penryn";
// The oldest x86_64 Macs have core2/Merom; the oldest x86 Macs have Yonah.
return Is64Bit ? "core2" : "yonah";
}
// Set up default CPU name for PS4 compilers.
if (Triple.isPS4CPU())
return "btver2";
// On Android use targets compatible with gcc
if (Triple.isAndroid())
return Is64Bit ? "x86-64" : "i686";
// Everything else goes to x86-64 in 64-bit mode.
if (Is64Bit)
return "x86-64";
switch (Triple.getOS()) {
case llvm::Triple::FreeBSD:
case llvm::Triple::NetBSD:
case llvm::Triple::OpenBSD:
return "i486";
case llvm::Triple::Haiku:
return "i586";
default:
// Fallback to p4.
return "pentium4";
}
}
void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple,
const ArgList &Args,
std::vector<StringRef> &Features) {
// If -march=native, autodetect the feature list.
if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ)) {
if (StringRef(A->getValue()) == "native") {
llvm::StringMap<bool> HostFeatures;
if (llvm::sys::getHostCPUFeatures(HostFeatures))
for (auto &F : HostFeatures)
Features.push_back(
Args.MakeArgString((F.second ? "+" : "-") + F.first()));
}
}
if (Triple.getArchName() == "x86_64h") {
// x86_64h implies quite a few of the more modern subtarget features
// for Haswell class CPUs, but not all of them. Opt-out of a few.
Features.push_back("-rdrnd");
Features.push_back("-aes");
Features.push_back("-pclmul");
Features.push_back("-rtm");
Features.push_back("-fsgsbase");
}
const llvm::Triple::ArchType ArchType = Triple.getArch();
// Add features to be compatible with gcc for Android.
if (Triple.isAndroid()) {
if (ArchType == llvm::Triple::x86_64) {
Features.push_back("+sse4.2");
Features.push_back("+popcnt");
} else
Features.push_back("+ssse3");
}
// Set features according to the -arch flag on MSVC.
if (Arg *A = Args.getLastArg(options::OPT__SLASH_arch)) {
StringRef Arch = A->getValue();
bool ArchUsed = false;
// First, look for flags that are shared in x86 and x86-64.
if (ArchType == llvm::Triple::x86_64 || ArchType == llvm::Triple::x86) {
if (Arch == "AVX" || Arch == "AVX2") {
ArchUsed = true;
Features.push_back(Args.MakeArgString("+" + Arch.lower()));
}
}
// Then, look for x86-specific flags.
if (ArchType == llvm::Triple::x86) {
if (Arch == "IA32") {
ArchUsed = true;
} else if (Arch == "SSE" || Arch == "SSE2") {
ArchUsed = true;
Features.push_back(Args.MakeArgString("+" + Arch.lower()));
}
}
if (!ArchUsed)
D.Diag(clang::diag::warn_drv_unused_argument) << A->getAsString(Args);
}
// Now add any that the user explicitly requested on the command line,
// which may override the defaults.
handleTargetFeaturesGroup(Args, Features, options::OPT_m_x86_Features_Group);
}

View File

@ -0,0 +1,37 @@
//===--- X86.h - X86-specific Tool Helpers ----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_X86_H
#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_X86_H
#include "clang/Driver/Driver.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Option/Option.h"
#include <string>
#include <vector>
namespace clang {
namespace driver {
namespace tools {
namespace x86 {
const char *getX86TargetCPU(const llvm::opt::ArgList &Args,
const llvm::Triple &Triple);
void getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple,
const llvm::opt::ArgList &Args,
std::vector<llvm::StringRef> &Features);
} // end namespace x86
} // end namespace target
} // end namespace driver
} // end namespace clang
#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_X86_H

Some files were not shown because too many files have changed in this diff Show More