summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Basic/Targets.cpp113
-rw-r--r--clang/lib/Driver/ToolChains.cpp215
-rw-r--r--clang/lib/Driver/ToolChains.h15
-rw-r--r--clang/lib/Driver/Tools.cpp213
4 files changed, 302 insertions, 254 deletions
diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp
index d078683fd35..132864fa8df 100644
--- a/clang/lib/Basic/Targets.cpp
+++ b/clang/lib/Basic/Targets.cpp
@@ -5645,14 +5645,27 @@ class HexagonTargetInfo : public TargetInfo {
static const char * const GCCRegNames[];
static const TargetInfo::GCCRegAlias GCCRegAliases[];
std::string CPU;
+ bool HasHVX, HasHVXDouble;
+
public:
HexagonTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
BigEndian = false;
- DataLayoutString = "e-m:e-p:32:32-i1:32-i64:64-a:0-n32";
+ DataLayoutString = "e-m:e-p:32:32:32-"
+ "i64:64:64-i32:32:32-i16:16:16-i1:8:8-"
+ "f64:64:64-f32:32:32-v64:64:64-v32:32:32-a:0-n16:32";
+ SizeType = UnsignedInt;
+ PtrDiffType = SignedInt;
+ IntPtrType = SignedInt;
// {} in inline assembly are packet specifiers, not assembly variant
// specifiers.
NoAsmVariants = true;
+
+ LargeArrayMinWidth = 64;
+ LargeArrayAlign = 64;
+ UseBitFieldTypeAlignment = true;
+ ZeroLengthBitfieldBoundary = 32;
+ HasHVX = HasHVXDouble = false;
}
ArrayRef<Builtin::Info> getTargetBuiltins() const override {
@@ -5668,10 +5681,23 @@ public:
void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override;
+ bool isCLZForZeroUndef() const override { return false; }
+
bool hasFeature(StringRef Feature) const override {
- return Feature == "hexagon";
+ return llvm::StringSwitch<bool>(Feature)
+ .Case("hexagon", true)
+ .Case("hvx", HasHVX)
+ .Case("hvx-double", HasHVXDouble)
+ .Default(false);
}
+ bool initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
+ StringRef CPU, const std::vector<std::string> &FeaturesVec)
+ const override;
+
+ bool handleTargetFeatures(std::vector<std::string> &Features,
+ DiagnosticsEngine &Diags) override;
+
BuiltinVaListKind getBuiltinVaListKind() const override {
return TargetInfo::CharPtrBuiltinVaList;
}
@@ -5685,71 +5711,77 @@ public:
return llvm::StringSwitch<const char*>(Name)
.Case("hexagonv4", "4")
.Case("hexagonv5", "5")
+ .Case("hexagonv55", "55")
+ .Case("hexagonv60", "60")
.Default(nullptr);
}
bool setCPU(const std::string &Name) override {
if (!getHexagonCPUSuffix(Name))
return false;
-
CPU = Name;
return true;
}
+
+ int getEHDataRegisterNumber(unsigned RegNo) const override {
+ return RegNo < 2 ? RegNo : -1;
+ }
};
void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts,
- MacroBuilder &Builder) const {
- Builder.defineMacro("qdsp6");
- Builder.defineMacro("__qdsp6", "1");
+ MacroBuilder &Builder) const {
Builder.defineMacro("__qdsp6__", "1");
-
- Builder.defineMacro("hexagon");
- Builder.defineMacro("__hexagon", "1");
Builder.defineMacro("__hexagon__", "1");
- if(CPU == "hexagonv1") {
- Builder.defineMacro("__HEXAGON_V1__");
- Builder.defineMacro("__HEXAGON_ARCH__", "1");
- if(Opts.HexagonQdsp6Compat) {
- Builder.defineMacro("__QDSP6_V1__");
- Builder.defineMacro("__QDSP6_ARCH__", "1");
- }
- }
- else if(CPU == "hexagonv2") {
- Builder.defineMacro("__HEXAGON_V2__");
- Builder.defineMacro("__HEXAGON_ARCH__", "2");
- if(Opts.HexagonQdsp6Compat) {
- Builder.defineMacro("__QDSP6_V2__");
- Builder.defineMacro("__QDSP6_ARCH__", "2");
- }
- }
- else if(CPU == "hexagonv3") {
- Builder.defineMacro("__HEXAGON_V3__");
- Builder.defineMacro("__HEXAGON_ARCH__", "3");
- if(Opts.HexagonQdsp6Compat) {
- Builder.defineMacro("__QDSP6_V3__");
- Builder.defineMacro("__QDSP6_ARCH__", "3");
- }
- }
- else if(CPU == "hexagonv4") {
+ if (CPU == "hexagonv4") {
Builder.defineMacro("__HEXAGON_V4__");
Builder.defineMacro("__HEXAGON_ARCH__", "4");
- if(Opts.HexagonQdsp6Compat) {
+ if (Opts.HexagonQdsp6Compat) {
Builder.defineMacro("__QDSP6_V4__");
Builder.defineMacro("__QDSP6_ARCH__", "4");
}
- }
- else if(CPU == "hexagonv5") {
+ } else if (CPU == "hexagonv5") {
Builder.defineMacro("__HEXAGON_V5__");
Builder.defineMacro("__HEXAGON_ARCH__", "5");
if(Opts.HexagonQdsp6Compat) {
Builder.defineMacro("__QDSP6_V5__");
Builder.defineMacro("__QDSP6_ARCH__", "5");
}
+ } else if (CPU == "hexagonv60") {
+ Builder.defineMacro("__HEXAGON_V60__");
+ Builder.defineMacro("__HEXAGON_ARCH__", "60");
+ Builder.defineMacro("__QDSP6_V60__");
+ Builder.defineMacro("__QDSP6_ARCH__", "60");
+ }
+}
+
+bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
+ DiagnosticsEngine &Diags) {
+ for (auto &F : Features) {
+ if (F == "+hvx")
+ HasHVX = true;
+ else if (F == "-hvx")
+ HasHVX = HasHVXDouble = false;
+ else if (F == "+hvx-double")
+ HasHVX = HasHVXDouble = true;
+ else if (F == "-hvx-double")
+ HasHVXDouble = false;
}
+ return true;
+}
+
+bool HexagonTargetInfo::initFeatureMap(llvm::StringMap<bool> &Features,
+ DiagnosticsEngine &Diags, StringRef CPU,
+ const std::vector<std::string> &FeaturesVec) const {
+ // Default for v60: -hvx, -hvx-double.
+ Features["hvx"] = false;
+ Features["hvx-double"] = false;
+
+ return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
}
-const char * const HexagonTargetInfo::GCCRegNames[] = {
+
+const char *const HexagonTargetInfo::GCCRegNames[] = {
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
@@ -5758,16 +5790,15 @@ const char * const HexagonTargetInfo::GCCRegNames[] = {
"sa0", "lc0", "sa1", "lc1", "m0", "m1", "usr", "ugp"
};
-ArrayRef<const char *> HexagonTargetInfo::getGCCRegNames() const {
+ArrayRef<const char*> HexagonTargetInfo::getGCCRegNames() const {
return llvm::makeArrayRef(GCCRegNames);
}
-
const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = {
{ { "sp" }, "r29" },
{ { "fp" }, "r30" },
{ { "lr" }, "r31" },
- };
+};
ArrayRef<TargetInfo::GCCRegAlias> HexagonTargetInfo::getGCCRegAliases() const {
return llvm::makeArrayRef(GCCRegAliases);
diff --git a/clang/lib/Driver/ToolChains.cpp b/clang/lib/Driver/ToolChains.cpp
index 7370e623210..2d882eb5368 100644
--- a/clang/lib/Driver/ToolChains.cpp
+++ b/clang/lib/Driver/ToolChains.cpp
@@ -2555,122 +2555,108 @@ std::string MipsLLVMToolChain::getCompilerRT(const ArgList &Args,
/// Hexagon Toolchain
-std::string HexagonToolChain::GetGnuDir(const std::string &InstalledDir,
- const ArgList &Args) const {
- // Locate the rest of the toolchain ...
- std::string GccToolchain = getGCCToolchainDir(Args);
+std::string HexagonToolChain::getHexagonTargetDir(
+ const std::string &InstalledDir,
+ const SmallVectorImpl<std::string> &PrefixDirs) const {
+ std::string InstallRelDir;
+ const Driver &D = getDriver();
- if (!GccToolchain.empty())
- return GccToolchain;
+ // Locate the rest of the toolchain ...
+ for (auto &I : PrefixDirs)
+ if (D.getVFS().exists(I))
+ return I;
- std::string InstallRelDir = InstalledDir + "/../../gnu";
- if (getVFS().exists(InstallRelDir))
+ if (getVFS().exists(InstallRelDir = InstalledDir + "/../target"))
return InstallRelDir;
- std::string PrefixRelDir = std::string(LLVM_PREFIX) + "/../gnu";
+ std::string PrefixRelDir = std::string(LLVM_PREFIX) + "/target";
if (getVFS().exists(PrefixRelDir))
return PrefixRelDir;
return InstallRelDir;
}
-const char *HexagonToolChain::GetSmallDataThreshold(const ArgList &Args) {
- Arg *A;
- A = Args.getLastArg(options::OPT_G, options::OPT_G_EQ,
- options::OPT_msmall_data_threshold_EQ);
- if (A)
- return A->getValue();
+Optional<unsigned> HexagonToolChain::getSmallDataThreshold(
+ const ArgList &Args) {
+ StringRef Gn = "";
+ if (Arg *A = Args.getLastArg(options::OPT_G, options::OPT_G_EQ,
+ options::OPT_msmall_data_threshold_EQ)) {
+ Gn = A->getValue();
+ } else if (Args.getLastArg(options::OPT_shared, options::OPT_fpic,
+ options::OPT_fPIC)) {
+ Gn = "0";
+ }
- A = Args.getLastArg(options::OPT_shared, options::OPT_fpic,
- options::OPT_fPIC);
- if (A)
- return "0";
+ unsigned G;
+ if (!Gn.getAsInteger(10, G))
+ return G;
- return nullptr;
+ return None;
}
-bool HexagonToolChain::UsesG0(const char *smallDataThreshold) {
- return smallDataThreshold && smallDataThreshold[0] == '0';
-}
-static void GetHexagonLibraryPaths(const HexagonToolChain &TC,
- const ArgList &Args, const std::string &Ver,
- const std::string &MarchString,
- const std::string &InstalledDir,
- ToolChain::path_list *LibPaths) {
- bool buildingLib = Args.hasArg(options::OPT_shared);
+void HexagonToolChain::getHexagonLibraryPaths(const ArgList &Args,
+ ToolChain::path_list &LibPaths) const {
+ const Driver &D = getDriver();
//----------------------------------------------------------------------------
// -L Args
//----------------------------------------------------------------------------
for (Arg *A : Args.filtered(options::OPT_L))
for (const char *Value : A->getValues())
- LibPaths->push_back(Value);
+ LibPaths.push_back(Value);
//----------------------------------------------------------------------------
// Other standard paths
//----------------------------------------------------------------------------
- const std::string MarchSuffix = "/" + MarchString;
- const std::string G0Suffix = "/G0";
- const std::string MarchG0Suffix = MarchSuffix + G0Suffix;
- const std::string RootDir = TC.GetGnuDir(InstalledDir, Args) + "/";
-
- // lib/gcc/hexagon/...
- std::string LibGCCHexagonDir = RootDir + "lib/gcc/hexagon/";
- if (buildingLib) {
- LibPaths->push_back(LibGCCHexagonDir + Ver + MarchG0Suffix);
- LibPaths->push_back(LibGCCHexagonDir + Ver + G0Suffix);
- }
- LibPaths->push_back(LibGCCHexagonDir + Ver + MarchSuffix);
- LibPaths->push_back(LibGCCHexagonDir + Ver);
-
- // lib/gcc/...
- LibPaths->push_back(RootDir + "lib/gcc");
-
- // hexagon/lib/...
- std::string HexagonLibDir = RootDir + "hexagon/lib";
- if (buildingLib) {
- LibPaths->push_back(HexagonLibDir + MarchG0Suffix);
- LibPaths->push_back(HexagonLibDir + G0Suffix);
+ std::vector<std::string> RootDirs;
+ std::copy(D.PrefixDirs.begin(), D.PrefixDirs.end(), RootDirs.begin());
+
+ std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
+ D.PrefixDirs);
+ if (std::find(RootDirs.begin(), RootDirs.end(), TargetDir) == RootDirs.end())
+ RootDirs.push_back(TargetDir);
+
+ bool HasPIC = Args.hasArg(options::OPT_fpic, options::OPT_fPIC);
+ // Assume G0 with -shared.
+ bool HasG0 = Args.hasArg(options::OPT_shared);
+ if (auto G = getSmallDataThreshold(Args))
+ HasG0 = G.getValue() == 0;
+
+ const std::string CpuVer = GetTargetCPUVersion(Args).str();
+ for (auto &Dir : RootDirs) {
+ std::string LibDir = Dir + "/hexagon/lib";
+ std::string LibDirCpu = LibDir + '/' + CpuVer;
+ if (HasG0) {
+ if (HasPIC)
+ LibPaths.push_back(LibDirCpu + "/G0/pic");
+ LibPaths.push_back(LibDirCpu + "/G0");
+ }
+ LibPaths.push_back(LibDirCpu);
+ LibPaths.push_back(LibDir);
}
- LibPaths->push_back(HexagonLibDir + MarchSuffix);
- LibPaths->push_back(HexagonLibDir);
}
HexagonToolChain::HexagonToolChain(const Driver &D, const llvm::Triple &Triple,
- const ArgList &Args)
+ const llvm::opt::ArgList &Args)
: Linux(D, Triple, Args) {
- const std::string InstalledDir(getDriver().getInstalledDir());
- const std::string GnuDir = GetGnuDir(InstalledDir, Args);
+ const std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
+ D.PrefixDirs);
// Note: Generic_GCC::Generic_GCC adds InstalledDir and getDriver().Dir to
// program paths
- const std::string BinDir(GnuDir + "/bin");
+ const std::string BinDir(TargetDir + "/bin");
if (D.getVFS().exists(BinDir))
getProgramPaths().push_back(BinDir);
- // Determine version of GCC libraries and headers to use.
- const std::string HexagonDir(GnuDir + "/lib/gcc/hexagon");
- std::error_code ec;
- GCCVersion MaxVersion = GCCVersion::Parse("0.0.0");
- for (vfs::directory_iterator di = D.getVFS().dir_begin(HexagonDir, ec), de;
- !ec && di != de; di = di.increment(ec)) {
- GCCVersion cv = GCCVersion::Parse(llvm::sys::path::filename(di->getName()));
- if (MaxVersion < cv)
- MaxVersion = cv;
- }
- GCCLibAndIncVersion = MaxVersion;
-
- ToolChain::path_list *LibPaths = &getFilePaths();
+ ToolChain::path_list &LibPaths = getFilePaths();
// Remove paths added by Linux toolchain. Currently Hexagon_TC really targets
// 'elf' OS type, so the Linux paths are not appropriate. When we actually
// support 'linux' we'll need to fix this up
- LibPaths->clear();
-
- GetHexagonLibraryPaths(*this, Args, GetGCCLibAndIncVersion(),
- GetTargetCPU(Args), InstalledDir, LibPaths);
+ LibPaths.clear();
+ getHexagonLibraryPaths(Args, LibPaths);
}
HexagonToolChain::~HexagonToolChain() {}
@@ -2685,18 +2671,14 @@ Tool *HexagonToolChain::buildLinker() const {
void HexagonToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const {
- const Driver &D = getDriver();
-
if (DriverArgs.hasArg(options::OPT_nostdinc) ||
DriverArgs.hasArg(options::OPT_nostdlibinc))
return;
- std::string Ver(GetGCCLibAndIncVersion());
- std::string GnuDir = GetGnuDir(D.InstalledDir, DriverArgs);
- std::string HexagonDir(GnuDir + "/lib/gcc/hexagon/" + Ver);
- addExternCSystemInclude(DriverArgs, CC1Args, HexagonDir + "/include");
- addExternCSystemInclude(DriverArgs, CC1Args, HexagonDir + "/include-fixed");
- addExternCSystemInclude(DriverArgs, CC1Args, GnuDir + "/hexagon/include");
+ const Driver &D = getDriver();
+ std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
+ D.PrefixDirs);
+ addExternCSystemInclude(DriverArgs, CC1Args, TargetDir + "/hexagon/include");
}
void HexagonToolChain::AddClangCXXStdlibIncludeArgs(
@@ -2706,12 +2688,8 @@ void HexagonToolChain::AddClangCXXStdlibIncludeArgs(
return;
const Driver &D = getDriver();
- std::string Ver(GetGCCLibAndIncVersion());
- SmallString<128> IncludeDir(GetGnuDir(D.InstalledDir, DriverArgs));
-
- llvm::sys::path::append(IncludeDir, "hexagon/include/c++/");
- llvm::sys::path::append(IncludeDir, Ver);
- addSystemInclude(DriverArgs, CC1Args, IncludeDir);
+ std::string TargetDir = getHexagonTargetDir(D.InstalledDir, D.PrefixDirs);
+ addSystemInclude(DriverArgs, CC1Args, TargetDir + "/hexagon/include/c++");
}
ToolChain::CXXStdlibType
@@ -2721,53 +2699,34 @@ HexagonToolChain::GetCXXStdlibType(const ArgList &Args) const {
return ToolChain::CST_Libstdcxx;
StringRef Value = A->getValue();
- if (Value != "libstdc++") {
+ if (Value != "libstdc++")
getDriver().Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args);
- }
return ToolChain::CST_Libstdcxx;
}
-static int getHexagonVersion(const ArgList &Args) {
- Arg *A = Args.getLastArg(options::OPT_march_EQ, options::OPT_mcpu_EQ);
- // Select the default CPU (v4) if none was given.
- if (!A)
- return 4;
-
- // FIXME: produce errors if we cannot parse the version.
- StringRef WhichHexagon = A->getValue();
- if (WhichHexagon.startswith("hexagonv")) {
- int Val;
- if (!WhichHexagon.substr(sizeof("hexagonv") - 1).getAsInteger(10, Val))
- return Val;
- }
- if (WhichHexagon.startswith("v")) {
- int Val;
- if (!WhichHexagon.substr(1).getAsInteger(10, Val))
- return Val;
- }
-
- // FIXME: should probably be an error.
- return 4;
+//
+// Returns the default CPU for Hexagon. This is the default compilation target
+// if no Hexagon processor is selected at the command-line.
+//
+const StringRef HexagonToolChain::GetDefaultCPU() {
+ return "hexagonv60";
}
-StringRef HexagonToolChain::GetTargetCPU(const ArgList &Args) {
- int V = getHexagonVersion(Args);
- // FIXME: We don't support versions < 4. We should error on them.
- switch (V) {
- default:
- llvm_unreachable("Unexpected version");
- case 5:
- return "v5";
- case 4:
- return "v4";
- case 3:
- return "v3";
- case 2:
- return "v2";
- case 1:
- return "v1";
+const StringRef HexagonToolChain::GetTargetCPUVersion(const ArgList &Args) {
+ Arg *CpuArg = nullptr;
+
+ for (auto &A : Args) {
+ if (A->getOption().matches(options::OPT_mcpu_EQ)) {
+ CpuArg = A;
+ A->claim();
+ }
}
+
+ StringRef CPU = CpuArg ? CpuArg->getValue() : GetDefaultCPU();
+ if (CPU.startswith("hexagon"))
+ return CPU.substr(sizeof("hexagon") - 1);
+ return CPU;
}
// End Hexagon
diff --git a/clang/lib/Driver/ToolChains.h b/clang/lib/Driver/ToolChains.h
index ceb61ca8472..257750eff3e 100644
--- a/clang/lib/Driver/ToolChains.h
+++ b/clang/lib/Driver/ToolChains.h
@@ -875,14 +875,17 @@ public:
return true;
}
- std::string GetGnuDir(const std::string &InstalledDir,
- const llvm::opt::ArgList &Args) const;
+ std::string getHexagonTargetDir(
+ const std::string &InstalledDir,
+ const SmallVectorImpl<std::string> &PrefixDirs) const;
+ void getHexagonLibraryPaths(const llvm::opt::ArgList &Args,
+ ToolChain::path_list &LibPaths) const;
- static StringRef GetTargetCPU(const llvm::opt::ArgList &Args);
+ static const StringRef GetDefaultCPU();
+ static const StringRef GetTargetCPUVersion(const llvm::opt::ArgList &Args);
- static const char *GetSmallDataThreshold(const llvm::opt::ArgList &Args);
-
- static bool UsesG0(const char *smallDataThreshold);
+ static Optional<unsigned> getSmallDataThreshold(
+ const llvm::opt::ArgList &Args);
};
class LLVM_LIBRARY_VISIBILITY AMDGPUToolChain : public Generic_ELF {
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp
index a73c0863d0a..7a02a115b88 100644
--- a/clang/lib/Driver/Tools.cpp
+++ b/clang/lib/Driver/Tools.cpp
@@ -1714,7 +1714,8 @@ static std::string getCPUName(const ArgList &Args, const llvm::Triple &T,
return getX86TargetCPU(Args, T);
case llvm::Triple::hexagon:
- return "hexagon" + toolchains::HexagonToolChain::GetTargetCPU(Args).str();
+ return "hexagon" +
+ toolchains::HexagonToolChain::GetTargetCPUVersion(Args).str();
case llvm::Triple::systemz:
return getSystemZTargetCPU(Args);
@@ -1997,12 +1998,11 @@ void Clang::AddHexagonTargetArgs(const ArgList &Args,
CmdArgs.push_back("-mqdsp6-compat");
CmdArgs.push_back("-Wreturn-type");
- if (const char *v =
- toolchains::HexagonToolChain::GetSmallDataThreshold(Args)) {
- std::string SmallDataThreshold = "-hexagon-small-data-threshold=";
- SmallDataThreshold += v;
+ if (auto G = toolchains::HexagonToolChain::getSmallDataThreshold(Args)) {
+ std::string N = llvm::utostr(G.getValue());
+ std::string Opt = std::string("-hexagon-small-data-threshold=") + N;
CmdArgs.push_back("-mllvm");
- CmdArgs.push_back(Args.MakeArgString(SmallDataThreshold));
+ CmdArgs.push_back(Args.MakeArgString(Opt));
}
if (!Args.hasArg(options::OPT_fno_short_enums))
@@ -2182,6 +2182,29 @@ static void getAArch64TargetFeatures(const Driver &D, const ArgList &Args,
Features.push_back("+reserve-x18");
}
+static void getHexagonTargetFeatures(const ArgList &Args,
+ std::vector<const char *> &Features) {
+ bool HasHVX = false, HasHVXD = false;
+
+ for (auto &A : Args) {
+ auto &Opt = A->getOption();
+ if (Opt.matches(options::OPT_mhexagon_hvx))
+ HasHVX = true;
+ else if (Opt.matches(options::OPT_mno_hexagon_hvx))
+ HasHVXD = HasHVX = false;
+ else if (Opt.matches(options::OPT_mhexagon_hvx_double))
+ HasHVXD = HasHVX = true;
+ else if (Opt.matches(options::OPT_mno_hexagon_hvx_double))
+ HasHVXD = false;
+ else
+ continue;
+ A->claim();
+ }
+
+ Features.push_back(HasHVX ? "+hvx" : "-hvx");
+ Features.push_back(HasHVXD ? "+hvx-double" : "-hvx-double");
+}
+
static void getWebAssemblyTargetFeatures(const ArgList &Args,
std::vector<const char *> &Features) {
for (const Arg *A : Args.filtered(options::OPT_m_wasm_Features_Group)) {
@@ -2238,6 +2261,9 @@ static void getTargetFeatures(const ToolChain &TC, const llvm::Triple &Triple,
case llvm::Triple::x86_64:
getX86TargetFeatures(D, Triple, Args, Features);
break;
+ case llvm::Triple::hexagon:
+ getHexagonTargetFeatures(Args, Features);
+ break;
case llvm::Triple::wasm32:
case llvm::Triple::wasm64:
getWebAssemblyTargetFeatures(Args, Features);
@@ -6049,7 +6075,9 @@ void gcc::Linker::RenderExtraToolArgs(const JobAction &JA,
// Hexagon tools start.
void hexagon::Assembler::RenderExtraToolArgs(const JobAction &JA,
- ArgStringList &CmdArgs) const {}
+ ArgStringList &CmdArgs) const {
+}
+
void hexagon::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
@@ -6057,15 +6085,21 @@ void hexagon::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
const char *LinkingOutput) const {
claimNoWarnArgs(Args);
- const Driver &D = getToolChain().getDriver();
+ auto &HTC = static_cast<const toolchains::HexagonToolChain&>(getToolChain());
+ const Driver &D = HTC.getDriver();
ArgStringList CmdArgs;
- std::string MarchString = "-march=";
- MarchString += toolchains::HexagonToolChain::GetTargetCPU(Args);
- CmdArgs.push_back(Args.MakeArgString(MarchString));
+ std::string MArchString = "-march=hexagon";
+ CmdArgs.push_back(Args.MakeArgString(MArchString));
RenderExtraToolArgs(JA, CmdArgs);
+ std::string AsName = "hexagon-llvm-mc";
+ std::string MCpuString = "-mcpu=hexagon" +
+ toolchains::HexagonToolChain::GetTargetCPUVersion(Args).str();
+ CmdArgs.push_back("-filetype=obj");
+ CmdArgs.push_back(Args.MakeArgString(MCpuString));
+
if (Output.isFilename()) {
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
@@ -6074,8 +6108,10 @@ void hexagon::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-fsyntax-only");
}
- if (const char *v = toolchains::HexagonToolChain::GetSmallDataThreshold(Args))
- CmdArgs.push_back(Args.MakeArgString(std::string("-G") + v));
+ if (auto G = toolchains::HexagonToolChain::getSmallDataThreshold(Args)) {
+ std::string N = llvm::utostr(G.getValue());
+ CmdArgs.push_back(Args.MakeArgString(std::string("-gpsize=") + N));
+ }
Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
@@ -6091,13 +6127,13 @@ void hexagon::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
// Don't try to pass LLVM or AST inputs to a generic gcc.
if (types::isLLVMIR(II.getType()))
D.Diag(clang::diag::err_drv_no_linker_llvm_support)
- << getToolChain().getTripleString();
+ << HTC.getTripleString();
else if (II.getType() == types::TY_AST)
D.Diag(clang::diag::err_drv_no_ast_support)
- << getToolChain().getTripleString();
+ << HTC.getTripleString();
else if (II.getType() == types::TY_ModuleFile)
D.Diag(diag::err_drv_no_module_support)
- << getToolChain().getTripleString();
+ << HTC.getTripleString();
if (II.isFilename())
CmdArgs.push_back(II.getFilename());
@@ -6107,41 +6143,38 @@ void hexagon::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
II.getInputArg().render(Args, CmdArgs);
}
- const char *GCCName = "hexagon-as";
- const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath(GCCName));
+ auto *Exec = Args.MakeArgString(HTC.GetProgramPath(AsName.c_str()));
C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
}
void hexagon::Linker::RenderExtraToolArgs(const JobAction &JA,
ArgStringList &CmdArgs) const {
- // The types are (hopefully) good enough.
}
static void
constructHexagonLinkArgs(Compilation &C, const JobAction &JA,
- const toolchains::HexagonToolChain &ToolChain,
+ const toolchains::HexagonToolChain &HTC,
const InputInfo &Output, const InputInfoList &Inputs,
const ArgList &Args, ArgStringList &CmdArgs,
const char *LinkingOutput) {
- const Driver &D = ToolChain.getDriver();
+ const Driver &D = HTC.getDriver();
//----------------------------------------------------------------------------
//
//----------------------------------------------------------------------------
- bool hasStaticArg = Args.hasArg(options::OPT_static);
- bool buildingLib = Args.hasArg(options::OPT_shared);
- bool buildPIE = Args.hasArg(options::OPT_pie);
- bool incStdLib = !Args.hasArg(options::OPT_nostdlib);
- bool incStartFiles = !Args.hasArg(options::OPT_nostartfiles);
- bool incDefLibs = !Args.hasArg(options::OPT_nodefaultlibs);
- bool useG0 = false;
- bool useShared = buildingLib && !hasStaticArg;
+ bool IsStatic = Args.hasArg(options::OPT_static);
+ bool IsShared = Args.hasArg(options::OPT_shared);
+ bool IsPIE = Args.hasArg(options::OPT_pie);
+ bool IncStdLib = !Args.hasArg(options::OPT_nostdlib);
+ bool IncStartFiles = !Args.hasArg(options::OPT_nostartfiles);
+ bool IncDefLibs = !Args.hasArg(options::OPT_nodefaultlibs);
+ bool UseG0 = false;
+ bool UseShared = IsShared && !IsStatic;
//----------------------------------------------------------------------------
// Silence warnings for various options
//----------------------------------------------------------------------------
-
Args.ClaimAllArgs(options::OPT_g_Group);
Args.ClaimAllArgs(options::OPT_emit_llvm);
Args.ClaimAllArgs(options::OPT_w); // Other warning options are already
@@ -6151,28 +6184,37 @@ constructHexagonLinkArgs(Compilation &C, const JobAction &JA,
//----------------------------------------------------------------------------
//
//----------------------------------------------------------------------------
- for (const auto &Opt : ToolChain.ExtraOpts)
+ if (Args.hasArg(options::OPT_s))
+ CmdArgs.push_back("-s");
+
+ if (Args.hasArg(options::OPT_r))
+ CmdArgs.push_back("-r");
+
+ for (const auto &Opt : HTC.ExtraOpts)
CmdArgs.push_back(Opt.c_str());
- std::string MarchString = toolchains::HexagonToolChain::GetTargetCPU(Args);
- CmdArgs.push_back(Args.MakeArgString("-m" + MarchString));
+ CmdArgs.push_back("-march=hexagon");
+ std::string CpuVer =
+ toolchains::HexagonToolChain::GetTargetCPUVersion(Args).str();
+ std::string MCpuString = "-mcpu=hexagon" + CpuVer;
+ CmdArgs.push_back(Args.MakeArgString(MCpuString));
- if (buildingLib) {
+ if (IsShared) {
CmdArgs.push_back("-shared");
- CmdArgs.push_back("-call_shared"); // should be the default, but doing as
- // hexagon-gcc does
+ // The following should be the default, but doing as hexagon-gcc does.
+ CmdArgs.push_back("-call_shared");
}
- if (hasStaticArg)
+ if (IsStatic)
CmdArgs.push_back("-static");
- if (buildPIE && !buildingLib)
+ if (IsPIE && !IsShared)
CmdArgs.push_back("-pie");
- if (const char *v =
- toolchains::HexagonToolChain::GetSmallDataThreshold(Args)) {
- CmdArgs.push_back(Args.MakeArgString(std::string("-G") + v));
- useG0 = toolchains::HexagonToolChain::UsesG0(v);
+ if (auto G = toolchains::HexagonToolChain::getSmallDataThreshold(Args)) {
+ std::string N = llvm::utostr(G.getValue());
+ CmdArgs.push_back(Args.MakeArgString(std::string("-G") + N));
+ UseG0 = G.getValue() == 0;
}
//----------------------------------------------------------------------------
@@ -6181,49 +6223,62 @@ constructHexagonLinkArgs(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
- const std::string MarchSuffix = "/" + MarchString;
- const std::string G0Suffix = "/G0";
- const std::string MarchG0Suffix = MarchSuffix + G0Suffix;
- const std::string RootDir = ToolChain.GetGnuDir(D.InstalledDir, Args) + "/";
- const std::string StartFilesDir =
- RootDir + "hexagon/lib" + (useG0 ? MarchG0Suffix : MarchSuffix);
-
//----------------------------------------------------------------------------
// moslib
//----------------------------------------------------------------------------
- std::vector<std::string> oslibs;
- bool hasStandalone = false;
+ std::vector<std::string> OsLibs;
+ bool HasStandalone = false;
for (const Arg *A : Args.filtered(options::OPT_moslib_EQ)) {
A->claim();
- oslibs.emplace_back(A->getValue());
- hasStandalone = hasStandalone || (oslibs.back() == "standalone");
+ OsLibs.emplace_back(A->getValue());
+ HasStandalone = HasStandalone || (OsLibs.back() == "standalone");
}
- if (oslibs.empty()) {
- oslibs.push_back("standalone");
- hasStandalone = true;
+ if (OsLibs.empty()) {
+ OsLibs.push_back("standalone");
+ HasStandalone = true;
}
//----------------------------------------------------------------------------
// Start Files
//----------------------------------------------------------------------------
- if (incStdLib && incStartFiles) {
-
- if (!buildingLib) {
- if (hasStandalone) {
- CmdArgs.push_back(
- Args.MakeArgString(StartFilesDir + "/crt0_standalone.o"));
+ const std::string MCpuSuffix = "/" + CpuVer;
+ const std::string MCpuG0Suffix = MCpuSuffix + "/G0";
+ const std::string RootDir =
+ HTC.getHexagonTargetDir(D.InstalledDir, D.PrefixDirs) + "/";
+ const std::string StartSubDir =
+ "hexagon/lib" + (UseG0 ? MCpuG0Suffix : MCpuSuffix);
+
+ auto Find = [&HTC] (const std::string &RootDir, const std::string &SubDir,
+ const char *Name) -> std::string {
+ std::string RelName = SubDir + Name;
+ std::string P = HTC.GetFilePath(RelName.c_str());
+ if (llvm::sys::fs::exists(P))
+ return P;
+ return RootDir + RelName;
+ };
+
+ if (IncStdLib && IncStartFiles) {
+ if (!IsShared) {
+ if (HasStandalone) {
+ std::string Crt0SA = Find(RootDir, StartSubDir, "/crt0_standalone.o");
+ CmdArgs.push_back(Args.MakeArgString(Crt0SA));
}
- CmdArgs.push_back(Args.MakeArgString(StartFilesDir + "/crt0.o"));
+ std::string Crt0 = Find(RootDir, StartSubDir, "/crt0.o");
+ CmdArgs.push_back(Args.MakeArgString(Crt0));
}
- std::string initObj = useShared ? "/initS.o" : "/init.o";
- CmdArgs.push_back(Args.MakeArgString(StartFilesDir + initObj));
+ std::string Init = UseShared
+ ? Find(RootDir, StartSubDir + "/pic", "/initS.o")
+ : Find(RootDir, StartSubDir, "/init.o");
+ CmdArgs.push_back(Args.MakeArgString(Init));
}
//----------------------------------------------------------------------------
// Library Search Paths
//----------------------------------------------------------------------------
- ToolChain.AddFilePathLibArgs(Args, CmdArgs);
+ const ToolChain::path_list &LibPaths = HTC.getFilePaths();
+ for (const auto &LibPath : LibPaths)
+ CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath));
//----------------------------------------------------------------------------
//
@@ -6232,21 +6287,21 @@ constructHexagonLinkArgs(Compilation &C, const JobAction &JA,
{options::OPT_T_Group, options::OPT_e, options::OPT_s,
options::OPT_t, options::OPT_u_Group});
- AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
+ AddLinkerInputs(HTC, Inputs, Args, CmdArgs);
//----------------------------------------------------------------------------
// Libraries
//----------------------------------------------------------------------------
- if (incStdLib && incDefLibs) {
+ if (IncStdLib && IncDefLibs) {
if (D.CCCIsCXX()) {
- ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
+ HTC.AddCXXStdlibLibArgs(Args, CmdArgs);
CmdArgs.push_back("-lm");
}
CmdArgs.push_back("--start-group");
- if (!buildingLib) {
- for (const std::string &Lib : oslibs)
+ if (!IsShared) {
+ for (const std::string &Lib : OsLibs)
CmdArgs.push_back(Args.MakeArgString("-l" + Lib));
CmdArgs.push_back("-lc");
}
@@ -6258,9 +6313,11 @@ constructHexagonLinkArgs(Compilation &C, const JobAction &JA,
//----------------------------------------------------------------------------
// End files
//----------------------------------------------------------------------------
- if (incStdLib && incStartFiles) {
- std::string finiObj = useShared ? "/finiS.o" : "/fini.o";
- CmdArgs.push_back(Args.MakeArgString(StartFilesDir + finiObj));
+ if (IncStdLib && IncStartFiles) {
+ std::string Fini = UseShared
+ ? Find(RootDir, StartSubDir + "/pic", "/finiS.o")
+ : Find(RootDir, StartSubDir, "/fini.o");
+ CmdArgs.push_back(Args.MakeArgString(Fini));
}
}
@@ -6269,15 +6326,13 @@ void hexagon::Linker::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) const {
-
- const toolchains::HexagonToolChain &ToolChain =
- static_cast<const toolchains::HexagonToolChain &>(getToolChain());
+ auto &HTC = static_cast<const toolchains::HexagonToolChain&>(getToolChain());
ArgStringList CmdArgs;
- constructHexagonLinkArgs(C, JA, ToolChain, Output, Inputs, Args, CmdArgs,
+ constructHexagonLinkArgs(C, JA, HTC, Output, Inputs, Args, CmdArgs,
LinkingOutput);
- std::string Linker = ToolChain.GetProgramPath("hexagon-ld");
+ std::string Linker = HTC.GetProgramPath("hexagon-link");
C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Linker),
CmdArgs, Inputs));
}
OpenPOWER on IntegriCloud