mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-28 02:37:37 +00:00
[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:
parent
25ac19de4b
commit
96d4ccf00c
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
39
clang/lib/Basic/Targets/VE.cpp
Normal file
39
clang/lib/Basic/Targets/VE.cpp
Normal 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>();
|
||||
}
|
170
clang/lib/Basic/Targets/VE.h
Normal file
170
clang/lib/Basic/Targets/VE.h
Normal 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
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
26
clang/lib/Driver/ToolChains/Arch/VE.cpp
Normal file
26
clang/lib/Driver/ToolChains/Arch/VE.cpp
Normal 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) {}
|
33
clang/lib/Driver/ToolChains/Arch/VE.h
Normal file
33
clang/lib/Driver/ToolChains/Arch/VE.h
Normal 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
|
@ -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 {
|
||||
|
@ -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 };
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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 &&
|
||||
|
119
clang/lib/Driver/ToolChains/VE.cpp
Normal file
119
clang/lib/Driver/ToolChains/VE.cpp
Normal 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;
|
||||
}
|
66
clang/lib/Driver/ToolChains/VE.h
Normal file
66
clang/lib/Driver/ToolChains/VE.h
Normal 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
|
14
clang/test/CodeGen/ve-abi.c
Normal file
14
clang/test/CodeGen/ve-abi.c
Normal 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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user