[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
This commit is contained in:
Kazushi (Jam) Marukawa 2020-06-24 10:11:59 +02:00 committed by Simon Moll
parent 25ac19de4b
commit 96d4ccf00c
18 changed files with 574 additions and 2 deletions

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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>();
}

View File

@ -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

View File

@ -10548,6 +10548,56 @@ public:
};
} // 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));
}
}

View File

@ -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

View File

@ -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,

View File

@ -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) {}

View File

@ -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

View File

@ -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 {

View File

@ -73,6 +73,8 @@ private:
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 };

View File

@ -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();

View File

@ -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

View File

@ -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 &&

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}