[clang] 96d4ccf - [VE] Clang toolchain for VE
Simon Moll via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 24 01:12:54 PDT 2020
Author: Kazushi (Jam) Marukawa
Date: 2020-06-24T10:12:09+02:00
New Revision: 96d4ccf00c8f746aebb549288fac33dcbb15bc4b
URL: https://github.com/llvm/llvm-project/commit/96d4ccf00c8f746aebb549288fac33dcbb15bc4b
DIFF: https://github.com/llvm/llvm-project/commit/96d4ccf00c8f746aebb549288fac33dcbb15bc4b.diff
LOG: [VE] Clang toolchain for VE
Summary:
This patch enables compilation of C code for the VE target with Clang.
Differential Revision: https://reviews.llvm.org/D79411
Added:
clang/lib/Basic/Targets/VE.cpp
clang/lib/Basic/Targets/VE.h
clang/lib/Driver/ToolChains/Arch/VE.cpp
clang/lib/Driver/ToolChains/Arch/VE.h
clang/lib/Driver/ToolChains/VE.cpp
clang/lib/Driver/ToolChains/VE.h
clang/test/CodeGen/ve-abi.c
Modified:
clang/include/clang/Basic/TargetBuiltins.h
clang/lib/Basic/CMakeLists.txt
clang/lib/Basic/Targets.cpp
clang/lib/CodeGen/TargetInfo.cpp
clang/lib/Driver/CMakeLists.txt
clang/lib/Driver/Driver.cpp
clang/lib/Driver/ToolChains/Clang.cpp
clang/lib/Driver/ToolChains/Clang.h
clang/lib/Driver/ToolChains/CommonArgs.cpp
clang/lib/Driver/ToolChains/Gnu.cpp
clang/lib/Driver/ToolChains/Linux.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/TargetBuiltins.h b/clang/include/clang/Basic/TargetBuiltins.h
index eba055c302a7..b472547012f0 100644
--- a/clang/include/clang/Basic/TargetBuiltins.h
+++ b/clang/include/clang/Basic/TargetBuiltins.h
@@ -119,6 +119,11 @@ namespace clang {
};
}
+ /// VE builtins
+ namespace VE {
+ enum { LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, LastTSBuiltin };
+ }
+
/// Flags to identify the types for overloaded Neon builtins.
///
/// These must be kept in sync with the flags in utils/TableGen/NeonEmitter.h.
diff --git a/clang/lib/Basic/CMakeLists.txt b/clang/lib/Basic/CMakeLists.txt
index cd310ec811b4..1b55d8417377 100644
--- a/clang/lib/Basic/CMakeLists.txt
+++ b/clang/lib/Basic/CMakeLists.txt
@@ -84,6 +84,7 @@ add_clang_library(clangBasic
Targets/Sparc.cpp
Targets/SystemZ.cpp
Targets/TCE.cpp
+ Targets/VE.cpp
Targets/WebAssembly.cpp
Targets/X86.cpp
Targets/XCore.cpp
diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp
index 69133ca31fec..6bbcafa27dfe 100644
--- a/clang/lib/Basic/Targets.cpp
+++ b/clang/lib/Basic/Targets.cpp
@@ -33,6 +33,7 @@
#include "Targets/Sparc.h"
#include "Targets/SystemZ.h"
#include "Targets/TCE.h"
+#include "Targets/VE.h"
#include "Targets/WebAssembly.h"
#include "Targets/X86.h"
#include "Targets/XCore.h"
@@ -613,6 +614,9 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple,
return new LinuxTargetInfo<RenderScript32TargetInfo>(Triple, Opts);
case llvm::Triple::renderscript64:
return new LinuxTargetInfo<RenderScript64TargetInfo>(Triple, Opts);
+
+ case llvm::Triple::ve:
+ return new LinuxTargetInfo<VETargetInfo>(Triple, Opts);
}
}
} // namespace targets
diff --git a/clang/lib/Basic/Targets/VE.cpp b/clang/lib/Basic/Targets/VE.cpp
new file mode 100644
index 000000000000..22223654e8ad
--- /dev/null
+++ b/clang/lib/Basic/Targets/VE.cpp
@@ -0,0 +1,39 @@
+//===--- VE.cpp - Implement VE target feature support ---------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements VE TargetInfo objects.
+//
+//===----------------------------------------------------------------------===//
+
+#include "VE.h"
+#include "clang/Basic/Builtins.h"
+#include "clang/Basic/MacroBuilder.h"
+#include "clang/Basic/TargetBuiltins.h"
+
+using namespace clang;
+using namespace clang::targets;
+
+void VETargetInfo::getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ Builder.defineMacro("_LP64", "1");
+ Builder.defineMacro("unix", "1");
+ Builder.defineMacro("__unix__", "1");
+ Builder.defineMacro("__linux__", "1");
+ Builder.defineMacro("__ve", "1");
+ Builder.defineMacro("__ve__", "1");
+ Builder.defineMacro("__STDC_HOSTED__", "1");
+ Builder.defineMacro("__STDC__", "1");
+ Builder.defineMacro("__NEC__", "1");
+ // FIXME: define __FAST_MATH__ 1 if -ffast-math is enabled
+ // FIXME: define __OPTIMIZE__ n if -On is enabled
+ // FIXME: define __VECTOR__ n 1 if automatic vectorization is enabled
+}
+
+ArrayRef<Builtin::Info> VETargetInfo::getTargetBuiltins() const {
+ return ArrayRef<Builtin::Info>();
+}
diff --git a/clang/lib/Basic/Targets/VE.h b/clang/lib/Basic/Targets/VE.h
new file mode 100644
index 000000000000..7e50e7daeb90
--- /dev/null
+++ b/clang/lib/Basic/Targets/VE.h
@@ -0,0 +1,170 @@
+//===--- VE.h - Declare VE target feature support ---------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares VE TargetInfo objects.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_VE_H
+#define LLVM_CLANG_LIB_BASIC_TARGETS_VE_H
+
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/TargetOptions.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/Compiler.h"
+
+namespace clang {
+namespace targets {
+
+class LLVM_LIBRARY_VISIBILITY VETargetInfo : public TargetInfo {
+ static const Builtin::Info BuiltinInfo[];
+
+public:
+ VETargetInfo(const llvm::Triple &Triple, const TargetOptions &)
+ : TargetInfo(Triple) {
+ NoAsmVariants = true;
+ LongDoubleWidth = 128;
+ LongDoubleAlign = 128;
+ LongDoubleFormat = &llvm::APFloat::IEEEquad();
+ DoubleAlign = LongLongAlign = 64;
+ SuitableAlign = 64;
+ LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
+ SizeType = UnsignedLong;
+ PtrDiffType = SignedLong;
+ IntPtrType = SignedLong;
+ IntMaxType = SignedLong;
+ Int64Type = SignedLong;
+ RegParmMax = 8;
+ MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
+
+ WCharType = UnsignedInt;
+ WIntType = UnsignedInt;
+ UseZeroLengthBitfieldAlignment = true;
+ resetDataLayout("e-m:e-i64:64-n32:64-S64");
+ }
+
+ void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const override;
+
+ bool hasSjLjLowering() const override {
+ // TODO
+ return false;
+ }
+
+ ArrayRef<Builtin::Info> getTargetBuiltins() const override;
+
+ BuiltinVaListKind getBuiltinVaListKind() const override {
+ return TargetInfo::VoidPtrBuiltinVaList;
+ }
+
+ CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
+ switch (CC) {
+ default:
+ return CCCR_Warning;
+ case CC_C:
+ return CCCR_OK;
+ }
+ }
+
+ const char *getClobbers() const override { return ""; }
+
+ ArrayRef<const char *> getGCCRegNames() const override {
+ static const char *const GCCRegNames[] = {
+ // Regular registers
+ "sx0", "sx1", "sx2", "sx3", "sx4", "sx5", "sx6", "sx7",
+ "sx8", "sx9", "sx10", "sx11", "sx12", "sx13", "sx14", "sx15",
+ "sx16", "sx17", "sx18", "sx19", "sx20", "sx21", "sx22", "sx23",
+ "sx24", "sx25", "sx26", "sx27", "sx28", "sx29", "sx30", "sx31",
+ "sx32", "sx33", "sx34", "sx35", "sx36", "sx37", "sx38", "sx39",
+ "sx40", "sx41", "sx42", "sx43", "sx44", "sx45", "sx46", "sx47",
+ "sx48", "sx49", "sx50", "sx51", "sx52", "sx53", "sx54", "sx55",
+ "sx56", "sx57", "sx58", "sx59", "sx60", "sx61", "sx62", "sx63",
+ };
+ return llvm::makeArrayRef(GCCRegNames);
+ }
+
+ ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
+ static const TargetInfo::GCCRegAlias GCCRegAliases[] = {
+ {{"s0"}, "sx0"},
+ {{"s1"}, "sx1"},
+ {{"s2"}, "sx2"},
+ {{"s3"}, "sx3"},
+ {{"s4"}, "sx4"},
+ {{"s5"}, "sx5"},
+ {{"s6"}, "sx6"},
+ {{"s7"}, "sx7"},
+ {{"s8", "sl"}, "sx8"},
+ {{"s9", "fp"}, "sx9"},
+ {{"s10", "lr"}, "sx10"},
+ {{"s11", "sp"}, "sx11"},
+ {{"s12", "outer"}, "sx12"},
+ {{"s13"}, "sx13"},
+ {{"s14", "tp"}, "sx14"},
+ {{"s15", "got"}, "sx15"},
+ {{"s16", "plt"}, "sx16"},
+ {{"s17", "info"}, "sx17"},
+ {{"s18"}, "sx18"},
+ {{"s19"}, "sx19"},
+ {{"s20"}, "sx20"},
+ {{"s21"}, "sx21"},
+ {{"s22"}, "sx22"},
+ {{"s23"}, "sx23"},
+ {{"s24"}, "sx24"},
+ {{"s25"}, "sx25"},
+ {{"s26"}, "sx26"},
+ {{"s27"}, "sx27"},
+ {{"s28"}, "sx28"},
+ {{"s29"}, "sx29"},
+ {{"s30"}, "sx30"},
+ {{"s31"}, "sx31"},
+ {{"s32"}, "sx32"},
+ {{"s33"}, "sx33"},
+ {{"s34"}, "sx34"},
+ {{"s35"}, "sx35"},
+ {{"s36"}, "sx36"},
+ {{"s37"}, "sx37"},
+ {{"s38"}, "sx38"},
+ {{"s39"}, "sx39"},
+ {{"s40"}, "sx40"},
+ {{"s41"}, "sx41"},
+ {{"s42"}, "sx42"},
+ {{"s43"}, "sx43"},
+ {{"s44"}, "sx44"},
+ {{"s45"}, "sx45"},
+ {{"s46"}, "sx46"},
+ {{"s47"}, "sx47"},
+ {{"s48"}, "sx48"},
+ {{"s49"}, "sx49"},
+ {{"s50"}, "sx50"},
+ {{"s51"}, "sx51"},
+ {{"s52"}, "sx52"},
+ {{"s53"}, "sx53"},
+ {{"s54"}, "sx54"},
+ {{"s55"}, "sx55"},
+ {{"s56"}, "sx56"},
+ {{"s57"}, "sx57"},
+ {{"s58"}, "sx58"},
+ {{"s59"}, "sx59"},
+ {{"s60"}, "sx60"},
+ {{"s61"}, "sx61"},
+ {{"s62"}, "sx62"},
+ {{"s63"}, "sx63"},
+ };
+ return llvm::makeArrayRef(GCCRegAliases);
+ }
+
+ bool validateAsmConstraint(const char *&Name,
+ TargetInfo::ConstraintInfo &Info) const override {
+ return false;
+ }
+
+ bool allowsLargerPreferedTypeAlignment() const override { return false; }
+};
+} // namespace targets
+} // namespace clang
+#endif // LLVM_CLANG_LIB_BASIC_TARGETS_VE_H
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index 9710e676e58f..d28326f9f2f8 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -10548,6 +10548,56 @@ class RISCVTargetCodeGenInfo : public TargetCodeGenInfo {
};
} // namespace
+//===----------------------------------------------------------------------===//
+// VE ABI Implementation.
+//
+namespace {
+class VEABIInfo : public DefaultABIInfo {
+public:
+ VEABIInfo(CodeGenTypes &CGT) : DefaultABIInfo(CGT) {}
+
+private:
+ ABIArgInfo classifyReturnType(QualType RetTy) const;
+ ABIArgInfo classifyArgumentType(QualType RetTy) const;
+ void computeInfo(CGFunctionInfo &FI) const override;
+};
+} // end anonymous namespace
+
+ABIArgInfo VEABIInfo::classifyReturnType(QualType Ty) const {
+ if (Ty->isAnyComplexType()) {
+ return ABIArgInfo::getDirect();
+ }
+ return DefaultABIInfo::classifyReturnType(Ty);
+}
+
+ABIArgInfo VEABIInfo::classifyArgumentType(QualType Ty) const {
+ if (Ty->isAnyComplexType()) {
+ return ABIArgInfo::getDirect();
+ }
+ return DefaultABIInfo::classifyArgumentType(Ty);
+}
+
+void VEABIInfo::computeInfo(CGFunctionInfo &FI) const {
+
+ FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
+ for (auto &Arg : FI.arguments())
+ Arg.info = classifyArgumentType(Arg.type);
+}
+
+namespace {
+class VETargetCodeGenInfo : public TargetCodeGenInfo {
+public:
+ VETargetCodeGenInfo(CodeGenTypes &CGT)
+ : TargetCodeGenInfo(std::make_unique<VEABIInfo>(CGT)) {}
+ // VE ABI requires the arguments of variadic and prototype-less functions
+ // are passed in both registers and memory.
+ bool isNoProtoCallVariadic(const CallArgList &args,
+ const FunctionNoProtoType *fnType) const override {
+ return true;
+ }
+};
+} // end anonymous namespace
+
//===----------------------------------------------------------------------===//
// Driver code
//===----------------------------------------------------------------------===//
@@ -10750,6 +10800,8 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {
case llvm::Triple::spir:
case llvm::Triple::spir64:
return SetCGInfo(new SPIRTargetCodeGenInfo(Types));
+ case llvm::Triple::ve:
+ return SetCGInfo(new VETargetCodeGenInfo(Types));
}
}
diff --git a/clang/lib/Driver/CMakeLists.txt b/clang/lib/Driver/CMakeLists.txt
index 6f25d3588ebb..b13789f8b2a8 100644
--- a/clang/lib/Driver/CMakeLists.txt
+++ b/clang/lib/Driver/CMakeLists.txt
@@ -31,6 +31,7 @@ add_clang_library(clangDriver
ToolChains/Arch/RISCV.cpp
ToolChains/Arch/Sparc.cpp
ToolChains/Arch/SystemZ.cpp
+ ToolChains/Arch/VE.cpp
ToolChains/Arch/X86.cpp
ToolChains/AIX.cpp
ToolChains/Ananas.cpp
@@ -67,6 +68,7 @@ add_clang_library(clangDriver
ToolChains/RISCVToolchain.cpp
ToolChains/Solaris.cpp
ToolChains/TCE.cpp
+ ToolChains/VE.cpp
ToolChains/WebAssembly.cpp
ToolChains/XCore.cpp
ToolChains/PPCLinux.cpp
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 0cf99377f2b5..24436ec4e8d7 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -43,6 +43,7 @@
#include "ToolChains/RISCVToolchain.h"
#include "ToolChains/Solaris.h"
#include "ToolChains/TCE.h"
+#include "ToolChains/VE.h"
#include "ToolChains/WebAssembly.h"
#include "ToolChains/XCore.h"
#include "clang/Basic/Version.h"
@@ -4907,6 +4908,9 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
Target.getArch() == llvm::Triple::ppc64le)
TC = std::make_unique<toolchains::PPCLinuxToolChain>(*this, Target,
Args);
+ else if (Target.getArch() == llvm::Triple::ve)
+ TC = std::make_unique<toolchains::VEToolChain>(*this, Target, Args);
+
else
TC = std::make_unique<toolchains::Linux>(*this, Target, Args);
break;
@@ -4999,6 +5003,9 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
case llvm::Triple::riscv64:
TC = std::make_unique<toolchains::RISCVToolChain>(*this, Target, Args);
break;
+ case llvm::Triple::ve:
+ TC = std::make_unique<toolchains::VEToolChain>(*this, Target, Args);
+ break;
default:
if (Target.getVendor() == llvm::Triple::Myriad)
TC = std::make_unique<toolchains::MyriadToolChain>(*this, Target,
diff --git a/clang/lib/Driver/ToolChains/Arch/VE.cpp b/clang/lib/Driver/ToolChains/Arch/VE.cpp
new file mode 100644
index 000000000000..fa10e4810f1c
--- /dev/null
+++ b/clang/lib/Driver/ToolChains/Arch/VE.cpp
@@ -0,0 +1,26 @@
+//===--- VE.cpp - Tools Implementations -------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "VE.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 *ve::getVEAsmModeForCPU(StringRef Name, const llvm::Triple &Triple) {
+ return "";
+}
+
+void ve::getVETargetFeatures(const Driver &D, const ArgList &Args,
+ std::vector<StringRef> &Features) {}
diff --git a/clang/lib/Driver/ToolChains/Arch/VE.h b/clang/lib/Driver/ToolChains/Arch/VE.h
new file mode 100644
index 000000000000..713e3e7d042f
--- /dev/null
+++ b/clang/lib/Driver/ToolChains/Arch/VE.h
@@ -0,0 +1,33 @@
+//===--- VE.h - VE-specific Tool Helpers ------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_VE_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_VE_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 ve {
+
+void getVETargetFeatures(const Driver &D, const llvm::opt::ArgList &Args,
+ std::vector<llvm::StringRef> &Features);
+const char *getVEAsmModeForCPU(llvm::StringRef Name,
+ const llvm::Triple &Triple);
+
+} // end namespace ve
+} // namespace tools
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ARCH_VE_H
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index aa18727671be..54c79032545c 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -15,6 +15,7 @@
#include "Arch/RISCV.h"
#include "Arch/Sparc.h"
#include "Arch/SystemZ.h"
+#include "Arch/VE.h"
#include "Arch/X86.h"
#include "CommonArgs.h"
#include "Hexagon.h"
@@ -368,6 +369,9 @@ static void getTargetFeatures(const Driver &D, const llvm::Triple &Triple,
break;
case llvm::Triple::msp430:
msp430::getMSP430TargetFeatures(D, Args, Features);
+ break;
+ case llvm::Triple::ve:
+ ve::getVETargetFeatures(D, Args, Features);
}
// Find the last of each feature.
@@ -1663,6 +1667,10 @@ void Clang::RenderTargetOptions(const llvm::Triple &EffectiveTriple,
case llvm::Triple::wasm64:
AddWebAssemblyTargetArgs(Args, CmdArgs);
break;
+
+ case llvm::Triple::ve:
+ AddVETargetArgs(Args, CmdArgs);
+ break;
}
}
@@ -2160,6 +2168,12 @@ void Clang::AddWebAssemblyTargetArgs(const ArgList &Args,
}
}
+void Clang::AddVETargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const {
+ // Floating point operations and argument passing are hard.
+ CmdArgs.push_back("-mfloat-abi");
+ CmdArgs.push_back("hard");
+}
+
void Clang::DumpCompilationDatabase(Compilation &C, StringRef Filename,
StringRef Target, const InputInfo &Output,
const InputInfo &Input, const ArgList &Args) const {
diff --git a/clang/lib/Driver/ToolChains/Clang.h b/clang/lib/Driver/ToolChains/Clang.h
index 48100c2fc6ec..180bf9f321ab 100644
--- a/clang/lib/Driver/ToolChains/Clang.h
+++ b/clang/lib/Driver/ToolChains/Clang.h
@@ -73,6 +73,8 @@ class LLVM_LIBRARY_VISIBILITY Clang : public Tool {
llvm::opt::ArgStringList &CmdArgs) const;
void AddWebAssemblyTargetArgs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const;
+ void AddVETargetArgs(const llvm::opt::ArgList &Args,
+ llvm::opt::ArgStringList &CmdArgs) const;
enum RewriteKind { RK_None, RK_Fragile, RK_NonFragile };
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 542fb67db7ef..2a9d7e30a461 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -12,6 +12,7 @@
#include "Arch/Mips.h"
#include "Arch/PPC.h"
#include "Arch/SystemZ.h"
+#include "Arch/VE.h"
#include "Arch/X86.h"
#include "HIP.h"
#include "Hexagon.h"
@@ -504,8 +505,11 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,
void tools::addArchSpecificRPath(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs) {
+ // Enable -frtlib-add-rpath by default for the case of VE.
+ const bool IsVE = TC.getTriple().isVE();
+ bool DefaultValue = IsVE;
if (!Args.hasFlag(options::OPT_frtlib_add_rpath,
- options::OPT_fno_rtlib_add_rpath, false))
+ options::OPT_fno_rtlib_add_rpath, DefaultValue))
return;
std::string CandidateRPath = TC.getArchSpecificLibPath();
diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp
index 4e577ee163df..ede84c2e3dc4 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -305,6 +305,8 @@ static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) {
if (T.getEnvironment() == llvm::Triple::GNUX32)
return "elf32_x86_64";
return "elf_x86_64";
+ case llvm::Triple::ve:
+ return "elf64ve";
default:
return nullptr;
}
@@ -396,6 +398,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
const llvm::Triple::ArchType Arch = ToolChain.getArch();
const bool isAndroid = ToolChain.getTriple().isAndroid();
const bool IsIAMCU = ToolChain.getTriple().isOSIAMCU();
+ const bool IsVE = ToolChain.getTriple().isVE();
const bool IsPIE = getPIE(Args, ToolChain);
const bool IsStaticPIE = getStaticPIE(Args, ToolChain);
const bool IsStatic = getStatic(Args);
@@ -514,6 +517,11 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
}
+ if (IsVE) {
+ CmdArgs.push_back("-z");
+ CmdArgs.push_back("max-page-size=0x4000000");
+ }
+
if (IsIAMCU)
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o")));
else if (HasCRTBeginEndFiles) {
@@ -683,6 +691,7 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C,
llvm::Reloc::Model RelocationModel;
unsigned PICLevel;
bool IsPIE;
+ const char *DefaultAssembler = "as";
std::tie(RelocationModel, PICLevel, IsPIE) =
ParsePICArgs(getToolChain(), Args);
@@ -903,6 +912,8 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C,
CmdArgs.push_back(Args.MakeArgString("-march=" + CPUName));
break;
}
+ case llvm::Triple::ve:
+ DefaultAssembler = "nas";
}
for (const Arg *A : Args.filtered(options::OPT_ffile_prefix_map_EQ,
@@ -927,7 +938,8 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C,
for (const auto &II : Inputs)
CmdArgs.push_back(II.getFilename());
- const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
+ const char *Exec =
+ Args.MakeArgString(getToolChain().GetProgramPath(DefaultAssembler));
C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
// Handle the debug info splitting at object creation time if we're
diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp
index 5e74a2b3c5ff..180350476c38 100644
--- a/clang/lib/Driver/ToolChains/Linux.cpp
+++ b/clang/lib/Driver/ToolChains/Linux.cpp
@@ -541,6 +541,8 @@ std::string Linux::getDynamicLinker(const ArgList &Args) const {
Loader = X32 ? "ld-linux-x32.so.2" : "ld-linux-x86-64.so.2";
break;
}
+ case llvm::Triple::ve:
+ return "/opt/nec/ve/lib/ld-linux-ve.so.1";
}
if (Distro == Distro::Exherbo &&
diff --git a/clang/lib/Driver/ToolChains/VE.cpp b/clang/lib/Driver/ToolChains/VE.cpp
new file mode 100644
index 000000000000..ae4e5fedf6b4
--- /dev/null
+++ b/clang/lib/Driver/ToolChains/VE.cpp
@@ -0,0 +1,119 @@
+//===--- VE.cpp - VE ToolChain Implementations ------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "VE.h"
+#include "CommonArgs.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/Options.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include <cstdlib> // ::getenv
+
+using namespace clang::driver;
+using namespace clang::driver::toolchains;
+using namespace clang;
+using namespace llvm::opt;
+
+/// VE tool chain
+VEToolChain::VEToolChain(const Driver &D, const llvm::Triple &Triple,
+ const ArgList &Args)
+ : Linux(D, Triple, Args) {
+ getProgramPaths().push_back("/opt/nec/ve/bin");
+ // ProgramPaths are found via 'PATH' environment variable.
+
+ // default file paths are:
+ // ${RESOURCEDIR}/lib/linux/ve (== getArchSpecificLibPath)
+ // /lib/../lib64
+ // /usr/lib/../lib64
+ // ${BINPATH}/../lib
+ // /lib
+ // /usr/lib
+ //
+ // These are OK for host, but no go for VE. So, defines them all
+ // from scratch here.
+ getFilePaths().clear();
+ getFilePaths().push_back(getArchSpecificLibPath());
+ getFilePaths().push_back(computeSysRoot() + "/opt/nec/ve/lib");
+}
+
+Tool *VEToolChain::buildAssembler() const {
+ return new tools::gnutools::Assembler(*this);
+}
+
+Tool *VEToolChain::buildLinker() const {
+ return new tools::gnutools::Linker(*this);
+}
+
+bool VEToolChain::isPICDefault() const { return false; }
+
+bool VEToolChain::isPIEDefault() const { return false; }
+
+bool VEToolChain::isPICDefaultForced() const { return false; }
+
+bool VEToolChain::SupportsProfiling() const { return false; }
+
+bool VEToolChain::hasBlocksRuntime() const { return false; }
+
+void VEToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
+ ArgStringList &CC1Args) const {
+ if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc))
+ return;
+
+ if (DriverArgs.hasArg(options::OPT_nobuiltininc) &&
+ DriverArgs.hasArg(options::OPT_nostdlibinc))
+ return;
+
+ if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
+ SmallString<128> P(getDriver().ResourceDir);
+ llvm::sys::path::append(P, "include");
+ addSystemInclude(DriverArgs, CC1Args, P);
+ }
+
+ if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) {
+ if (const char *cl_include_dir = getenv("NCC_C_INCLUDE_PATH")) {
+ SmallVector<StringRef, 4> Dirs;
+ const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
+ StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr));
+ ArrayRef<StringRef> DirVec(Dirs);
+ addSystemIncludes(DriverArgs, CC1Args, DirVec);
+ } else {
+ addSystemInclude(DriverArgs, CC1Args,
+ getDriver().SysRoot + "/opt/nec/ve/include");
+ }
+ }
+}
+
+void VEToolChain::addClangTargetOptions(const ArgList &DriverArgs,
+ ArgStringList &CC1Args,
+ Action::OffloadKind) const {
+ CC1Args.push_back("-nostdsysteminc");
+ bool UseInitArrayDefault = true;
+ if (!DriverArgs.hasFlag(options::OPT_fuse_init_array,
+ options::OPT_fno_use_init_array, UseInitArrayDefault))
+ CC1Args.push_back("-fno-use-init-array");
+}
+
+void VEToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
+ ArgStringList &CC1Args) const {
+ // TODO upstream VE libc++ patches
+ llvm_unreachable("The VE target has no C++ stdlib for Clang yet");
+}
+
+void VEToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
+ ArgStringList &CmdArgs) const {
+ // TODO upstream VE libc++ patches
+ llvm_unreachable("The VE target has no C++ stdlib for Clang yet");
+}
+
+llvm::ExceptionHandling
+VEToolChain::GetExceptionModel(const ArgList &Args) const {
+ // VE uses SjLj exceptions.
+ return llvm::ExceptionHandling::SjLj;
+}
diff --git a/clang/lib/Driver/ToolChains/VE.h b/clang/lib/Driver/ToolChains/VE.h
new file mode 100644
index 000000000000..59069c0a7595
--- /dev/null
+++ b/clang/lib/Driver/ToolChains/VE.h
@@ -0,0 +1,66 @@
+//===--- VE.h - VE ToolChain Implementations --------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_VE_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_VE_H
+
+#include "Linux.h"
+#include "clang/Driver/ToolChain.h"
+
+namespace clang {
+namespace driver {
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY VEToolChain : public Linux {
+public:
+ VEToolChain(const Driver &D, const llvm::Triple &Triple,
+ const llvm::opt::ArgList &Args);
+
+protected:
+ Tool *buildAssembler() const override;
+ Tool *buildLinker() const override;
+
+public:
+ bool isPICDefault() const override;
+ bool isPIEDefault() const override;
+ bool isPICDefaultForced() const override;
+ bool SupportsProfiling() const override;
+ bool hasBlocksRuntime() const override;
+ void
+ AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const override;
+ void
+ addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args,
+ Action::OffloadKind DeviceOffloadKind) const override;
+ void AddClangCXXStdlibIncludeArgs(
+ const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const override;
+ void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
+ llvm::opt::ArgStringList &CmdArgs) const override;
+
+ llvm::ExceptionHandling
+ GetExceptionModel(const llvm::opt::ArgList &Args) const override;
+
+ CXXStdlibType
+ GetCXXStdlibType(const llvm::opt::ArgList &Args) const override {
+ return ToolChain::CST_Libcxx;
+ }
+
+ RuntimeLibType GetDefaultRuntimeLibType() const override {
+ return ToolChain::RLT_CompilerRT;
+ }
+
+ const char *getDefaultLinker() const override { return "nld"; }
+};
+
+} // end namespace toolchains
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_VE_H
diff --git a/clang/test/CodeGen/ve-abi.c b/clang/test/CodeGen/ve-abi.c
new file mode 100644
index 000000000000..aa35095d5dea
--- /dev/null
+++ b/clang/test/CodeGen/ve-abi.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -triple ve-linux-gnu -emit-llvm %s -o - | FileCheck %s
+
+// CHECK-LABEL: define { float, float } @p(float %a.coerce0, float %a.coerce1, float %b.coerce0, float %b.coerce1) #0 {
+float __complex__ p(float __complex__ a, float __complex__ b) {
+}
+
+// CHECK-LABEL: define { double, double } @q(double %a.coerce0, double %a.coerce1, double %b.coerce0, double %b.coerce1) #0 {
+double __complex__ q(double __complex__ a, double __complex__ b) {
+}
+
+void func() {
+ // CHECK-LABEL: %call = call i32 (i32, i32, i32, i32, i32, i32, i32, ...) bitcast (i32 (...)* @hoge to i32 (i32, i32, i32, i32, i32, i32, i32, ...)*)(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7)
+ hoge(1, 2, 3, 4, 5, 6, 7);
+}
More information about the cfe-commits
mailing list