Reapply "Frontend support for Nios2 target"

Summary:
- Implements TargetInfo class for Nios2 target.
- Enables handling of -march and -mcpu options for Nios2 target.
- Definition of Nios2 builtin functions.

Reviewed By: craig.topper

Differential Revision: https://reviews.llvm.org/D33356

Author: belickim <mateusz.belicki@intel.com>
llvm-svn: 305066
This commit is contained in:
Nikolai Bozhenov 2017-06-09 10:56:18 +00:00
parent 28285576cb
commit b2de17c734
5 changed files with 270 additions and 0 deletions

View File

@ -0,0 +1,70 @@
//===-- BuiltinsNios2.def - Nios2 Builtin function database --------*- C++ -*-==//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the Nios2-specific builtin function database. Users of
// this file must define the BUILTIN macro to make use of this information.
//
//===----------------------------------------------------------------------===//
// The format of this database matches clang/Basic/Builtins.def.
#if defined(BUILTIN) && !defined(TARGET_BUILTIN)
# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS)
#endif
// Nios2 R1 builtins:
//int __builtin_ldbio(volatile const void *);
BUILTIN(__builtin_ldbio, "ivDC*", "")
//int __builtin_ldbuio(volatile const void *);
BUILTIN(__builtin_ldbuio, "ivDC*", "")
//int __builtin_ldhio(volatile const void *);
BUILTIN(__builtin_ldhio, "ivDC*", "")
//int __builtin_ldhuio(volatile const void *);
BUILTIN(__builtin_ldhuio, "ivDC*", "")
//int __builtin_ldwio(volatile const void *);
BUILTIN(__builtin_ldwio, "ivDC*", "")
//int __builtin_ldwuio(int);
BUILTIN(__builtin_ldwuio, "ii", "")
// int __builtin_rdctl(int);
BUILTIN(__builtin_rdctl, "iIi", "")
// void __builtin_wrctl(int, int);
BUILTIN(__builtin_wrctl, "vIii", "")
// int __builtin_rdprs(int, int);
BUILTIN(__builtin_rdprs, "iii", "")
//void __builtin_stbio(volatile void *, int);
BUILTIN(__builtin_stbio, "vvD*i", "")
//void __builtin_sthio(volatile void *, int);
BUILTIN(__builtin_sthio, "vvD*i", "")
//void __builtin_stwio(volatile void *, int);
BUILTIN(__builtin_stwio, "vvD*i", "")
//void __builtin_sync(void);
BUILTIN(__builtin_sync, "v", "")
// void __builtin_flushd(volatile void *);
BUILTIN(__builtin_flushd, "vvD*", "")
// void __builtin_flushda(volatile void *);
BUILTIN(__builtin_flushda, "vvD*", "")
// Nios2 R2 builtins:
// int __builtin_wrpie(int);
TARGET_BUILTIN(__builtin_wrpie, "ii", "", "nios2r2mandatory")
// void __builtin_eni(int);
TARGET_BUILTIN(__builtin_eni, "vi", "", "nios2r2mandatory")
// int __builtin_ldex(volatile const void *);
TARGET_BUILTIN(__builtin_ldex, "ivDC*", "", "nios2r2mandatory")
// int __builtin_stex(volatile void *, int);
TARGET_BUILTIN(__builtin_stex, "ivD*i", "", "nios2r2mandatory")
// int __builtin_ldsex(volatile const void *);
TARGET_BUILTIN(__builtin_ldsex, "ivDC*", "", "nios2r2mpx")
// int __builtin_stsex(volatile void *, int);
TARGET_BUILTIN(__builtin_stsex, "ivDC*i", "", "nios2r2mpx")
#undef BUILTIN
#undef TARGET_BUILTIN

View File

