Skip to content

Commit

Permalink
Frontend support for Nios2 target.
Browse files Browse the repository at this point in the history
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: 304994
  • Loading branch information
Nikolai Bozhenov committed Jun 8, 2017
1 parent e128958 commit 32dc6c8
Show file tree
Hide file tree
Showing 5 changed files with 270 additions and 0 deletions.
70 changes: 70 additions & 0 deletions clang/include/clang/Basic/BuiltinsNios2.def
@@ -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
10 changes: 10 additions & 0 deletions clang/include/clang/Basic/TargetBuiltins.h
Expand Up @@ -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 {
Expand Down
145 changes: 145 additions & 0 deletions clang/lib/Basic/Targets.cpp
Expand Up @@ -7702,6 +7702,148 @@ class BPFTargetInfo : public TargetInfo {
}
};

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;
Expand Down Expand Up @@ -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:
Expand Down
19 changes: 19 additions & 0 deletions clang/lib/Driver/ToolChains/CommonArgs.cpp
Expand Up @@ -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();
Expand Down Expand Up @@ -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:
Expand Down
26 changes: 26 additions & 0 deletions clang/test/Driver/nios2-cpu.c
@@ -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: "-target" "nios2"
// CHECK-R1: "-target" "nios2"
// CHECK-R1: "-target-cpu" "nios2r1"
// CHECK-R2: "-target" "nios2"
// CHECK-R2: "-target-cpu" "nios2r2"

0 comments on commit 32dc6c8

Please sign in to comment.