diff --git a/clang/include/clang/Basic/TargetBuiltins.h b/clang/include/clang/Basic/TargetBuiltins.h --- a/clang/include/clang/Basic/TargetBuiltins.h +++ b/clang/include/clang/Basic/TargetBuiltins.h @@ -119,6 +119,11 @@ }; } + /// 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 --- a/clang/lib/Basic/CMakeLists.txt +++ b/clang/lib/Basic/CMakeLists.txt @@ -84,6 +84,7 @@ 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 --- 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 @@ return new LinuxTargetInfo(Triple, Opts); case llvm::Triple::renderscript64: return new LinuxTargetInfo(Triple, Opts); + + case llvm::Triple::ve: + return new LinuxTargetInfo(Triple, Opts); } } } // namespace targets diff --git a/clang/lib/Basic/Targets/VE.h b/clang/lib/Basic/Targets/VE.h new file mode 100644 --- /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 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 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 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/Basic/Targets/VE.cpp b/clang/lib/Basic/Targets/VE.cpp new file mode 100644 --- /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 VETargetInfo::getTargetBuiltins() const { + return ArrayRef(); +} diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -10549,6 +10549,56 @@ } // 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(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 @@ 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 --- a/clang/lib/Driver/CMakeLists.txt +++ b/clang/lib/Driver/CMakeLists.txt @@ -31,6 +31,7 @@ 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 @@ 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 --- 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 @@ Target.getArch() == llvm::Triple::ppc64le) TC = std::make_unique(*this, Target, Args); + else if (Target.getArch() == llvm::Triple::ve) + TC = std::make_unique(*this, Target, Args); + else TC = std::make_unique(*this, Target, Args); break; @@ -4999,6 +5003,9 @@ case llvm::Triple::riscv64: TC = std::make_unique(*this, Target, Args); break; + case llvm::Triple::ve: + TC = std::make_unique(*this, Target, Args); + break; default: if (Target.getVendor() == llvm::Triple::Myriad) TC = std::make_unique(*this, Target, diff --git a/clang/lib/Driver/ToolChains/Arch/VE.h b/clang/lib/Driver/ToolChains/Arch/VE.h new file mode 100644 --- /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 +#include + +namespace clang { +namespace driver { +namespace tools { +namespace ve { + +void getVETargetFeatures(const Driver &D, const llvm::opt::ArgList &Args, + std::vector &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/Arch/VE.cpp b/clang/lib/Driver/ToolChains/Arch/VE.cpp new file mode 100644 --- /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 &Features) {} diff --git a/clang/lib/Driver/ToolChains/Clang.h b/clang/lib/Driver/ToolChains/Clang.h --- a/clang/lib/Driver/ToolChains/Clang.h +++ b/clang/lib/Driver/ToolChains/Clang.h @@ -73,6 +73,8 @@ 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/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp --- 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 @@ 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 @@ case llvm::Triple::wasm64: AddWebAssemblyTargetArgs(Args, CmdArgs); break; + + case llvm::Triple::ve: + AddVETargetArgs(Args, CmdArgs); + break; } } @@ -2160,6 +2168,12 @@ } } +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/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp --- 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::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 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -305,6 +305,8 @@ 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 @@ 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 @@ 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 @@ llvm::Reloc::Model RelocationModel; unsigned PICLevel; bool IsPIE; + const char *DefaultAssembler = "as"; std::tie(RelocationModel, PICLevel, IsPIE) = ParsePICArgs(getToolChain(), Args); @@ -903,6 +912,8 @@ 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 @@ 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(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 --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -541,6 +541,8 @@ 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.h b/clang/lib/Driver/ToolChains/VE.h new file mode 100644 --- /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/lib/Driver/ToolChains/VE.cpp b/clang/lib/Driver/ToolChains/VE.cpp new file mode 100644 --- /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 // ::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 Dirs; + const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'}; + StringRef(cl_include_dir).split(Dirs, StringRef(EnvPathSeparatorStr)); + ArrayRef 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/test/CodeGen/ve-abi.c b/clang/test/CodeGen/ve-abi.c new file mode 100644 --- /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); +}