@ -150,6 +150,16 @@ namespace clang {
};
}
/// \brief Nios2 builtins
namespace Nios2 {
enum {
LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
#include "clang/Basic/BuiltinsNios2.def"
LastTSBuiltin
};
}
/// \brief MIPS builtins
namespace Mips {
enum {

View File

@ -7702,6 +7702,148 @@ public:
}
};
class Nios2TargetInfo : public TargetInfo {
void setDataLayout() {
if (BigEndian)
resetDataLayout("E-p:32:32:32-i8:8:32-i16:16:32-n32");
else
resetDataLayout("e-p:32:32:32-i8:8:32-i16:16:32-n32");
}
static const Builtin::Info BuiltinInfo[];
std::string CPU;
std::string ABI;
public:
Nios2TargetInfo(const llvm::Triple &triple, const TargetOptions &opts)
: TargetInfo(triple), CPU(opts.CPU), ABI(opts.ABI) {
SizeType = UnsignedInt;
PtrDiffType = SignedInt;
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32;
setDataLayout();
}
StringRef getABI() const override { return ABI; }
bool setABI(const std::string &Name) override {
if (Name == "o32" || Name == "eabi") {
ABI = Name;
return true;
}
return false;
}
bool setCPU(const std::string &Name) override {
if (Name == "nios2r1" || Name == "nios2r2") {
CPU = Name;
return true;
}
return false;
}
void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override {
DefineStd(Builder, "nios2", Opts);
DefineStd(Builder, "NIOS2", Opts);
Builder.defineMacro("__nios2");
Builder.defineMacro("__NIOS2");
Builder.defineMacro("__nios2__");
Builder.defineMacro("__NIOS2__");
}
ArrayRef<Builtin::Info> getTargetBuiltins() const override {
return llvm::makeArrayRef(BuiltinInfo, clang::Nios2::LastTSBuiltin -
Builtin::FirstTSBuiltin);
}
bool isFeatureSupportedByCPU(StringRef Feature, StringRef CPU) const {
const bool isR2 = CPU == "nios2r2";
return llvm::StringSwitch<bool>(Feature)
.Case("nios2r2mandatory", isR2)
.Case("nios2r2bmx", isR2)
.Case("nios2r2mpx", isR2)
.Case("nios2r2cdx", isR2)
.Default(false);
}
bool initFeatureMap(llvm::StringMap<bool> &Features,
DiagnosticsEngine &Diags, StringRef CPU,
const std::vector<std::string> &FeatureVec) const override {
static const char *allFeatures[] = {
"nios2r2mandatory", "nios2r2bmx", "nios2r2mpx", "nios2r2cdx"
};
for (const char *feature : allFeatures) {
Features[feature] = isFeatureSupportedByCPU(feature, CPU);
}
return true;
}
bool hasFeature(StringRef Feature) const override {
return isFeatureSupportedByCPU(Feature, CPU);
}
BuiltinVaListKind getBuiltinVaListKind() const override {
return TargetInfo::VoidPtrBuiltinVaList;
}
ArrayRef<const char *> getGCCRegNames() const override {
static const char *const GCCRegNames[] = {
// CPU register names
// Must match second column of GCCRegAliases
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
"r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20",
"r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30",
"r31",
// Floating point register names
"ctl0", "ctl1", "ctl2", "ctl3", "ctl4", "ctl5", "ctl6", "ctl7", "ctl8",
"ctl9", "ctl10", "ctl11", "ctl12", "ctl13", "ctl14", "ctl15"
};
return llvm::makeArrayRef(GCCRegNames);
}
bool validateAsmConstraint(const char *&Name,
TargetInfo::ConstraintInfo &Info) const override {
switch (*Name) {
default:
return false;
case 'r': // CPU registers.
case 'd': // Equivalent to "r" unless generating MIPS16 code.
case 'y': // Equivalent to "r", backwards compatibility only.
case 'f': // floating-point registers.
case 'c': // $25 for indirect jumps
case 'l': // lo register
case 'x': // hilo register pair
Info.setAllowsRegister();
return true;
}
}
const char *getClobbers() const override { return ""; }
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
static const TargetInfo::GCCRegAlias aliases[] = {
{{"zero"}, "r0"}, {{"at"}, "r1"}, {{"et"}, "r24"},
{{"bt"}, "r25"}, {{"gp"}, "r26"}, {{"sp"}, "r27"},
{{"fp"}, "r28"}, {{"ea"}, "r29"}, {{"ba"}, "r30"},
{{"ra"}, "r31"}, {{"status"}, "ctl0"}, {{"estatus"}, "ctl1"},
{{"bstatus"}, "ctl2"}, {{"ienable"}, "ctl3"}, {{"ipending"}, "ctl4"},
{{"cpuid"}, "ctl5"}, {{"exception"}, "ctl7"}, {{"pteaddr"}, "ctl8"},
{{"tlbacc"}, "ctl9"}, {{"tlbmisc"}, "ctl10"}, {{"badaddr"}, "ctl12"},
{{"config"}, "ctl13"}, {{"mpubase"}, "ctl14"}, {{"mpuacc"}, "ctl15"},
};
return llvm::makeArrayRef(aliases);
}
};
const Builtin::Info Nios2TargetInfo::BuiltinInfo[] = {
#define BUILTIN(ID, TYPE, ATTRS) \
{#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
{#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE},
#include "clang/Basic/BuiltinsNios2.def"
};
class MipsTargetInfo : public TargetInfo {
void setDataLayout() {
StringRef Layout;
@ -9328,6 +9470,9 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple,
case llvm::Triple::msp430:
return new MSP430TargetInfo(Triple, Opts);
case llvm::Triple::nios2:
return new LinuxTargetInfo<Nios2TargetInfo>(Triple, Opts);
case llvm::Triple::mips:
switch (os) {
case llvm::Triple::Linux:

View File

@ -215,6 +215,21 @@ static std::string getR600TargetGPU(const ArgList &Args) {
return "";
}
static std::string getNios2TargetCPU(const ArgList &Args) {
Arg *A = Args.getLastArg(options::OPT_mcpu_EQ);
if (!A)
A = Args.getLastArg(options::OPT_march_EQ);
if (!A)
return "";
const char *name = A->getValue();
return llvm::StringSwitch<const char *>(name)
.Case("r1", "nios2r1")
.Case("r2", "nios2r2")
.Default(name);
}
static std::string getLanaiTargetCPU(const ArgList &Args) {
if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
return A->getValue();
@ -267,6 +282,10 @@ std::string tools::getCPUName(const ArgList &Args, const llvm::Triple &T,
return A->getValue();
return "";
case llvm::Triple::nios2: {
return getNios2TargetCPU(Args);
}
case llvm::Triple::mips:
case llvm::Triple::mipsel:
case llvm::Triple::mips64:

View File

@ -0,0 +1,26 @@
// RUN: %clang -target nios2--- %s -### -o %t.o 2>&1 \
// RUN: | FileCheck %s
// RUN: %clang -target nios2--- -mcpu=r1 %s -### -o %t.o 2>&1 \
// RUN: | FileCheck -check-prefix=CHECK-R1 %s
// RUN: %clang -target nios2--- -mcpu=nios2r1 %s -### -o %t.o 2>&1 \
// RUN: | FileCheck -check-prefix=CHECK-R1 %s
// RUN: %clang -target nios2--- -march=r1 %s -### -o %t.o 2>&1 \
// RUN: | FileCheck -check-prefix=CHECK-R1 %s
// RUN: %clang -target nios2--- -march=nios2r1 %s -### -o %t.o 2>&1 \
// RUN: | FileCheck -check-prefix=CHECK-R1 %s
// RUN: %clang -target nios2--- -mcpu=r2 %s -### -o %t.o 2>&1 \
// RUN: | FileCheck -check-prefix=CHECK-R2 %s
// RUN: %clang -target nios2--- -mcpu=nios2r2 %s -### -o %t.o 2>&1 \
// RUN: | FileCheck -check-prefix=CHECK-R2 %s
// RUN: %clang -target nios2--- -march=r2 %s -### -o %t.o 2>&1 \
// RUN: | FileCheck -check-prefix=CHECK-R2 %s
// RUN: %clang -target nios2--- -march=nios2r2 %s -### -o %t.o 2>&1 \
// RUN: | FileCheck -check-prefix=CHECK-R2 %s
// CHECK: "-triple" "nios2---"
// CHECK-R1: "-triple" "nios2---"
// CHECK-R1: "-target-cpu" "nios2r1"
// CHECK-R2: "-triple" "nios2---"
// CHECK-R2: "-target-cpu" "nios2r2"