Skip to content

Commit

Permalink
[VE] Clang toolchain for VE
Browse files Browse the repository at this point in the history
Summary:
This patch enables compilation of C code for the VE target with Clang.

Differential Revision: https://reviews.llvm.org/D79411
  • Loading branch information
kaz7 authored and simoll committed Jun 24, 2020
1 parent 25ac19d commit 96d4ccf
Show file tree
Hide file tree
Showing 18 changed files with 574 additions and 2 deletions.
5 changes: 5 additions & 0 deletions clang/include/clang/Basic/TargetBuiltins.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Basic/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Basic/Targets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down
39 changes: 39 additions & 0 deletions clang/lib/Basic/Targets/VE.cpp
Original file line number Diff line number Diff line change
@@ -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 changes: 170 additions & 0 deletions clang/lib/Basic/Targets/VE.h
Original file line number Diff line number Diff line change
@@ -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
52 changes: 52 additions & 0 deletions clang/lib/CodeGen/TargetInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -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));
}
}

Expand Down
2 changes: 2 additions & 0 deletions clang/lib/Driver/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
7 changes: 7 additions & 0 deletions clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down
26 changes: 26 additions & 0 deletions clang/lib/Driver/ToolChains/Arch/VE.cpp
Original file line number Diff line number Diff line change
@@ -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) {}
Loading

0 comments on commit 96d4ccf

Please sign in to comment.