Index: include/clang/Basic/BuiltinsNios2.def =================================================================== --- include/clang/Basic/BuiltinsNios2.def +++ 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 Index: include/clang/Basic/TargetBuiltins.h =================================================================== --- include/clang/Basic/TargetBuiltins.h +++ include/clang/Basic/TargetBuiltins.h @@ -150,6 +150,16 @@ }; } + /// \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 { Index: lib/Basic/Targets.cpp =================================================================== --- lib/Basic/Targets.cpp +++ lib/Basic/Targets.cpp @@ -7604,6 +7604,147 @@ } }; +class Nios2TargetInfo : public TargetInfo { + void setDataLayout() { + StringRef Layout = "p:32:32:32-i8:8:32-i16:16:32-n32"; + if (BigEndian) { + resetDataLayout(("E-" + Layout).str()); + } else { + resetDataLayout(("e-" + Layout).str()); + } + } + + 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_ARCH", "\"" + CPU + "\""); + Builder.defineMacro("_NIOS2_ARCH_" + StringRef(CPU).upper()); + } + + ArrayRef 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(Feature) + .Case("nios2r2mandatory", isR2) + .Case("nios2r2bmx", isR2) + .Case("nios2r2mpx", isR2) + .Case("nios2r2cdx", isR2) + .Default(false); + } + + bool initFeatureMap(llvm::StringMap &Features, + DiagnosticsEngine &Diags, StringRef CPU, + const std::vector &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 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", + // Control 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 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; @@ -9224,6 +9365,9 @@ case llvm::Triple::msp430: return new MSP430TargetInfo(Triple, Opts); + case llvm::Triple::nios2: + return new LinuxTargetInfo(Triple, Opts); + case llvm::Triple::mips: switch (os) { case llvm::Triple::Linux: Index: lib/Driver/ToolChains/CommonArgs.cpp =================================================================== --- lib/Driver/ToolChains/CommonArgs.cpp +++ lib/Driver/ToolChains/CommonArgs.cpp @@ -215,6 +215,21 @@ return ""; } +static std::string getNios2TargetCPU(const ArgList &Args) { + Arg *A = Args.getLastArg(options::OPT_mcpu_EQ); + if (A == nullptr) + A = Args.getLastArg(options::OPT_march_EQ); + + if (A) { + const char *name = A->getValue(); + return llvm::StringSwitch(name) + .Case("r1", "nios2r1") + .Case("r2", "nios2r2") + .Default(name); + } + return ""; +} + static std::string getLanaiTargetCPU(const ArgList &Args) { if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) { return A->getValue(); @@ -267,6 +282,10 @@ return A->getValue(); return ""; + case llvm::Triple::nios2: { + return getNios2TargetCPU(Args); + } + case llvm::Triple::mips: case llvm::Triple::mipsel: case llvm::Triple::mips64: