2006-10-14 15:39:34 +08:00
|
|
|
//===--- Targets.cpp - Implement -arch option and targets -----------------===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-30 03:59:25 +08:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2006-10-14 15:39:34 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2009-05-03 21:42:53 +08:00
|
|
|
// This file implements construction of a TargetInfo object from a
|
2007-12-13 02:05:32 +08:00
|
|
|
// target triple.
|
2006-10-14 15:39:34 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "clang/Basic/TargetInfo.h"
|
2009-11-15 14:48:46 +08:00
|
|
|
#include "clang/Basic/Builtins.h"
|
|
|
|
#include "clang/Basic/Diagnostic.h"
|
2008-12-05 06:54:33 +08:00
|
|
|
#include "clang/Basic/LangOptions.h"
|
2010-01-20 14:13:02 +08:00
|
|
|
#include "clang/Basic/MacroBuilder.h"
|
2009-11-15 14:48:46 +08:00
|
|
|
#include "clang/Basic/TargetBuiltins.h"
|
|
|
|
#include "clang/Basic/TargetOptions.h"
|
2008-05-20 22:27:34 +08:00
|
|
|
#include "llvm/ADT/APFloat.h"
|
2009-11-15 14:48:46 +08:00
|
|
|
#include "llvm/ADT/OwningPtr.h"
|
2009-11-11 17:38:56 +08:00
|
|
|
#include "llvm/ADT/STLExtras.h"
|
2009-08-20 04:04:03 +08:00
|
|
|
#include "llvm/ADT/StringRef.h"
|
2009-11-11 17:38:56 +08:00
|
|
|
#include "llvm/ADT/StringSwitch.h"
|
2009-08-12 14:24:27 +08:00
|
|
|
#include "llvm/ADT/Triple.h"
|
2009-08-11 03:03:04 +08:00
|
|
|
#include "llvm/MC/MCSectionMachO.h"
|
2010-10-30 07:24:33 +08:00
|
|
|
#include "llvm/Type.h"
|
2010-01-10 02:20:57 +08:00
|
|
|
#include <algorithm>
|
2007-12-04 06:06:55 +08:00
|
|
|
using namespace clang;
|
2006-10-14 15:39:34 +08:00
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
2006-10-15 02:32:12 +08:00
|
|
|
// Common code shared among targets.
|
2006-10-14 15:39:34 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2009-03-21 00:06:38 +08:00
|
|
|
/// DefineStd - Define a macro name and standard variants. For example if
|
|
|
|
/// MacroName is "unix", then this will define "__unix", "__unix__", and "unix"
|
|
|
|
/// when in GNU mode.
|
2010-01-10 01:55:51 +08:00
|
|
|
static void DefineStd(MacroBuilder &Builder, llvm::StringRef MacroName,
|
2009-03-21 00:06:38 +08:00
|
|
|
const LangOptions &Opts) {
|
|
|
|
assert(MacroName[0] != '_' && "Identifier should be in the user's namespace");
|
2009-05-03 21:42:53 +08:00
|
|
|
|
2009-03-21 00:06:38 +08:00
|
|
|
// If in GNU mode (e.g. -std=gnu99 but not -std=c99) define the raw identifier
|
|
|
|
// in the user's namespace.
|
|
|
|
if (Opts.GNUMode)
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro(MacroName);
|
2009-05-03 21:42:53 +08:00
|
|
|
|
2009-03-21 00:06:38 +08:00
|
|
|
// Define __unix.
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__" + MacroName);
|
2009-05-03 21:42:53 +08:00
|
|
|
|
2009-03-21 00:06:38 +08:00
|
|
|
// Define __unix__.
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__" + MacroName + "__");
|
2009-03-21 00:06:38 +08:00
|
|
|
}
|
|
|
|
|
2008-10-06 05:50:58 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Defines specific to certain operating systems.
|
|
|
|
//===----------------------------------------------------------------------===//
|
2009-08-11 03:03:04 +08:00
|
|
|
|
2009-07-01 01:10:35 +08:00
|
|
|
namespace {
|
2009-07-01 23:12:53 +08:00
|
|
|
template<typename TgtInfo>
|
|
|
|
class OSTargetInfo : public TgtInfo {
|
2009-07-01 01:10:35 +08:00
|
|
|
protected:
|
2009-08-24 17:10:05 +08:00
|
|
|
virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
2010-01-10 01:55:51 +08:00
|
|
|
MacroBuilder &Builder) const=0;
|
2009-07-01 01:10:35 +08:00
|
|
|
public:
|
2009-07-01 23:12:53 +08:00
|
|
|
OSTargetInfo(const std::string& triple) : TgtInfo(triple) {}
|
2009-07-01 01:10:35 +08:00
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
2010-01-10 01:55:51 +08:00
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
TgtInfo::getTargetDefines(Opts, Builder);
|
|
|
|
getOSDefines(Opts, TgtInfo::getTriple(), Builder);
|
2009-07-01 01:00:25 +08:00
|
|
|
}
|
|
|
|
|
2009-07-01 01:10:35 +08:00
|
|
|
};
|
2009-08-12 14:24:27 +08:00
|
|
|
} // end anonymous namespace
|
2009-05-03 21:42:53 +08:00
|
|
|
|
2008-12-05 07:20:07 +08:00
|
|
|
|
2010-01-26 09:44:04 +08:00
|
|
|
static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
|
|
|
|
const llvm::Triple &Triple) {
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__APPLE_CC__", "5621");
|
|
|
|
Builder.defineMacro("__APPLE__");
|
|
|
|
Builder.defineMacro("__MACH__");
|
|
|
|
Builder.defineMacro("OBJC_NEW_PROPERTIES");
|
2009-05-03 21:42:53 +08:00
|
|
|
|
2009-04-08 00:50:40 +08:00
|
|
|
// __weak is always defined, for use in blocks and with objc pointers.
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))");
|
2009-05-03 21:42:53 +08:00
|
|
|
|
2009-04-08 00:50:40 +08:00
|
|
|
// Darwin defines __strong even in C mode (just to nothing).
|
|
|
|
if (!Opts.ObjC1 || Opts.getGCMode() == LangOptions::NonGC)
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__strong", "");
|
2009-04-08 00:50:40 +08:00
|
|
|
else
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__strong", "__attribute__((objc_gc(strong)))");
|
2009-06-05 07:00:29 +08:00
|
|
|
|
|
|
|
if (Opts.Static)
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__STATIC__");
|
2009-06-05 07:00:29 +08:00
|
|
|
else
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__DYNAMIC__");
|
2009-09-03 12:54:28 +08:00
|
|
|
|
|
|
|
if (Opts.POSIXThreads)
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("_REENTRANT");
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2010-01-26 09:44:04 +08:00
|
|
|
// Get the OS version number from the triple.
|
2009-04-11 03:52:24 +08:00
|
|
|
unsigned Maj, Min, Rev;
|
|
|
|
|
2010-01-26 09:44:04 +08:00
|
|
|
// If no version was given, default to to 10.4.0, for simplifying tests.
|
|
|
|
if (Triple.getOSName() == "darwin") {
|
|
|
|
Min = Rev = 0;
|
|
|
|
Maj = 8;
|
|
|
|
} else
|
|
|
|
Triple.getDarwinNumber(Maj, Min, Rev);
|
|
|
|
|
|
|
|
// Set the appropriate OS version define.
|
|
|
|
if (Triple.getEnvironmentName() == "iphoneos") {
|
|
|
|
assert(Maj < 10 && Min < 99 && Rev < 99 && "Invalid version!");
|
|
|
|
char Str[6];
|
|
|
|
Str[0] = '0' + Maj;
|
|
|
|
Str[1] = '0' + (Min / 10);
|
|
|
|
Str[2] = '0' + (Min % 10);
|
|
|
|
Str[3] = '0' + (Rev / 10);
|
|
|
|
Str[4] = '0' + (Rev % 10);
|
|
|
|
Str[5] = '\0';
|
|
|
|
Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", Str);
|
|
|
|
} else {
|
|
|
|
// For historical reasons that make little sense, the version passed here is
|
|
|
|
// the "darwin" version, which drops the 10 and offsets by 4.
|
|
|
|
Rev = Min;
|
|
|
|
Min = Maj - 4;
|
|
|
|
Maj = 10;
|
|
|
|
|
|
|
|
assert(Triple.getEnvironmentName().empty() && "Invalid environment!");
|
|
|
|
assert(Maj < 99 && Min < 10 && Rev < 10 && "Invalid version!");
|
|
|
|
char Str[5];
|
|
|
|
Str[0] = '0' + (Maj / 10);
|
|
|
|
Str[1] = '0' + (Maj % 10);
|
|
|
|
Str[2] = '0' + Min;
|
|
|
|
Str[3] = '0' + Rev;
|
|
|
|
Str[4] = '\0';
|
|
|
|
Builder.defineMacro("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", Str);
|
2008-09-30 09:00:25 +08:00
|
|
|
}
|
2008-08-20 10:34:37 +08:00
|
|
|
}
|
2006-10-14 15:39:34 +08:00
|
|
|
|
2009-08-11 03:03:04 +08:00
|
|
|
namespace {
|
2009-07-01 01:10:35 +08:00
|
|
|
template<typename Target>
|
|
|
|
class DarwinTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
2009-08-24 17:10:05 +08:00
|
|
|
virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
2010-01-10 01:55:51 +08:00
|
|
|
MacroBuilder &Builder) const {
|
2010-01-26 09:44:04 +08:00
|
|
|
getDarwinDefines(Builder, Opts, Triple);
|
2009-07-01 01:10:35 +08:00
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-07-01 01:10:35 +08:00
|
|
|
public:
|
|
|
|
DarwinTargetInfo(const std::string& triple) :
|
|
|
|
OSTargetInfo<Target>(triple) {
|
2010-06-26 03:04:52 +08:00
|
|
|
this->TLSSupported = llvm::Triple(triple).getDarwinMajorNumber() > 10;
|
2009-07-01 01:10:35 +08:00
|
|
|
}
|
|
|
|
|
2010-01-31 02:33:31 +08:00
|
|
|
virtual std::string isValidSectionSpecifier(llvm::StringRef SR) const {
|
2009-08-11 03:03:04 +08:00
|
|
|
// Let MCSectionMachO validate this.
|
|
|
|
llvm::StringRef Segment, Section;
|
|
|
|
unsigned TAA, StubSize;
|
|
|
|
return llvm::MCSectionMachO::ParseSectionSpecifier(SR, Segment, Section,
|
|
|
|
TAA, StubSize);
|
|
|
|
}
|
2010-10-21 11:16:25 +08:00
|
|
|
|
2010-06-09 06:47:50 +08:00
|
|
|
virtual const char *getStaticInitSectionSpecifier() const {
|
|
|
|
// FIXME: We should return 0 when building kexts.
|
|
|
|
return "__TEXT,__StaticInit,regular,pure_instructions";
|
|
|
|
}
|
2010-10-21 11:16:25 +08:00
|
|
|
|
2009-07-01 01:10:35 +08:00
|
|
|
};
|
|
|
|
|
2009-08-11 03:03:04 +08:00
|
|
|
|
2009-07-01 01:10:35 +08:00
|
|
|
// DragonFlyBSD Target
|
|
|
|
template<typename Target>
|
|
|
|
class DragonFlyBSDTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
2009-08-24 17:10:05 +08:00
|
|
|
virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
2010-01-10 01:55:51 +08:00
|
|
|
MacroBuilder &Builder) const {
|
2009-07-01 01:10:35 +08:00
|
|
|
// DragonFly defines; list based off of gcc output
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__DragonFly__");
|
|
|
|
Builder.defineMacro("__DragonFly_cc_version", "100001");
|
|
|
|
Builder.defineMacro("__ELF__");
|
|
|
|
Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
|
|
|
|
Builder.defineMacro("__tune_i386__");
|
|
|
|
DefineStd(Builder, "unix", Opts);
|
2009-07-01 01:10:35 +08:00
|
|
|
}
|
|
|
|
public:
|
2009-09-09 23:08:12 +08:00
|
|
|
DragonFlyBSDTargetInfo(const std::string &triple)
|
2009-07-01 01:10:35 +08:00
|
|
|
: OSTargetInfo<Target>(triple) {}
|
|
|
|
};
|
|
|
|
|
|
|
|
// FreeBSD Target
|
|
|
|
template<typename Target>
|
|
|
|
class FreeBSDTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
2009-08-24 17:10:05 +08:00
|
|
|
virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
2010-01-10 01:55:51 +08:00
|
|
|
MacroBuilder &Builder) const {
|
2009-07-01 01:10:35 +08:00
|
|
|
// FreeBSD defines; list based off of gcc output
|
|
|
|
|
2009-08-24 17:10:05 +08:00
|
|
|
// FIXME: Move version number handling to llvm::Triple.
|
2010-01-31 03:55:01 +08:00
|
|
|
llvm::StringRef Release = Triple.getOSName().substr(strlen("freebsd"), 1);
|
|
|
|
|
|
|
|
Builder.defineMacro("__FreeBSD__", Release);
|
|
|
|
Builder.defineMacro("__FreeBSD_cc_version", Release + "00001");
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
|
|
|
|
DefineStd(Builder, "unix", Opts);
|
|
|
|
Builder.defineMacro("__ELF__");
|
2009-07-01 01:10:35 +08:00
|
|
|
}
|
|
|
|
public:
|
2009-09-09 23:08:12 +08:00
|
|
|
FreeBSDTargetInfo(const std::string &triple)
|
2009-07-08 21:55:08 +08:00
|
|
|
: OSTargetInfo<Target>(triple) {
|
|
|
|
this->UserLabelPrefix = "";
|
|
|
|
}
|
2009-07-01 01:10:35 +08:00
|
|
|
};
|
|
|
|
|
2010-07-08 00:01:42 +08:00
|
|
|
// Minix Target
|
|
|
|
template<typename Target>
|
|
|
|
class MinixTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
|
|
|
virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
// Minix defines
|
|
|
|
|
|
|
|
Builder.defineMacro("__minix", "3");
|
|
|
|
Builder.defineMacro("_EM_WSIZE", "4");
|
|
|
|
Builder.defineMacro("_EM_PSIZE", "4");
|
|
|
|
Builder.defineMacro("_EM_SSIZE", "2");
|
|
|
|
Builder.defineMacro("_EM_LSIZE", "4");
|
|
|
|
Builder.defineMacro("_EM_FSIZE", "4");
|
|
|
|
Builder.defineMacro("_EM_DSIZE", "8");
|
|
|
|
DefineStd(Builder, "unix", Opts);
|
|
|
|
}
|
|
|
|
public:
|
|
|
|
MinixTargetInfo(const std::string &triple)
|
|
|
|
: OSTargetInfo<Target>(triple) {
|
|
|
|
this->UserLabelPrefix = "";
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2009-07-01 01:10:35 +08:00
|
|
|
// Linux target
|
|
|
|
template<typename Target>
|
|
|
|
class LinuxTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
2009-08-24 17:10:05 +08:00
|
|
|
virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
2010-01-10 01:55:51 +08:00
|
|
|
MacroBuilder &Builder) const {
|
2009-07-01 01:10:35 +08:00
|
|
|
// Linux defines; list based off of gcc output
|
2010-01-10 01:55:51 +08:00
|
|
|
DefineStd(Builder, "unix", Opts);
|
|
|
|
DefineStd(Builder, "linux", Opts);
|
|
|
|
Builder.defineMacro("__gnu_linux__");
|
|
|
|
Builder.defineMacro("__ELF__");
|
2009-09-03 12:54:28 +08:00
|
|
|
if (Opts.POSIXThreads)
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("_REENTRANT");
|
2010-04-21 13:52:38 +08:00
|
|
|
if (Opts.CPlusPlus)
|
|
|
|
Builder.defineMacro("_GNU_SOURCE");
|
2009-07-01 01:10:35 +08:00
|
|
|
}
|
|
|
|
public:
|
2009-09-09 23:08:12 +08:00
|
|
|
LinuxTargetInfo(const std::string& triple)
|
2009-07-01 01:10:35 +08:00
|
|
|
: OSTargetInfo<Target>(triple) {
|
|
|
|
this->UserLabelPrefix = "";
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2009-07-14 04:29:08 +08:00
|
|
|
// NetBSD Target
|
|
|
|
template<typename Target>
|
|
|
|
class NetBSDTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
2009-08-24 17:10:05 +08:00
|
|
|
virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
2010-01-10 01:55:51 +08:00
|
|
|
MacroBuilder &Builder) const {
|
2009-07-14 04:29:08 +08:00
|
|
|
// NetBSD defines; list based off of gcc output
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__NetBSD__");
|
|
|
|
Builder.defineMacro("__unix__");
|
|
|
|
Builder.defineMacro("__ELF__");
|
2009-09-03 12:54:28 +08:00
|
|
|
if (Opts.POSIXThreads)
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("_POSIX_THREADS");
|
2009-07-14 04:29:08 +08:00
|
|
|
}
|
|
|
|
public:
|
2009-09-09 23:08:12 +08:00
|
|
|
NetBSDTargetInfo(const std::string &triple)
|
2009-07-14 04:29:08 +08:00
|
|
|
: OSTargetInfo<Target>(triple) {
|
|
|
|
this->UserLabelPrefix = "";
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2009-07-01 01:10:35 +08:00
|
|
|
// OpenBSD Target
|
|
|
|
template<typename Target>
|
|
|
|
class OpenBSDTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
2009-08-24 17:10:05 +08:00
|
|
|
virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
2010-01-10 01:55:51 +08:00
|
|
|
MacroBuilder &Builder) const {
|
2009-07-01 01:10:35 +08:00
|
|
|
// OpenBSD defines; list based off of gcc output
|
|
|
|
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__OpenBSD__");
|
|
|
|
DefineStd(Builder, "unix", Opts);
|
|
|
|
Builder.defineMacro("__ELF__");
|
2009-09-03 12:54:28 +08:00
|
|
|
if (Opts.POSIXThreads)
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("_POSIX_THREADS");
|
2009-07-01 01:10:35 +08:00
|
|
|
}
|
|
|
|
public:
|
2009-09-09 23:08:12 +08:00
|
|
|
OpenBSDTargetInfo(const std::string &triple)
|
2009-07-01 01:10:35 +08:00
|
|
|
: OSTargetInfo<Target>(triple) {}
|
|
|
|
};
|
|
|
|
|
2009-11-15 18:22:07 +08:00
|
|
|
// PSP Target
|
|
|
|
template<typename Target>
|
|
|
|
class PSPTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
|
|
|
virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
2010-01-10 01:55:51 +08:00
|
|
|
MacroBuilder &Builder) const {
|
2009-11-15 18:22:07 +08:00
|
|
|
// PSP defines; list based on the output of the pspdev gcc toolchain.
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("PSP");
|
|
|
|
Builder.defineMacro("_PSP");
|
|
|
|
Builder.defineMacro("__psp__");
|
|
|
|
Builder.defineMacro("__ELF__");
|
2009-11-15 18:22:07 +08:00
|
|
|
}
|
|
|
|
public:
|
|
|
|
PSPTargetInfo(const std::string& triple)
|
|
|
|
: OSTargetInfo<Target>(triple) {
|
|
|
|
this->UserLabelPrefix = "";
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2009-11-20 01:18:50 +08:00
|
|
|
// PS3 PPU Target
|
|
|
|
template<typename Target>
|
|
|
|
class PS3PPUTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
|
|
|
virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
2010-01-10 01:55:51 +08:00
|
|
|
MacroBuilder &Builder) const {
|
2009-11-20 01:18:50 +08:00
|
|
|
// PS3 PPU defines.
|
2010-03-26 00:18:32 +08:00
|
|
|
Builder.defineMacro("__PPC__");
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__PPU__");
|
|
|
|
Builder.defineMacro("__CELLOS_LV2__");
|
|
|
|
Builder.defineMacro("__ELF__");
|
|
|
|
Builder.defineMacro("__LP32__");
|
2010-06-25 06:44:13 +08:00
|
|
|
Builder.defineMacro("_ARCH_PPC64");
|
|
|
|
Builder.defineMacro("__powerpc64__");
|
2009-11-20 01:18:50 +08:00
|
|
|
}
|
|
|
|
public:
|
|
|
|
PS3PPUTargetInfo(const std::string& triple)
|
|
|
|
: OSTargetInfo<Target>(triple) {
|
|
|
|
this->UserLabelPrefix = "";
|
2009-12-18 22:21:08 +08:00
|
|
|
this->LongWidth = this->LongAlign = this->PointerWidth = this->PointerAlign = 32;
|
2010-06-25 06:44:13 +08:00
|
|
|
this->IntMaxType = TargetInfo::SignedLongLong;
|
|
|
|
this->UIntMaxType = TargetInfo::UnsignedLongLong;
|
|
|
|
this->Int64Type = TargetInfo::SignedLongLong;
|
2009-12-18 22:21:08 +08:00
|
|
|
this->SizeType = TargetInfo::UnsignedInt;
|
2010-06-25 06:44:13 +08:00
|
|
|
this->DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
|
|
|
|
"i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";
|
2009-11-20 01:18:50 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// FIXME: Need a real SPU target.
|
|
|
|
// PS3 SPU Target
|
|
|
|
template<typename Target>
|
|
|
|
class PS3SPUTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
|
|
|
virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
2010-01-10 01:55:51 +08:00
|
|
|
MacroBuilder &Builder) const {
|
2009-11-20 01:18:50 +08:00
|
|
|
// PS3 PPU defines.
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__SPU__");
|
|
|
|
Builder.defineMacro("__ELF__");
|
2009-11-20 01:18:50 +08:00
|
|
|
}
|
|
|
|
public:
|
|
|
|
PS3SPUTargetInfo(const std::string& triple)
|
|
|
|
: OSTargetInfo<Target>(triple) {
|
|
|
|
this->UserLabelPrefix = "";
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2009-10-18 21:33:59 +08:00
|
|
|
// AuroraUX target
|
|
|
|
template<typename Target>
|
|
|
|
class AuroraUXTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
|
|
|
virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
2010-01-10 01:55:51 +08:00
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
DefineStd(Builder, "sun", Opts);
|
|
|
|
DefineStd(Builder, "unix", Opts);
|
|
|
|
Builder.defineMacro("__ELF__");
|
|
|
|
Builder.defineMacro("__svr4__");
|
|
|
|
Builder.defineMacro("__SVR4");
|
2009-10-18 21:33:59 +08:00
|
|
|
}
|
|
|
|
public:
|
|
|
|
AuroraUXTargetInfo(const std::string& triple)
|
|
|
|
: OSTargetInfo<Target>(triple) {
|
|
|
|
this->UserLabelPrefix = "";
|
|
|
|
this->WCharType = this->SignedLong;
|
|
|
|
// FIXME: WIntType should be SignedLong
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2009-07-01 01:10:35 +08:00
|
|
|
// Solaris target
|
|
|
|
template<typename Target>
|
|
|
|
class SolarisTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
2009-08-24 17:10:05 +08:00
|
|
|
virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
2010-01-10 01:55:51 +08:00
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
DefineStd(Builder, "sun", Opts);
|
|
|
|
DefineStd(Builder, "unix", Opts);
|
|
|
|
Builder.defineMacro("__ELF__");
|
|
|
|
Builder.defineMacro("__svr4__");
|
|
|
|
Builder.defineMacro("__SVR4");
|
2009-07-01 01:10:35 +08:00
|
|
|
}
|
|
|
|
public:
|
2009-09-09 23:08:12 +08:00
|
|
|
SolarisTargetInfo(const std::string& triple)
|
2009-07-01 01:10:35 +08:00
|
|
|
: OSTargetInfo<Target>(triple) {
|
|
|
|
this->UserLabelPrefix = "";
|
|
|
|
this->WCharType = this->SignedLong;
|
|
|
|
// FIXME: WIntType should be SignedLong
|
|
|
|
}
|
|
|
|
};
|
2010-10-21 13:21:48 +08:00
|
|
|
|
|
|
|
// Windows target
|
|
|
|
template<typename Target>
|
|
|
|
class WindowsTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
|
|
|
virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
|
|
|
MacroBuilder &Builder) const {
|
2010-10-21 16:22:51 +08:00
|
|
|
Builder.defineMacro("_WIN32");
|
|
|
|
}
|
|
|
|
void getVisualStudioDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const {
|
2010-10-21 13:21:48 +08:00
|
|
|
if (Opts.CPlusPlus) {
|
|
|
|
if (Opts.RTTI)
|
|
|
|
Builder.defineMacro("_CPPRTTI");
|
|
|
|
|
|
|
|
if (Opts.Exceptions)
|
|
|
|
Builder.defineMacro("_CPPUNWIND");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!Opts.CharIsSigned)
|
|
|
|
Builder.defineMacro("_CHAR_UNSIGNED");
|
|
|
|
|
|
|
|
// FIXME: POSIXThreads isn't exactly the option this should be defined for,
|
|
|
|
// but it works for now.
|
|
|
|
if (Opts.POSIXThreads)
|
|
|
|
Builder.defineMacro("_MT");
|
2010-10-21 16:22:51 +08:00
|
|
|
|
2010-10-21 13:21:48 +08:00
|
|
|
if (Opts.MSCVersion != 0)
|
|
|
|
Builder.defineMacro("_MSC_VER", llvm::Twine(Opts.MSCVersion));
|
|
|
|
|
|
|
|
if (Opts.Microsoft) {
|
|
|
|
Builder.defineMacro("_MSC_EXTENSIONS");
|
|
|
|
|
|
|
|
if (Opts.CPlusPlus0x) {
|
|
|
|
Builder.defineMacro("_RVALUE_REFERENCES_V2_SUPPORTED");
|
|
|
|
Builder.defineMacro("_RVALUE_REFERENCES_SUPPORTED");
|
|
|
|
Builder.defineMacro("_NATIVE_NULLPTR_SUPPORTED");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Builder.defineMacro("_INTEGRAL_MAX_BITS", "64");
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
WindowsTargetInfo(const std::string &triple)
|
|
|
|
: OSTargetInfo<Target>(triple) {}
|
|
|
|
};
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
} // end anonymous namespace.
|
2009-07-01 01:10:35 +08:00
|
|
|
|
2008-08-21 07:11:40 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Specific target implementations.
|
|
|
|
//===----------------------------------------------------------------------===//
|
2007-10-13 08:45:48 +08:00
|
|
|
|
2008-08-21 07:11:40 +08:00
|
|
|
namespace {
|
|
|
|
// PPC abstract base class
|
|
|
|
class PPCTargetInfo : public TargetInfo {
|
|
|
|
static const Builtin::Info BuiltinInfo[];
|
|
|
|
static const char * const GCCRegNames[];
|
|
|
|
static const TargetInfo::GCCRegAlias GCCRegAliases[];
|
|
|
|
|
|
|
|
public:
|
2009-06-05 15:05:05 +08:00
|
|
|
PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {}
|
|
|
|
|
2008-08-21 07:11:40 +08:00
|
|
|
virtual void getTargetBuiltins(const Builtin::Info *&Records,
|
|
|
|
unsigned &NumRecords) const {
|
2007-01-29 13:24:35 +08:00
|
|
|
Records = BuiltinInfo;
|
2008-08-21 07:11:40 +08:00
|
|
|
NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
|
2007-01-29 13:24:35 +08:00
|
|
|
}
|
2009-05-03 21:42:53 +08:00
|
|
|
|
2009-03-20 23:52:06 +08:00
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
2010-01-10 01:55:51 +08:00
|
|
|
MacroBuilder &Builder) const;
|
2009-05-03 21:42:53 +08:00
|
|
|
|
2008-08-21 07:11:40 +08:00
|
|
|
virtual const char *getVAListDeclaration() const {
|
2008-10-27 09:11:29 +08:00
|
|
|
return "typedef char* __builtin_va_list;";
|
|
|
|
// This is the right definition for ABI/V4: System V.4/eabi.
|
|
|
|
/*return "typedef struct __va_list_tag {"
|
2008-08-21 07:11:40 +08:00
|
|
|
" unsigned char gpr;"
|
|
|
|
" unsigned char fpr;"
|
|
|
|
" unsigned short reserved;"
|
|
|
|
" void* overflow_arg_area;"
|
|
|
|
" void* reg_save_area;"
|
2008-10-27 09:11:29 +08:00
|
|
|
"} __builtin_va_list[1];";*/
|
2007-11-25 07:38:12 +08:00
|
|
|
}
|
2009-05-03 21:42:53 +08:00
|
|
|
virtual void getGCCRegNames(const char * const *&Names,
|
2008-08-21 07:11:40 +08:00
|
|
|
unsigned &NumNames) const;
|
2009-05-03 21:42:53 +08:00
|
|
|
virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
|
2008-08-21 07:11:40 +08:00
|
|
|
unsigned &NumAliases) const;
|
2009-03-01 01:11:49 +08:00
|
|
|
virtual bool validateAsmConstraint(const char *&Name,
|
2009-04-26 15:16:29 +08:00
|
|
|
TargetInfo::ConstraintInfo &Info) const {
|
2009-03-01 01:11:49 +08:00
|
|
|
switch (*Name) {
|
2007-11-27 12:11:28 +08:00
|
|
|
default: return false;
|
|
|
|
case 'O': // Zero
|
2010-06-25 06:44:13 +08:00
|
|
|
break;
|
2007-11-27 12:11:28 +08:00
|
|
|
case 'b': // Base register
|
|
|
|
case 'f': // Floating point register
|
2009-04-26 15:16:29 +08:00
|
|
|
Info.setAllowsRegister();
|
2010-06-25 06:44:13 +08:00
|
|
|
break;
|
|
|
|
// FIXME: The following are added to allow parsing.
|
|
|
|
// I just took a guess at what the actions should be.
|
|
|
|
// Also, is more specific checking needed? I.e. specific registers?
|
2010-10-21 11:16:25 +08:00
|
|
|
case 'd': // Floating point register (containing 64-bit value)
|
2010-06-25 06:44:13 +08:00
|
|
|
case 'v': // Altivec vector register
|
|
|
|
Info.setAllowsRegister();
|
|
|
|
break;
|
|
|
|
case 'w':
|
|
|
|
switch (Name[1]) {
|
2010-10-21 11:16:25 +08:00
|
|
|
case 'd':// VSX vector register to hold vector double data
|
|
|
|
case 'f':// VSX vector register to hold vector float data
|
|
|
|
case 's':// VSX vector register to hold scalar float data
|
|
|
|
case 'a':// Any VSX register
|
2010-06-25 06:44:13 +08:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
Info.setAllowsRegister();
|
|
|
|
Name++; // Skip over 'w'.
|
|
|
|
break;
|
2010-10-21 11:16:25 +08:00
|
|
|
case 'h': // `MQ', `CTR', or `LINK' register
|
|
|
|
case 'q': // `MQ' register
|
|
|
|
case 'c': // `CTR' register
|
|
|
|
case 'l': // `LINK' register
|
|
|
|
case 'x': // `CR' register (condition register) number 0
|
|
|
|
case 'y': // `CR' register (condition register)
|
|
|
|
case 'z': // `XER[CA]' carry bit (part of the XER register)
|
2010-06-25 06:44:13 +08:00
|
|
|
Info.setAllowsRegister();
|
|
|
|
break;
|
2010-10-21 11:16:25 +08:00
|
|
|
case 'I': // Signed 16-bit constant
|
2010-06-25 06:44:13 +08:00
|
|
|
case 'J': // Unsigned 16-bit constant shifted left 16 bits
|
2010-10-21 11:16:25 +08:00
|
|
|
// (use `L' instead for SImode constants)
|
|
|
|
case 'K': // Unsigned 16-bit constant
|
|
|
|
case 'L': // Signed 16-bit constant shifted left 16 bits
|
|
|
|
case 'M': // Constant larger than 31
|
|
|
|
case 'N': // Exact power of 2
|
|
|
|
case 'P': // Constant whose negation is a signed 16-bit constant
|
2010-06-25 06:44:13 +08:00
|
|
|
case 'G': // Floating point constant that can be loaded into a
|
2010-10-21 11:16:25 +08:00
|
|
|
// register with one instruction per word
|
2010-06-25 06:44:13 +08:00
|
|
|
case 'H': // Integer/Floating point constant that can be loaded
|
2010-10-21 11:16:25 +08:00
|
|
|
// into a register using three instructions
|
2010-06-25 06:44:13 +08:00
|
|
|
break;
|
|
|
|
case 'm': // Memory operand. Note that on PowerPC targets, m can
|
|
|
|
// include addresses that update the base register. It
|
|
|
|
// is therefore only safe to use `m' in an asm statement
|
|
|
|
// if that asm statement accesses the operand exactly once.
|
|
|
|
// The asm statement must also use `%U<opno>' as a
|
2010-08-18 06:42:34 +08:00
|
|
|
// placeholder for the "update" flag in the corresponding
|
2010-10-21 11:16:25 +08:00
|
|
|
// load or store instruction. For example:
|
2010-06-25 06:44:13 +08:00
|
|
|
// asm ("st%U0 %1,%0" : "=m" (mem) : "r" (val));
|
2010-10-21 11:16:25 +08:00
|
|
|
// is correct but:
|
2010-06-25 06:44:13 +08:00
|
|
|
// asm ("st %1,%0" : "=m" (mem) : "r" (val));
|
|
|
|
// is not. Use es rather than m if you don't want the base
|
2010-10-21 11:16:25 +08:00
|
|
|
// register to be updated.
|
|
|
|
case 'e':
|
2010-06-25 08:02:05 +08:00
|
|
|
if (Name[1] != 's')
|
|
|
|
return false;
|
2010-08-18 06:42:34 +08:00
|
|
|
// es: A "stable" memory operand; that is, one which does not
|
2010-06-25 06:44:13 +08:00
|
|
|
// include any automodification of the base register. Unlike
|
|
|
|
// `m', this constraint can be used in asm statements that
|
|
|
|
// might access the operand several times, or that might not
|
2010-06-25 08:02:05 +08:00
|
|
|
// access it at all.
|
2010-06-25 06:44:13 +08:00
|
|
|
Info.setAllowsMemory();
|
2010-06-25 08:02:05 +08:00
|
|
|
Name++; // Skip over 'e'.
|
2010-06-25 06:44:13 +08:00
|
|
|
break;
|
|
|
|
case 'Q': // Memory operand that is an offset from a register (it is
|
2010-10-21 11:16:25 +08:00
|
|
|
// usually better to use `m' or `es' in asm statements)
|
2010-06-25 06:44:13 +08:00
|
|
|
case 'Z': // Memory operand that is an indexed or indirect from a
|
|
|
|
// register (it is usually better to use `m' or `es' in
|
2010-10-21 11:16:25 +08:00
|
|
|
// asm statements)
|
2010-06-25 06:44:13 +08:00
|
|
|
Info.setAllowsMemory();
|
|
|
|
Info.setAllowsRegister();
|
|
|
|
break;
|
2010-10-21 11:16:25 +08:00
|
|
|
case 'R': // AIX TOC entry
|
2010-06-25 06:44:13 +08:00
|
|
|
case 'a': // Address operand that is an indexed or indirect from a
|
2010-10-21 11:16:25 +08:00
|
|
|
// register (`p' is preferable for asm statements)
|
|
|
|
case 'S': // Constant suitable as a 64-bit mask operand
|
|
|
|
case 'T': // Constant suitable as a 32-bit mask operand
|
|
|
|
case 'U': // System V Release 4 small data area reference
|
2010-06-25 06:44:13 +08:00
|
|
|
case 't': // AND masks that can be performed by two rldic{l, r}
|
2010-10-21 11:16:25 +08:00
|
|
|
// instructions
|
|
|
|
case 'W': // Vector constant that does not require memory
|
|
|
|
case 'j': // Vector constant that is all zeros.
|
2010-06-25 06:44:13 +08:00
|
|
|
break;
|
|
|
|
// End FIXME.
|
2007-11-27 12:11:28 +08:00
|
|
|
}
|
2010-06-25 06:44:13 +08:00
|
|
|
return true;
|
2007-11-27 12:11:28 +08:00
|
|
|
}
|
2008-08-21 07:11:40 +08:00
|
|
|
virtual const char *getClobbers() const {
|
|
|
|
return "";
|
2007-11-27 12:11:28 +08:00
|
|
|
}
|
2008-08-21 07:11:40 +08:00
|
|
|
};
|
2007-11-27 12:11:28 +08:00
|
|
|
|
2008-08-21 07:11:40 +08:00
|
|
|
const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
|
2010-12-01 01:35:24 +08:00
|
|
|
#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES, false },
|
|
|
|
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
|
|
|
|
ALL_LANGUAGES, false },
|
2009-06-14 09:05:48 +08:00
|
|
|
#include "clang/Basic/BuiltinsPPC.def"
|
2008-08-21 07:11:40 +08:00
|
|
|
};
|
2009-05-03 21:42:53 +08:00
|
|
|
|
|
|
|
|
2009-03-03 06:27:17 +08:00
|
|
|
/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
|
|
|
|
/// #defines that are not tied to a specific subtarget.
|
2009-03-20 23:52:06 +08:00
|
|
|
void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
|
2010-01-10 01:55:51 +08:00
|
|
|
MacroBuilder &Builder) const {
|
2009-03-03 06:27:17 +08:00
|
|
|
// Target identification.
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__ppc__");
|
|
|
|
Builder.defineMacro("_ARCH_PPC");
|
2010-02-17 02:14:57 +08:00
|
|
|
Builder.defineMacro("__powerpc__");
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__POWERPC__");
|
2009-03-03 06:27:17 +08:00
|
|
|
if (PointerWidth == 64) {
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("_ARCH_PPC64");
|
|
|
|
Builder.defineMacro("_LP64");
|
|
|
|
Builder.defineMacro("__LP64__");
|
2010-02-17 02:14:57 +08:00
|
|
|
Builder.defineMacro("__powerpc64__");
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__ppc64__");
|
2009-03-03 06:27:17 +08:00
|
|
|
} else {
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__ppc__");
|
2009-03-03 06:27:17 +08:00
|
|
|
}
|
2009-05-03 21:42:53 +08:00
|
|
|
|
2009-03-03 06:27:17 +08:00
|
|
|
// Target properties.
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("_BIG_ENDIAN");
|
|
|
|
Builder.defineMacro("__BIG_ENDIAN__");
|
2009-05-03 21:42:53 +08:00
|
|
|
|
2009-03-03 06:27:17 +08:00
|
|
|
// Subtarget options.
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__NATURAL_ALIGNMENT__");
|
|
|
|
Builder.defineMacro("__REGISTER_PREFIX__", "");
|
2009-05-03 21:42:53 +08:00
|
|
|
|
2009-03-03 06:27:17 +08:00
|
|
|
// FIXME: Should be controlled by command line option.
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__LONG_DOUBLE_128__");
|
2010-10-21 11:16:25 +08:00
|
|
|
|
2009-11-20 01:18:50 +08:00
|
|
|
if (Opts.AltiVec) {
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__VEC__", "10206");
|
|
|
|
Builder.defineMacro("__ALTIVEC__");
|
2009-11-20 01:18:50 +08:00
|
|
|
}
|
2009-03-03 06:27:17 +08:00
|
|
|
}
|
|
|
|
|
2008-04-22 02:56:49 +08:00
|
|
|
|
2008-08-21 07:11:40 +08:00
|
|
|
const char * const PPCTargetInfo::GCCRegNames[] = {
|
2009-09-16 13:05:27 +08:00
|
|
|
"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",
|
|
|
|
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
|
|
|
|
"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
|
|
|
|
"f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
|
|
|
|
"f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
|
2008-08-21 07:11:40 +08:00
|
|
|
"mq", "lr", "ctr", "ap",
|
2009-09-16 13:05:27 +08:00
|
|
|
"cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
|
2008-08-21 07:11:40 +08:00
|
|
|
"xer",
|
2009-09-16 13:05:27 +08:00
|
|
|
"v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
|
|
|
|
"v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
|
|
|
|
"v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
|
|
|
|
"v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
|
2008-08-21 07:11:40 +08:00
|
|
|
"vrsave", "vscr",
|
|
|
|
"spe_acc", "spefscr",
|
|
|
|
"sfp"
|
|
|
|
};
|
2007-01-29 13:24:35 +08:00
|
|
|
|
2009-05-03 21:42:53 +08:00
|
|
|
void PPCTargetInfo::getGCCRegNames(const char * const *&Names,
|
2008-08-21 07:11:40 +08:00
|
|
|
unsigned &NumNames) const {
|
|
|
|
Names = GCCRegNames;
|
|
|
|
NumNames = llvm::array_lengthof(GCCRegNames);
|
|
|
|
}
|
2006-10-14 15:39:34 +08:00
|
|
|
|
2008-08-21 07:11:40 +08:00
|
|
|
const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
|
|
|
|
// While some of these aliases do map to different registers
|
|
|
|
// they still share the same register name.
|
2009-09-17 15:03:19 +08:00
|
|
|
{ { "0" }, "r0" },
|
|
|
|
{ { "1"}, "r1" },
|
|
|
|
{ { "2" }, "r2" },
|
|
|
|
{ { "3" }, "r3" },
|
|
|
|
{ { "4" }, "r4" },
|
|
|
|
{ { "5" }, "r5" },
|
|
|
|
{ { "6" }, "r6" },
|
|
|
|
{ { "7" }, "r7" },
|
|
|
|
{ { "8" }, "r8" },
|
|
|
|
{ { "9" }, "r9" },
|
|
|
|
{ { "10" }, "r10" },
|
|
|
|
{ { "11" }, "r11" },
|
|
|
|
{ { "12" }, "r12" },
|
|
|
|
{ { "13" }, "r13" },
|
|
|
|
{ { "14" }, "r14" },
|
|
|
|
{ { "15" }, "r15" },
|
|
|
|
{ { "16" }, "r16" },
|
|
|
|
{ { "17" }, "r17" },
|
|
|
|
{ { "18" }, "r18" },
|
|
|
|
{ { "19" }, "r19" },
|
|
|
|
{ { "20" }, "r20" },
|
|
|
|
{ { "21" }, "r21" },
|
|
|
|
{ { "22" }, "r22" },
|
|
|
|
{ { "23" }, "r23" },
|
|
|
|
{ { "24" }, "r24" },
|
|
|
|
{ { "25" }, "r25" },
|
|
|
|
{ { "26" }, "r26" },
|
|
|
|
{ { "27" }, "r27" },
|
|
|
|
{ { "28" }, "r28" },
|
|
|
|
{ { "29" }, "r29" },
|
|
|
|
{ { "30" }, "r30" },
|
|
|
|
{ { "31" }, "r31" },
|
|
|
|
{ { "fr0" }, "f0" },
|
|
|
|
{ { "fr1" }, "f1" },
|
|
|
|
{ { "fr2" }, "f2" },
|
|
|
|
{ { "fr3" }, "f3" },
|
|
|
|
{ { "fr4" }, "f4" },
|
|
|
|
{ { "fr5" }, "f5" },
|
|
|
|
{ { "fr6" }, "f6" },
|
|
|
|
{ { "fr7" }, "f7" },
|
|
|
|
{ { "fr8" }, "f8" },
|
|
|
|
{ { "fr9" }, "f9" },
|
2009-09-18 05:15:00 +08:00
|
|
|
{ { "fr10" }, "f10" },
|
2009-09-17 15:03:19 +08:00
|
|
|
{ { "fr11" }, "f11" },
|
|
|
|
{ { "fr12" }, "f12" },
|
|
|
|
{ { "fr13" }, "f13" },
|
|
|
|
{ { "fr14" }, "f14" },
|
|
|
|
{ { "fr15" }, "f15" },
|
|
|
|
{ { "fr16" }, "f16" },
|
|
|
|
{ { "fr17" }, "f17" },
|
|
|
|
{ { "fr18" }, "f18" },
|
|
|
|
{ { "fr19" }, "f19" },
|
|
|
|
{ { "fr20" }, "f20" },
|
|
|
|
{ { "fr21" }, "f21" },
|
|
|
|
{ { "fr22" }, "f22" },
|
|
|
|
{ { "fr23" }, "f23" },
|
|
|
|
{ { "fr24" }, "f24" },
|
|
|
|
{ { "fr25" }, "f25" },
|
|
|
|
{ { "fr26" }, "f26" },
|
|
|
|
{ { "fr27" }, "f27" },
|
|
|
|
{ { "fr28" }, "f28" },
|
|
|
|
{ { "fr29" }, "f29" },
|
|
|
|
{ { "fr30" }, "f30" },
|
|
|
|
{ { "fr31" }, "f31" },
|
|
|
|
{ { "cc" }, "cr0" },
|
2008-08-21 07:11:40 +08:00
|
|
|
};
|
|
|
|
|
2009-05-03 21:42:53 +08:00
|
|
|
void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
|
2008-08-21 07:11:40 +08:00
|
|
|
unsigned &NumAliases) const {
|
|
|
|
Aliases = GCCRegAliases;
|
|
|
|
NumAliases = llvm::array_lengthof(GCCRegAliases);
|
|
|
|
}
|
|
|
|
} // end anonymous namespace.
|
2006-10-14 15:50:21 +08:00
|
|
|
|
2006-10-14 15:39:34 +08:00
|
|
|
namespace {
|
2008-08-21 07:11:40 +08:00
|
|
|
class PPC32TargetInfo : public PPCTargetInfo {
|
2006-10-14 15:39:34 +08:00
|
|
|
public:
|
2010-02-17 02:14:57 +08:00
|
|
|
PPC32TargetInfo(const std::string &triple) : PPCTargetInfo(triple) {
|
2008-08-21 08:13:15 +08:00
|
|
|
DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
|
2009-11-08 02:59:41 +08:00
|
|
|
"i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";
|
2010-02-17 02:14:57 +08:00
|
|
|
|
|
|
|
if (getTriple().getOS() == llvm::Triple::FreeBSD)
|
|
|
|
this->SizeType = TargetInfo::UnsignedInt;
|
2008-08-21 08:13:15 +08:00
|
|
|
}
|
2006-10-14 15:39:34 +08:00
|
|
|
};
|
|
|
|
} // end anonymous namespace.
|
|
|
|
|
|
|
|
namespace {
|
2008-08-21 07:11:40 +08:00
|
|
|
class PPC64TargetInfo : public PPCTargetInfo {
|
2006-10-14 15:39:34 +08:00
|
|
|
public:
|
2008-08-21 07:11:40 +08:00
|
|
|
PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
|
2008-05-09 14:17:04 +08:00
|
|
|
LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
|
2009-07-01 11:36:11 +08:00
|
|
|
IntMaxType = SignedLong;
|
|
|
|
UIntMaxType = UnsignedLong;
|
|
|
|
Int64Type = SignedLong;
|
2008-08-21 08:13:15 +08:00
|
|
|
DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
|
2009-11-08 02:59:41 +08:00
|
|
|
"i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64";
|
2008-05-09 14:17:04 +08:00
|
|
|
}
|
2008-08-21 07:11:40 +08:00
|
|
|
};
|
|
|
|
} // end anonymous namespace.
|
|
|
|
|
2010-05-30 08:07:30 +08:00
|
|
|
|
|
|
|
namespace {
|
|
|
|
class DarwinPPCTargetInfo :
|
|
|
|
public DarwinTargetInfo<PPCTargetInfo> {
|
|
|
|
public:
|
|
|
|
DarwinPPCTargetInfo(const std::string& triple)
|
|
|
|
: DarwinTargetInfo<PPCTargetInfo>(triple) {
|
|
|
|
HasAlignMac68kSupport = true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class DarwinPPC64TargetInfo :
|
|
|
|
public DarwinTargetInfo<PPC64TargetInfo> {
|
|
|
|
public:
|
|
|
|
DarwinPPC64TargetInfo(const std::string& triple)
|
|
|
|
: DarwinTargetInfo<PPC64TargetInfo>(triple) {
|
|
|
|
HasAlignMac68kSupport = true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
} // end anonymous namespace.
|
|
|
|
|
2010-03-07 05:21:27 +08:00
|
|
|
namespace {
|
|
|
|
// MBlaze abstract base class
|
|
|
|
class MBlazeTargetInfo : public TargetInfo {
|
|
|
|
static const char * const GCCRegNames[];
|
|
|
|
static const TargetInfo::GCCRegAlias GCCRegAliases[];
|
|
|
|
|
|
|
|
public:
|
|
|
|
MBlazeTargetInfo(const std::string& triple) : TargetInfo(triple) {
|
2010-12-13 04:56:47 +08:00
|
|
|
DescriptionString = "E-p:32:32:32-i8:8:8-i16:16:16";
|
2010-03-07 05:21:27 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
virtual void getTargetBuiltins(const Builtin::Info *&Records,
|
|
|
|
unsigned &NumRecords) const {
|
|
|
|
// FIXME: Implement.
|
|
|
|
Records = 0;
|
|
|
|
NumRecords = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const;
|
|
|
|
|
|
|
|
virtual const char *getVAListDeclaration() const {
|
|
|
|
return "typedef char* __builtin_va_list;";
|
|
|
|
}
|
|
|
|
virtual const char *getTargetPrefix() const {
|
|
|
|
return "mblaze";
|
|
|
|
}
|
|
|
|
virtual void getGCCRegNames(const char * const *&Names,
|
|
|
|
unsigned &NumNames) const;
|
|
|
|
virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
|
|
|
|
unsigned &NumAliases) const;
|
|
|
|
virtual bool validateAsmConstraint(const char *&Name,
|
|
|
|
TargetInfo::ConstraintInfo &Info) const {
|
|
|
|
switch (*Name) {
|
|
|
|
default: return false;
|
|
|
|
case 'O': // Zero
|
|
|
|
return true;
|
|
|
|
case 'b': // Base register
|
|
|
|
case 'f': // Floating point register
|
|
|
|
Info.setAllowsRegister();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
virtual const char *getClobbers() const {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/// MBlazeTargetInfo::getTargetDefines - Return a set of the MBlaze-specific
|
|
|
|
/// #defines that are not tied to a specific subtarget.
|
|
|
|
void MBlazeTargetInfo::getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
// Target identification.
|
|
|
|
Builder.defineMacro("__microblaze__");
|
|
|
|
Builder.defineMacro("_ARCH_MICROBLAZE");
|
|
|
|
Builder.defineMacro("__MICROBLAZE__");
|
|
|
|
|
|
|
|
// Target properties.
|
|
|
|
Builder.defineMacro("_BIG_ENDIAN");
|
|
|
|
Builder.defineMacro("__BIG_ENDIAN__");
|
|
|
|
|
|
|
|
// Subtarget options.
|
|
|
|
Builder.defineMacro("__REGISTER_PREFIX__", "");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const char * const MBlazeTargetInfo::GCCRegNames[] = {
|
|
|
|
"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",
|
|
|
|
"$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
|
|
|
|
"$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
|
|
|
|
"$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
|
|
|
|
"$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
|
|
|
|
"hi", "lo", "accum","rmsr", "$fcc1","$fcc2","$fcc3","$fcc4",
|
|
|
|
"$fcc5","$fcc6","$fcc7","$ap", "$rap", "$frp"
|
|
|
|
};
|
|
|
|
|
|
|
|
void MBlazeTargetInfo::getGCCRegNames(const char * const *&Names,
|
|
|
|
unsigned &NumNames) const {
|
|
|
|
Names = GCCRegNames;
|
|
|
|
NumNames = llvm::array_lengthof(GCCRegNames);
|
|
|
|
}
|
|
|
|
|
|
|
|
const TargetInfo::GCCRegAlias MBlazeTargetInfo::GCCRegAliases[] = {
|
|
|
|
{ {"f0"}, "r0" },
|
|
|
|
{ {"f1"}, "r1" },
|
|
|
|
{ {"f2"}, "r2" },
|
|
|
|
{ {"f3"}, "r3" },
|
|
|
|
{ {"f4"}, "r4" },
|
|
|
|
{ {"f5"}, "r5" },
|
|
|
|
{ {"f6"}, "r6" },
|
|
|
|
{ {"f7"}, "r7" },
|
|
|
|
{ {"f8"}, "r8" },
|
|
|
|
{ {"f9"}, "r9" },
|
|
|
|
{ {"f10"}, "r10" },
|
|
|
|
{ {"f11"}, "r11" },
|
|
|
|
{ {"f12"}, "r12" },
|
|
|
|
{ {"f13"}, "r13" },
|
|
|
|
{ {"f14"}, "r14" },
|
|
|
|
{ {"f15"}, "r15" },
|
|
|
|
{ {"f16"}, "r16" },
|
|
|
|
{ {"f17"}, "r17" },
|
|
|
|
{ {"f18"}, "r18" },
|
|
|
|
{ {"f19"}, "r19" },
|
|
|
|
{ {"f20"}, "r20" },
|
|
|
|
{ {"f21"}, "r21" },
|
|
|
|
{ {"f22"}, "r22" },
|
|
|
|
{ {"f23"}, "r23" },
|
|
|
|
{ {"f24"}, "r24" },
|
|
|
|
{ {"f25"}, "r25" },
|
|
|
|
{ {"f26"}, "r26" },
|
|
|
|
{ {"f27"}, "r27" },
|
|
|
|
{ {"f28"}, "r28" },
|
|
|
|
{ {"f29"}, "r29" },
|
|
|
|
{ {"f30"}, "r30" },
|
|
|
|
{ {"f31"}, "r31" },
|
|
|
|
};
|
|
|
|
|
|
|
|
void MBlazeTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
|
|
|
|
unsigned &NumAliases) const {
|
|
|
|
Aliases = GCCRegAliases;
|
|
|
|
NumAliases = llvm::array_lengthof(GCCRegAliases);
|
|
|
|
}
|
|
|
|
} // end anonymous namespace.
|
|
|
|
|
2006-10-14 15:39:34 +08:00
|
|
|
namespace {
|
2008-08-20 10:34:37 +08:00
|
|
|
// Namespace for x86 abstract base class
|
|
|
|
const Builtin::Info BuiltinInfo[] = {
|
2010-12-01 01:35:24 +08:00
|
|
|
#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES, false },
|
|
|
|
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
|
|
|
|
ALL_LANGUAGES, false },
|
2009-06-14 09:05:48 +08:00
|
|
|
#include "clang/Basic/BuiltinsX86.def"
|
2008-08-20 10:34:37 +08:00
|
|
|
};
|
|
|
|
|
2009-12-24 01:49:57 +08:00
|
|
|
static const char* const GCCRegNames[] = {
|
2008-08-20 10:34:37 +08:00
|
|
|
"ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
|
|
|
|
"st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
|
|
|
|
"argp", "flags", "fspr", "dirflag", "frame",
|
|
|
|
"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
|
|
|
|
"mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
|
|
|
|
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
|
|
|
|
"xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
|
|
|
|
};
|
|
|
|
|
|
|
|
const TargetInfo::GCCRegAlias GCCRegAliases[] = {
|
|
|
|
{ { "al", "ah", "eax", "rax" }, "ax" },
|
|
|
|
{ { "bl", "bh", "ebx", "rbx" }, "bx" },
|
|
|
|
{ { "cl", "ch", "ecx", "rcx" }, "cx" },
|
|
|
|
{ { "dl", "dh", "edx", "rdx" }, "dx" },
|
|
|
|
{ { "esi", "rsi" }, "si" },
|
|
|
|
{ { "edi", "rdi" }, "di" },
|
|
|
|
{ { "esp", "rsp" }, "sp" },
|
|
|
|
{ { "ebp", "rbp" }, "bp" },
|
|
|
|
};
|
|
|
|
|
|
|
|
// X86 target abstract base class; x86-32 and x86-64 are very close, so
|
|
|
|
// most of the implementation can be shared.
|
|
|
|
class X86TargetInfo : public TargetInfo {
|
2009-03-03 06:40:39 +08:00
|
|
|
enum X86SSEEnum {
|
|
|
|
NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42
|
|
|
|
} SSELevel;
|
2010-01-27 11:47:49 +08:00
|
|
|
enum AMD3DNowEnum {
|
|
|
|
NoAMD3DNow, AMD3DNow, AMD3DNowAthlon
|
|
|
|
} AMD3DNowLevel;
|
|
|
|
|
2010-04-03 07:50:19 +08:00
|
|
|
bool HasAES;
|
2010-08-05 06:29:13 +08:00
|
|
|
bool HasAVX;
|
|
|
|
|
2006-10-14 15:39:34 +08:00
|
|
|
public:
|
2009-05-03 21:42:53 +08:00
|
|
|
X86TargetInfo(const std::string& triple)
|
2010-04-03 07:50:19 +08:00
|
|
|
: TargetInfo(triple), SSELevel(NoMMXSSE), AMD3DNowLevel(NoAMD3DNow),
|
2010-08-05 06:29:13 +08:00
|
|
|
HasAES(false), HasAVX(false) {
|
2008-05-20 22:21:01 +08:00
|
|
|
LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
|
|
|
|
}
|
2007-01-29 13:24:35 +08:00
|
|
|
virtual void getTargetBuiltins(const Builtin::Info *&Records,
|
|
|
|
unsigned &NumRecords) const {
|
2008-08-20 10:34:37 +08:00
|
|
|
Records = BuiltinInfo;
|
|
|
|
NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
|
2007-01-29 13:24:35 +08:00
|
|
|
}
|
2009-05-03 21:42:53 +08:00
|
|
|
virtual void getGCCRegNames(const char * const *&Names,
|
2008-08-20 10:34:37 +08:00
|
|
|
unsigned &NumNames) const {
|
|
|
|
Names = GCCRegNames;
|
|
|
|
NumNames = llvm::array_lengthof(GCCRegNames);
|
2007-11-25 07:38:12 +08:00
|
|
|
}
|
2009-05-03 21:42:53 +08:00
|
|
|
virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
|
2007-11-25 07:38:12 +08:00
|
|
|
unsigned &NumAliases) const {
|
2008-08-20 10:34:37 +08:00
|
|
|
Aliases = GCCRegAliases;
|
|
|
|
NumAliases = llvm::array_lengthof(GCCRegAliases);
|
2007-10-13 08:45:48 +08:00
|
|
|
}
|
2009-03-01 01:11:49 +08:00
|
|
|
virtual bool validateAsmConstraint(const char *&Name,
|
2008-08-20 10:34:37 +08:00
|
|
|
TargetInfo::ConstraintInfo &info) const;
|
2010-10-30 07:12:32 +08:00
|
|
|
virtual const llvm::Type* adjustInlineAsmType(std::string& Constraint,
|
|
|
|
const llvm::Type* Ty,
|
|
|
|
llvm::LLVMContext& Context) const;
|
2008-08-20 10:34:37 +08:00
|
|
|
virtual std::string convertConstraint(const char Constraint) const;
|
|
|
|
virtual const char *getClobbers() const {
|
|
|
|
return "~{dirflag},~{fpsr},~{flags}";
|
|
|
|
}
|
2009-03-20 23:52:06 +08:00
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
2010-01-10 01:55:51 +08:00
|
|
|
MacroBuilder &Builder) const;
|
2009-05-07 05:07:50 +08:00
|
|
|
virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
|
|
|
|
const std::string &Name,
|
|
|
|
bool Enabled) const;
|
2009-09-09 23:08:12 +08:00
|
|
|
virtual void getDefaultFeatures(const std::string &CPU,
|
2009-05-07 05:07:50 +08:00
|
|
|
llvm::StringMap<bool> &Features) const;
|
2009-12-19 11:30:57 +08:00
|
|
|
virtual void HandleTargetFeatures(std::vector<std::string> &Features);
|
2008-08-20 10:34:37 +08:00
|
|
|
};
|
2009-03-03 06:20:04 +08:00
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
void X86TargetInfo::getDefaultFeatures(const std::string &CPU,
|
2009-05-07 05:07:50 +08:00
|
|
|
llvm::StringMap<bool> &Features) const {
|
2009-05-06 11:16:41 +08:00
|
|
|
// FIXME: This should not be here.
|
|
|
|
Features["3dnow"] = false;
|
|
|
|
Features["3dnowa"] = false;
|
|
|
|
Features["mmx"] = false;
|
|
|
|
Features["sse"] = false;
|
|
|
|
Features["sse2"] = false;
|
|
|
|
Features["sse3"] = false;
|
|
|
|
Features["ssse3"] = false;
|
|
|
|
Features["sse41"] = false;
|
|
|
|
Features["sse42"] = false;
|
2010-04-03 07:50:19 +08:00
|
|
|
Features["aes"] = false;
|
2010-08-05 06:29:13 +08:00
|
|
|
Features["avx"] = false;
|
2009-05-06 11:16:41 +08:00
|
|
|
|
|
|
|
// LLVM does not currently recognize this.
|
|
|
|
// Features["sse4a"] = false;
|
|
|
|
|
|
|
|
// FIXME: This *really* should not be here.
|
|
|
|
|
|
|
|
// X86_64 always has SSE2.
|
|
|
|
if (PointerWidth == 64)
|
|
|
|
Features["sse2"] = Features["sse"] = Features["mmx"] = true;
|
|
|
|
|
2009-05-07 05:56:32 +08:00
|
|
|
if (CPU == "generic" || CPU == "i386" || CPU == "i486" || CPU == "i586" ||
|
|
|
|
CPU == "pentium" || CPU == "i686" || CPU == "pentiumpro")
|
|
|
|
;
|
|
|
|
else if (CPU == "pentium-mmx" || CPU == "pentium2")
|
|
|
|
setFeatureEnabled(Features, "mmx", true);
|
|
|
|
else if (CPU == "pentium3")
|
|
|
|
setFeatureEnabled(Features, "sse", true);
|
|
|
|
else if (CPU == "pentium-m" || CPU == "pentium4" || CPU == "x86-64")
|
|
|
|
setFeatureEnabled(Features, "sse2", true);
|
|
|
|
else if (CPU == "yonah" || CPU == "prescott" || CPU == "nocona")
|
|
|
|
setFeatureEnabled(Features, "sse3", true);
|
|
|
|
else if (CPU == "core2")
|
|
|
|
setFeatureEnabled(Features, "ssse3", true);
|
|
|
|
else if (CPU == "penryn") {
|
|
|
|
setFeatureEnabled(Features, "sse4", true);
|
|
|
|
Features["sse42"] = false;
|
|
|
|
} else if (CPU == "atom")
|
|
|
|
setFeatureEnabled(Features, "sse3", true);
|
2010-04-03 07:50:19 +08:00
|
|
|
else if (CPU == "corei7") {
|
2009-05-07 05:56:32 +08:00
|
|
|
setFeatureEnabled(Features, "sse4", true);
|
2010-04-03 07:50:19 +08:00
|
|
|
setFeatureEnabled(Features, "aes", true);
|
|
|
|
}
|
2009-05-07 05:56:32 +08:00
|
|
|
else if (CPU == "k6" || CPU == "winchip-c6")
|
|
|
|
setFeatureEnabled(Features, "mmx", true);
|
2009-09-09 23:08:12 +08:00
|
|
|
else if (CPU == "k6-2" || CPU == "k6-3" || CPU == "athlon" ||
|
2009-05-07 05:56:32 +08:00
|
|
|
CPU == "athlon-tbird" || CPU == "winchip2" || CPU == "c3") {
|
|
|
|
setFeatureEnabled(Features, "mmx", true);
|
|
|
|
setFeatureEnabled(Features, "3dnow", true);
|
|
|
|
} else if (CPU == "athlon-4" || CPU == "athlon-xp" || CPU == "athlon-mp") {
|
|
|
|
setFeatureEnabled(Features, "sse", true);
|
|
|
|
setFeatureEnabled(Features, "3dnowa", true);
|
|
|
|
} else if (CPU == "k8" || CPU == "opteron" || CPU == "athlon64" ||
|
|
|
|
CPU == "athlon-fx") {
|
2009-09-09 23:08:12 +08:00
|
|
|
setFeatureEnabled(Features, "sse2", true);
|
2009-05-07 05:56:32 +08:00
|
|
|
setFeatureEnabled(Features, "3dnowa", true);
|
2010-12-29 21:28:29 +08:00
|
|
|
} else if (CPU == "k8-sse3") {
|
|
|
|
setFeatureEnabled(Features, "sse3", true);
|
|
|
|
setFeatureEnabled(Features, "3dnowa", true);
|
2009-05-07 05:56:32 +08:00
|
|
|
} else if (CPU == "c3-2")
|
|
|
|
setFeatureEnabled(Features, "sse", true);
|
2009-05-06 11:16:41 +08:00
|
|
|
}
|
|
|
|
|
2009-05-07 05:07:50 +08:00
|
|
|
bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
|
2009-09-09 23:08:12 +08:00
|
|
|
const std::string &Name,
|
2009-05-07 05:07:50 +08:00
|
|
|
bool Enabled) const {
|
2010-03-04 10:26:37 +08:00
|
|
|
// FIXME: This *really* should not be here. We need some way of translating
|
|
|
|
// options into llvm subtarget features.
|
|
|
|
if (!Features.count(Name) &&
|
|
|
|
(Name != "sse4" && Name != "sse4.2" && Name != "sse4.1"))
|
2009-05-07 05:07:50 +08:00
|
|
|
return false;
|
|
|
|
|
|
|
|
if (Enabled) {
|
|
|
|
if (Name == "mmx")
|
|
|
|
Features["mmx"] = true;
|
|
|
|
else if (Name == "sse")
|
|
|
|
Features["mmx"] = Features["sse"] = true;
|
|
|
|
else if (Name == "sse2")
|
|
|
|
Features["mmx"] = Features["sse"] = Features["sse2"] = true;
|
|
|
|
else if (Name == "sse3")
|
2009-09-09 23:08:12 +08:00
|
|
|
Features["mmx"] = Features["sse"] = Features["sse2"] =
|
2009-05-07 05:07:50 +08:00
|
|
|
Features["sse3"] = true;
|
|
|
|
else if (Name == "ssse3")
|
2009-09-09 23:08:12 +08:00
|
|
|
Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
|
2009-05-07 05:07:50 +08:00
|
|
|
Features["ssse3"] = true;
|
2010-03-04 10:26:37 +08:00
|
|
|
else if (Name == "sse4" || Name == "sse4.2")
|
2009-09-09 23:08:12 +08:00
|
|
|
Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
|
2009-05-07 05:07:50 +08:00
|
|
|
Features["ssse3"] = Features["sse41"] = Features["sse42"] = true;
|
2010-03-04 10:26:37 +08:00
|
|
|
else if (Name == "sse4.1")
|
|
|
|
Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
|
|
|
|
Features["ssse3"] = Features["sse41"] = true;
|
2009-05-07 05:07:50 +08:00
|
|
|
else if (Name == "3dnow")
|
|
|
|
Features["3dnowa"] = true;
|
|
|
|
else if (Name == "3dnowa")
|
|
|
|
Features["3dnow"] = Features["3dnowa"] = true;
|
2010-04-03 07:50:19 +08:00
|
|
|
else if (Name == "aes")
|
|
|
|
Features["aes"] = true;
|
2010-08-05 06:29:13 +08:00
|
|
|
else if (Name == "avx")
|
|
|
|
Features["avx"] = true;
|
2009-05-07 05:07:50 +08:00
|
|
|
} else {
|
|
|
|
if (Name == "mmx")
|
2009-09-09 23:08:12 +08:00
|
|
|
Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
|
2009-05-07 05:07:50 +08:00
|
|
|
Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
|
|
|
|
else if (Name == "sse")
|
2009-09-09 23:08:12 +08:00
|
|
|
Features["sse"] = Features["sse2"] = Features["sse3"] =
|
2009-05-07 05:07:50 +08:00
|
|
|
Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
|
|
|
|
else if (Name == "sse2")
|
2009-09-09 23:08:12 +08:00
|
|
|
Features["sse2"] = Features["sse3"] = Features["ssse3"] =
|
2009-05-07 05:07:50 +08:00
|
|
|
Features["sse41"] = Features["sse42"] = false;
|
|
|
|
else if (Name == "sse3")
|
2009-09-09 23:08:12 +08:00
|
|
|
Features["sse3"] = Features["ssse3"] = Features["sse41"] =
|
2009-05-07 05:07:50 +08:00
|
|
|
Features["sse42"] = false;
|
|
|
|
else if (Name == "ssse3")
|
|
|
|
Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
|
|
|
|
else if (Name == "sse4")
|
|
|
|
Features["sse41"] = Features["sse42"] = false;
|
2010-03-04 10:31:44 +08:00
|
|
|
else if (Name == "sse4.2")
|
|
|
|
Features["sse42"] = false;
|
|
|
|
else if (Name == "sse4.1")
|
|
|
|
Features["sse41"] = Features["sse42"] = false;
|
2009-05-07 05:07:50 +08:00
|
|
|
else if (Name == "3dnow")
|
|
|
|
Features["3dnow"] = Features["3dnowa"] = false;
|
|
|
|
else if (Name == "3dnowa")
|
|
|
|
Features["3dnowa"] = false;
|
2010-04-03 07:50:19 +08:00
|
|
|
else if (Name == "aes")
|
|
|
|
Features["aes"] = false;
|
2010-08-05 06:29:13 +08:00
|
|
|
else if (Name == "avx")
|
|
|
|
Features["avx"] = false;
|
2009-05-07 05:07:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2009-05-06 11:16:41 +08:00
|
|
|
/// HandleTargetOptions - Perform initialization based on the user
|
|
|
|
/// configured set of features.
|
2009-12-19 11:30:57 +08:00
|
|
|
void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) {
|
2009-11-11 17:38:56 +08:00
|
|
|
// Remember the maximum enabled sselevel.
|
|
|
|
for (unsigned i = 0, e = Features.size(); i !=e; ++i) {
|
|
|
|
// Ignore disabled features.
|
|
|
|
if (Features[i][0] == '-')
|
|
|
|
continue;
|
|
|
|
|
2010-04-03 07:50:19 +08:00
|
|
|
if (Features[i].substr(1) == "aes") {
|
|
|
|
HasAES = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2010-08-05 06:29:13 +08:00
|
|
|
// FIXME: Not sure yet how to treat AVX in regard to SSE levels.
|
|
|
|
// For now let it be enabled together with other SSE levels.
|
|
|
|
if (Features[i].substr(1) == "avx") {
|
|
|
|
HasAVX = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2009-11-11 17:38:56 +08:00
|
|
|
assert(Features[i][0] == '+' && "Invalid target feature!");
|
|
|
|
X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Features[i].substr(1))
|
|
|
|
.Case("sse42", SSE42)
|
|
|
|
.Case("sse41", SSE41)
|
|
|
|
.Case("ssse3", SSSE3)
|
2010-03-12 18:20:09 +08:00
|
|
|
.Case("sse3", SSE3)
|
2009-11-11 17:38:56 +08:00
|
|
|
.Case("sse2", SSE2)
|
|
|
|
.Case("sse", SSE1)
|
|
|
|
.Case("mmx", MMX)
|
|
|
|
.Default(NoMMXSSE);
|
|
|
|
SSELevel = std::max(SSELevel, Level);
|
2010-10-21 11:16:25 +08:00
|
|
|
|
|
|
|
AMD3DNowEnum ThreeDNowLevel =
|
2010-01-27 11:47:49 +08:00
|
|
|
llvm::StringSwitch<AMD3DNowEnum>(Features[i].substr(1))
|
|
|
|
.Case("3dnowa", AMD3DNowAthlon)
|
|
|
|
.Case("3dnow", AMD3DNow)
|
|
|
|
.Default(NoAMD3DNow);
|
2010-10-21 11:16:25 +08:00
|
|
|
|
2010-01-27 11:47:49 +08:00
|
|
|
AMD3DNowLevel = std::max(AMD3DNowLevel, ThreeDNowLevel);
|
2009-11-11 17:38:56 +08:00
|
|
|
}
|
2009-03-03 06:20:04 +08:00
|
|
|
}
|
2009-03-03 06:27:17 +08:00
|
|
|
|
|
|
|
/// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines
|
|
|
|
/// that are not tied to a specific subtarget.
|
2009-03-20 23:52:06 +08:00
|
|
|
void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
|
2010-01-10 01:55:51 +08:00
|
|
|
MacroBuilder &Builder) const {
|
2009-03-03 06:27:17 +08:00
|
|
|
// Target identification.
|
|
|
|
if (PointerWidth == 64) {
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("_LP64");
|
|
|
|
Builder.defineMacro("__LP64__");
|
|
|
|
Builder.defineMacro("__amd64__");
|
|
|
|
Builder.defineMacro("__amd64");
|
|
|
|
Builder.defineMacro("__x86_64");
|
|
|
|
Builder.defineMacro("__x86_64__");
|
2009-03-03 06:27:17 +08:00
|
|
|
} else {
|
2010-01-10 01:55:51 +08:00
|
|
|
DefineStd(Builder, "i386", Opts);
|
2009-03-03 06:27:17 +08:00
|
|
|
}
|
2009-05-03 21:42:53 +08:00
|
|
|
|
2010-04-03 07:50:19 +08:00
|
|
|
if (HasAES)
|
|
|
|
Builder.defineMacro("__AES__");
|
|
|
|
|
2010-08-05 06:29:13 +08:00
|
|
|
if (HasAVX)
|
|
|
|
Builder.defineMacro("__AVX__");
|
|
|
|
|
2009-03-03 06:27:17 +08:00
|
|
|
// Target properties.
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__LITTLE_ENDIAN__");
|
2009-05-03 21:42:53 +08:00
|
|
|
|
2009-03-03 06:27:17 +08:00
|
|
|
// Subtarget options.
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__nocona");
|
|
|
|
Builder.defineMacro("__nocona__");
|
|
|
|
Builder.defineMacro("__tune_nocona__");
|
|
|
|
Builder.defineMacro("__REGISTER_PREFIX__", "");
|
2009-03-03 06:40:39 +08:00
|
|
|
|
2009-04-20 01:32:33 +08:00
|
|
|
// Define __NO_MATH_INLINES on linux/x86 so that we don't get inline
|
|
|
|
// functions in glibc header files that use FP Stack inline asm which the
|
|
|
|
// backend can't deal with (PR879).
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__NO_MATH_INLINES");
|
2009-05-03 21:42:53 +08:00
|
|
|
|
2009-03-03 06:40:39 +08:00
|
|
|
// Each case falls through to the previous one here.
|
|
|
|
switch (SSELevel) {
|
|
|
|
case SSE42:
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__SSE4_2__");
|
2009-03-03 06:40:39 +08:00
|
|
|
case SSE41:
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__SSE4_1__");
|
2009-03-03 06:40:39 +08:00
|
|
|
case SSSE3:
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__SSSE3__");
|
2009-03-03 06:40:39 +08:00
|
|
|
case SSE3:
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__SSE3__");
|
2009-03-03 06:40:39 +08:00
|
|
|
case SSE2:
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__SSE2__");
|
|
|
|
Builder.defineMacro("__SSE2_MATH__"); // -mfp-math=sse always implied.
|
2009-03-03 06:40:39 +08:00
|
|
|
case SSE1:
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__SSE__");
|
|
|
|
Builder.defineMacro("__SSE_MATH__"); // -mfp-math=sse always implied.
|
2009-03-03 06:40:39 +08:00
|
|
|
case MMX:
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__MMX__");
|
2009-03-03 06:40:39 +08:00
|
|
|
case NoMMXSSE:
|
|
|
|
break;
|
|
|
|
}
|
2010-10-18 15:10:59 +08:00
|
|
|
|
2010-10-21 13:21:48 +08:00
|
|
|
if (Opts.Microsoft && PointerWidth == 32) {
|
|
|
|
switch (SSELevel) {
|
2010-10-21 16:22:51 +08:00
|
|
|
case SSE42:
|
|
|
|
case SSE41:
|
|
|
|
case SSSE3:
|
|
|
|
case SSE3:
|
2010-10-21 13:21:48 +08:00
|
|
|
case SSE2:
|
|
|
|
Builder.defineMacro("_M_IX86_FP", llvm::Twine(2));
|
|
|
|
break;
|
|
|
|
case SSE1:
|
|
|
|
Builder.defineMacro("_M_IX86_FP", llvm::Twine(1));
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
Builder.defineMacro("_M_IX86_FP", llvm::Twine(0));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-01-27 11:47:49 +08:00
|
|
|
// Each case falls through to the previous one here.
|
|
|
|
switch (AMD3DNowLevel) {
|
|
|
|
case AMD3DNowAthlon:
|
|
|
|
Builder.defineMacro("__3dNOW_A__");
|
|
|
|
case AMD3DNow:
|
|
|
|
Builder.defineMacro("__3dNOW__");
|
|
|
|
case NoAMD3DNow:
|
|
|
|
break;
|
|
|
|
}
|
2009-03-03 06:27:17 +08:00
|
|
|
}
|
2009-05-03 21:42:53 +08:00
|
|
|
|
|
|
|
|
2008-08-20 10:34:37 +08:00
|
|
|
bool
|
2009-03-01 01:11:49 +08:00
|
|
|
X86TargetInfo::validateAsmConstraint(const char *&Name,
|
2009-04-26 15:16:29 +08:00
|
|
|
TargetInfo::ConstraintInfo &Info) const {
|
2009-03-01 01:11:49 +08:00
|
|
|
switch (*Name) {
|
2008-08-20 10:34:37 +08:00
|
|
|
default: return false;
|
2010-08-25 06:33:12 +08:00
|
|
|
case 'Y': // first letter of a pair:
|
|
|
|
switch (*(Name+1)) {
|
|
|
|
default: return false;
|
|
|
|
case '0': // First SSE register.
|
|
|
|
case 't': // Any SSE register, when SSE2 is enabled.
|
|
|
|
case 'i': // Any SSE register, when SSE2 and inter-unit moves enabled.
|
|
|
|
case 'm': // any MMX register, when inter-unit moves enabled.
|
|
|
|
break; // falls through to setAllowsRegister.
|
|
|
|
}
|
2008-08-20 10:34:37 +08:00
|
|
|
case 'a': // eax.
|
|
|
|
case 'b': // ebx.
|
|
|
|
case 'c': // ecx.
|
|
|
|
case 'd': // edx.
|
|
|
|
case 'S': // esi.
|
|
|
|
case 'D': // edi.
|
|
|
|
case 'A': // edx:eax.
|
2010-08-25 06:33:12 +08:00
|
|
|
case 'f': // any x87 floating point stack register.
|
2008-08-20 10:34:37 +08:00
|
|
|
case 't': // top of floating point stack.
|
|
|
|
case 'u': // second from top of floating point stack.
|
|
|
|
case 'q': // Any register accessible as [r]l: a, b, c, and d.
|
2008-10-06 08:41:45 +08:00
|
|
|
case 'y': // Any MMX register.
|
2008-10-07 03:17:39 +08:00
|
|
|
case 'x': // Any SSE register.
|
2008-08-20 10:34:37 +08:00
|
|
|
case 'Q': // Any register accessible as [r]h: a, b, c, and d.
|
2010-08-25 06:33:12 +08:00
|
|
|
case 'R': // "Legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
|
|
|
|
case 'l': // "Index" registers: any general register that can be used as an
|
|
|
|
// index in a base+index memory access.
|
|
|
|
Info.setAllowsRegister();
|
|
|
|
return true;
|
|
|
|
case 'C': // SSE floating point constant.
|
|
|
|
case 'G': // x87 floating point constant.
|
2009-05-03 21:42:53 +08:00
|
|
|
case 'e': // 32-bit signed integer constant for use with zero-extending
|
2009-01-25 02:03:09 +08:00
|
|
|
// x86_64 instructions.
|
2009-05-03 21:42:53 +08:00
|
|
|
case 'Z': // 32-bit unsigned integer constant for use with zero-extending
|
2009-01-25 02:03:09 +08:00
|
|
|
// x86_64 instructions.
|
2008-08-20 10:34:37 +08:00
|
|
|
return true;
|
2007-11-27 12:11:28 +08:00
|
|
|
}
|
2010-08-25 06:33:12 +08:00
|
|
|
return false;
|
2008-08-20 10:34:37 +08:00
|
|
|
}
|
2008-02-27 02:33:46 +08:00
|
|
|
|
2010-10-30 07:12:32 +08:00
|
|
|
const llvm::Type*
|
|
|
|
X86TargetInfo::adjustInlineAsmType(std::string& Constraint,
|
|
|
|
const llvm::Type* Ty,
|
|
|
|
llvm::LLVMContext &Context) const {
|
|
|
|
if (Constraint=="y" && Ty->isVectorTy())
|
|
|
|
return llvm::Type::getX86_MMXTy(Context);
|
|
|
|
return Ty;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-08-20 10:34:37 +08:00
|
|
|
std::string
|
|
|
|
X86TargetInfo::convertConstraint(const char Constraint) const {
|
|
|
|
switch (Constraint) {
|
|
|
|
case 'a': return std::string("{ax}");
|
|
|
|
case 'b': return std::string("{bx}");
|
|
|
|
case 'c': return std::string("{cx}");
|
|
|
|
case 'd': return std::string("{dx}");
|
|
|
|
case 'S': return std::string("{si}");
|
|
|
|
case 'D': return std::string("{di}");
|
2010-10-23 05:07:10 +08:00
|
|
|
case 'p': // address
|
|
|
|
return std::string("im");
|
2008-08-20 10:34:37 +08:00
|
|
|
case 't': // top of floating point stack.
|
|
|
|
return std::string("{st}");
|
|
|
|
case 'u': // second from top of floating point stack.
|
|
|
|
return std::string("{st(1)}"); // second from top of floating point stack.
|
|
|
|
default:
|
|
|
|
return std::string(1, Constraint);
|
2008-02-27 02:33:46 +08:00
|
|
|
}
|
2008-08-20 10:34:37 +08:00
|
|
|
}
|
|
|
|
} // end anonymous namespace
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
// X86-32 generic target
|
|
|
|
class X86_32TargetInfo : public X86TargetInfo {
|
|
|
|
public:
|
|
|
|
X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
|
|
|
|
DoubleAlign = LongLongAlign = 32;
|
|
|
|
LongDoubleWidth = 96;
|
|
|
|
LongDoubleAlign = 32;
|
2008-08-21 08:13:15 +08:00
|
|
|
DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
|
|
|
|
"i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
|
2009-11-08 02:59:41 +08:00
|
|
|
"a0:0:64-f80:32:32-n8:16:32";
|
2009-03-30 04:31:09 +08:00
|
|
|
SizeType = UnsignedInt;
|
|
|
|
PtrDiffType = SignedInt;
|
|
|
|
IntPtrType = SignedInt;
|
2009-04-04 07:38:25 +08:00
|
|
|
RegParmMax = 3;
|
2010-07-15 07:39:36 +08:00
|
|
|
|
|
|
|
// Use fpret for all types.
|
|
|
|
RealTypeUsesObjCFPRet = ((1 << TargetInfo::Float) |
|
|
|
|
(1 << TargetInfo::Double) |
|
|
|
|
(1 << TargetInfo::LongDouble));
|
2008-08-20 10:34:37 +08:00
|
|
|
}
|
|
|
|
virtual const char *getVAListDeclaration() const {
|
2008-08-20 15:28:14 +08:00
|
|
|
return "typedef char* __builtin_va_list;";
|
2008-08-20 10:34:37 +08:00
|
|
|
}
|
2010-10-21 11:16:25 +08:00
|
|
|
|
2009-09-23 14:06:36 +08:00
|
|
|
int getEHDataRegisterNumber(unsigned RegNo) const {
|
|
|
|
if (RegNo == 0) return 0;
|
|
|
|
if (RegNo == 1) return 2;
|
|
|
|
return -1;
|
|
|
|
}
|
2006-10-14 15:39:34 +08:00
|
|
|
};
|
2008-08-20 10:34:37 +08:00
|
|
|
} // end anonymous namespace
|
2006-10-14 15:39:34 +08:00
|
|
|
|
2009-07-06 02:47:56 +08:00
|
|
|
namespace {
|
|
|
|
class OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> {
|
|
|
|
public:
|
|
|
|
OpenBSDI386TargetInfo(const std::string& triple) :
|
|
|
|
OpenBSDTargetInfo<X86_32TargetInfo>(triple) {
|
|
|
|
SizeType = UnsignedLong;
|
|
|
|
IntPtrType = SignedLong;
|
2009-07-06 06:31:18 +08:00
|
|
|
PtrDiffType = SignedLong;
|
2009-07-06 02:47:56 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
} // end anonymous namespace
|
|
|
|
|
2006-10-14 15:39:34 +08:00
|
|
|
namespace {
|
2009-07-01 01:10:35 +08:00
|
|
|
class DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> {
|
2006-10-14 15:39:34 +08:00
|
|
|
public:
|
2009-07-01 01:10:35 +08:00
|
|
|
DarwinI386TargetInfo(const std::string& triple) :
|
|
|
|
DarwinTargetInfo<X86_32TargetInfo>(triple) {
|
2008-05-20 22:21:01 +08:00
|
|
|
LongDoubleWidth = 128;
|
|
|
|
LongDoubleAlign = 128;
|
2009-03-30 04:31:09 +08:00
|
|
|
SizeType = UnsignedLong;
|
|
|
|
IntPtrType = SignedLong;
|
2008-08-21 08:13:15 +08:00
|
|
|
DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
|
|
|
|
"i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
|
2009-11-08 02:59:41 +08:00
|
|
|
"a0:0:64-f80:128:128-n8:16:32";
|
2010-05-27 08:35:16 +08:00
|
|
|
HasAlignMac68kSupport = true;
|
2008-08-24 02:23:14 +08:00
|
|
|
}
|
|
|
|
|
2009-07-01 01:00:25 +08:00
|
|
|
};
|
2008-08-21 08:24:02 +08:00
|
|
|
} // end anonymous namespace
|
|
|
|
|
Initial implementation of Windows x86 target; at the moment, the only
difference from generic x86 is the defines. The rest is non-trivial to
implement.
I'm not planning on adding any more targets myself; if there are any
targets anyone is currently using that are missing, feel free to add
them, or ask me to add them.
This concludes the work I'm planning for the TargetInfo
implementations at the moment; all the other issues with TargetInfo require
some API changes, and I haven't really thought it through. Some of the
remaining issues: allowing targets to define size_t and wchar_t properly,
adding some sort of __builtin_type_info intrinsic so we can finish clang's
limits.h and float.h and get rid of a massive number of macro
definitions, allowing target-specific command-line options, allowing
target-specific defaults for certain command-line options like
-fms-extensions, exposing vector alignment outside of the description
string, exposing endianness outside of the description string, allowing
targets to expose special bit-field layout requirements, exposing some
sort of custom hook for call generation in CodeGen, and adding CPU
selection to control defines like __SSE__.
llvm-svn: 55098
2008-08-21 09:40:19 +08:00
|
|
|
namespace {
|
|
|
|
// x86-32 Windows target
|
2010-10-21 13:21:48 +08:00
|
|
|
class WindowsX86_32TargetInfo : public WindowsTargetInfo<X86_32TargetInfo> {
|
Initial implementation of Windows x86 target; at the moment, the only
difference from generic x86 is the defines. The rest is non-trivial to
implement.
I'm not planning on adding any more targets myself; if there are any
targets anyone is currently using that are missing, feel free to add
them, or ask me to add them.
This concludes the work I'm planning for the TargetInfo
implementations at the moment; all the other issues with TargetInfo require
some API changes, and I haven't really thought it through. Some of the
remaining issues: allowing targets to define size_t and wchar_t properly,
adding some sort of __builtin_type_info intrinsic so we can finish clang's
limits.h and float.h and get rid of a massive number of macro
definitions, allowing target-specific command-line options, allowing
target-specific defaults for certain command-line options like
-fms-extensions, exposing vector alignment outside of the description
string, exposing endianness outside of the description string, allowing
targets to expose special bit-field layout requirements, exposing some
sort of custom hook for call generation in CodeGen, and adding CPU
selection to control defines like __SSE__.
llvm-svn: 55098
2008-08-21 09:40:19 +08:00
|
|
|
public:
|
|
|
|
WindowsX86_32TargetInfo(const std::string& triple)
|
2010-10-21 13:21:48 +08:00
|
|
|
: WindowsTargetInfo<X86_32TargetInfo>(triple) {
|
2009-04-20 05:38:35 +08:00
|
|
|
TLSSupported = false;
|
2009-06-25 01:12:15 +08:00
|
|
|
WCharType = UnsignedShort;
|
2009-06-09 05:16:17 +08:00
|
|
|
DoubleAlign = LongLongAlign = 64;
|
|
|
|
DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
|
2009-12-19 10:05:07 +08:00
|
|
|
"i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-"
|
|
|
|
"v128:128:128-a0:0:64-f80:32:32-n8:16:32";
|
Initial implementation of Windows x86 target; at the moment, the only
difference from generic x86 is the defines. The rest is non-trivial to
implement.
I'm not planning on adding any more targets myself; if there are any
targets anyone is currently using that are missing, feel free to add
them, or ask me to add them.
This concludes the work I'm planning for the TargetInfo
implementations at the moment; all the other issues with TargetInfo require
some API changes, and I haven't really thought it through. Some of the
remaining issues: allowing targets to define size_t and wchar_t properly,
adding some sort of __builtin_type_info intrinsic so we can finish clang's
limits.h and float.h and get rid of a massive number of macro
definitions, allowing target-specific command-line options, allowing
target-specific defaults for certain command-line options like
-fms-extensions, exposing vector alignment outside of the description
string, exposing endianness outside of the description string, allowing
targets to expose special bit-field layout requirements, exposing some
sort of custom hook for call generation in CodeGen, and adding CPU
selection to control defines like __SSE__.
llvm-svn: 55098
2008-08-21 09:40:19 +08:00
|
|
|
}
|
2010-10-21 16:22:51 +08:00
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
WindowsTargetInfo<X86_32TargetInfo>::getTargetDefines(Opts, Builder);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
} // end anonymous namespace
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
// x86-32 Windows Visual Studio target
|
|
|
|
class VisualStudioWindowsX86_32TargetInfo : public WindowsX86_32TargetInfo {
|
|
|
|
public:
|
|
|
|
VisualStudioWindowsX86_32TargetInfo(const std::string& triple)
|
|
|
|
: WindowsX86_32TargetInfo(triple) {
|
|
|
|
LongDoubleWidth = 64;
|
|
|
|
LongDoubleFormat = &llvm::APFloat::IEEEdouble;
|
|
|
|
}
|
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
|
|
|
|
WindowsX86_32TargetInfo::getVisualStudioDefines(Opts, Builder);
|
|
|
|
// The value of the following reflects processor type.
|
|
|
|
// 300=386, 400=486, 500=Pentium, 600=Blend (default)
|
|
|
|
// We lost the original triple, so we use the default.
|
|
|
|
Builder.defineMacro("_M_IX86", "600");
|
|
|
|
}
|
2009-09-23 15:31:35 +08:00
|
|
|
};
|
|
|
|
} // end anonymous namespace
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
// x86-32 MinGW target
|
|
|
|
class MinGWX86_32TargetInfo : public WindowsX86_32TargetInfo {
|
|
|
|
public:
|
|
|
|
MinGWX86_32TargetInfo(const std::string& triple)
|
|
|
|
: WindowsX86_32TargetInfo(triple) {
|
|
|
|
}
|
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
2010-01-10 01:55:51 +08:00
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
|
2010-10-21 16:22:51 +08:00
|
|
|
DefineStd(Builder, "WIN32", Opts);
|
|
|
|
DefineStd(Builder, "WINNT", Opts);
|
|
|
|
Builder.defineMacro("_X86_");
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__MSVCRT__");
|
|
|
|
Builder.defineMacro("__MINGW32__");
|
|
|
|
Builder.defineMacro("__declspec", "__declspec");
|
2009-09-23 15:31:35 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
} // end anonymous namespace
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
// x86-32 Cygwin target
|
|
|
|
class CygwinX86_32TargetInfo : public X86_32TargetInfo {
|
|
|
|
public:
|
|
|
|
CygwinX86_32TargetInfo(const std::string& triple)
|
|
|
|
: X86_32TargetInfo(triple) {
|
|
|
|
TLSSupported = false;
|
|
|
|
WCharType = UnsignedShort;
|
|
|
|
DoubleAlign = LongLongAlign = 64;
|
|
|
|
DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
|
|
|
|
"i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
|
2009-11-08 02:59:41 +08:00
|
|
|
"a0:0:64-f80:32:32-n8:16:32";
|
2009-09-23 15:31:35 +08:00
|
|
|
}
|
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
2010-01-10 01:55:51 +08:00
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
X86_32TargetInfo::getTargetDefines(Opts, Builder);
|
|
|
|
Builder.defineMacro("__CYGWIN__");
|
|
|
|
Builder.defineMacro("__CYGWIN32__");
|
|
|
|
DefineStd(Builder, "unix", Opts);
|
2010-04-21 13:52:38 +08:00
|
|
|
if (Opts.CPlusPlus)
|
|
|
|
Builder.defineMacro("_GNU_SOURCE");
|
2009-06-08 14:11:14 +08:00
|
|
|
}
|
Initial implementation of Windows x86 target; at the moment, the only
difference from generic x86 is the defines. The rest is non-trivial to
implement.
I'm not planning on adding any more targets myself; if there are any
targets anyone is currently using that are missing, feel free to add
them, or ask me to add them.
This concludes the work I'm planning for the TargetInfo
implementations at the moment; all the other issues with TargetInfo require
some API changes, and I haven't really thought it through. Some of the
remaining issues: allowing targets to define size_t and wchar_t properly,
adding some sort of __builtin_type_info intrinsic so we can finish clang's
limits.h and float.h and get rid of a massive number of macro
definitions, allowing target-specific command-line options, allowing
target-specific defaults for certain command-line options like
-fms-extensions, exposing vector alignment outside of the description
string, exposing endianness outside of the description string, allowing
targets to expose special bit-field layout requirements, exposing some
sort of custom hook for call generation in CodeGen, and adding CPU
selection to control defines like __SSE__.
llvm-svn: 55098
2008-08-21 09:40:19 +08:00
|
|
|
};
|
|
|
|
} // end anonymous namespace
|
|
|
|
|
2010-04-12 03:29:39 +08:00
|
|
|
namespace {
|
|
|
|
// x86-32 Haiku target
|
|
|
|
class HaikuX86_32TargetInfo : public X86_32TargetInfo {
|
|
|
|
public:
|
|
|
|
HaikuX86_32TargetInfo(const std::string& triple)
|
|
|
|
: X86_32TargetInfo(triple) {
|
|
|
|
SizeType = UnsignedLong;
|
2010-04-23 01:48:00 +08:00
|
|
|
IntPtrType = SignedLong;
|
|
|
|
PtrDiffType = SignedLong;
|
2010-11-10 00:41:02 +08:00
|
|
|
this->UserLabelPrefix = "";
|
2010-08-22 09:00:03 +08:00
|
|
|
}
|
2010-04-12 03:29:39 +08:00
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
X86_32TargetInfo::getTargetDefines(Opts, Builder);
|
|
|
|
Builder.defineMacro("__INTEL__");
|
|
|
|
Builder.defineMacro("__HAIKU__");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
} // end anonymous namespace
|
|
|
|
|
2008-08-20 10:34:37 +08:00
|
|
|
namespace {
|
|
|
|
// x86-64 generic target
|
|
|
|
class X86_64TargetInfo : public X86TargetInfo {
|
|
|
|
public:
|
2009-03-20 23:52:06 +08:00
|
|
|
X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) {
|
2008-08-20 10:34:37 +08:00
|
|
|
LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
|
|
|
|
LongDoubleWidth = 128;
|
|
|
|
LongDoubleAlign = 128;
|
2010-06-05 07:15:27 +08:00
|
|
|
LargeArrayMinWidth = 128;
|
|
|
|
LargeArrayAlign = 128;
|
2009-02-05 15:32:46 +08:00
|
|
|
IntMaxType = SignedLong;
|
|
|
|
UIntMaxType = UnsignedLong;
|
2009-07-01 11:36:11 +08:00
|
|
|
Int64Type = SignedLong;
|
2009-04-04 07:38:25 +08:00
|
|
|
RegParmMax = 6;
|
2009-02-05 15:32:46 +08:00
|
|
|
|
2008-08-21 08:13:15 +08:00
|
|
|
DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
|
|
|
|
"i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
|
2009-11-08 02:59:41 +08:00
|
|
|
"a0:0:64-s0:64:64-f80:128:128-n8:16:32:64";
|
2010-07-15 07:39:36 +08:00
|
|
|
|
|
|
|
// Use fpret only for long double.
|
|
|
|
RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble);
|
2007-01-29 13:24:35 +08:00
|
|
|
}
|
2007-10-13 08:45:48 +08:00
|
|
|
virtual const char *getVAListDeclaration() const {
|
2008-08-20 15:28:14 +08:00
|
|
|
return "typedef struct __va_list_tag {"
|
|
|
|
" unsigned gp_offset;"
|
|
|
|
" unsigned fp_offset;"
|
|
|
|
" void* overflow_arg_area;"
|
|
|
|
" void* reg_save_area;"
|
2010-05-29 02:25:28 +08:00
|
|
|
"} __va_list_tag;"
|
2009-07-03 08:45:06 +08:00
|
|
|
"typedef __va_list_tag __builtin_va_list[1];";
|
2007-11-25 07:38:12 +08:00
|
|
|
}
|
2010-10-18 15:10:59 +08:00
|
|
|
|
2009-09-23 14:06:36 +08:00
|
|
|
int getEHDataRegisterNumber(unsigned RegNo) const {
|
|
|
|
if (RegNo == 0) return 0;
|
|
|
|
if (RegNo == 1) return 1;
|
|
|
|
return -1;
|
|
|
|
}
|
2008-08-20 10:34:37 +08:00
|
|
|
};
|
|
|
|
} // end anonymous namespace
|
|
|
|
|
2009-09-23 15:31:35 +08:00
|
|
|
namespace {
|
|
|
|
// x86-64 Windows target
|
2010-10-21 13:21:48 +08:00
|
|
|
class WindowsX86_64TargetInfo : public WindowsTargetInfo<X86_64TargetInfo> {
|
2009-09-23 15:31:35 +08:00
|
|
|
public:
|
|
|
|
WindowsX86_64TargetInfo(const std::string& triple)
|
2010-10-21 13:21:48 +08:00
|
|
|
: WindowsTargetInfo<X86_64TargetInfo>(triple) {
|
2009-09-23 15:31:35 +08:00
|
|
|
TLSSupported = false;
|
|
|
|
WCharType = UnsignedShort;
|
2009-10-09 07:00:00 +08:00
|
|
|
LongWidth = LongAlign = 32;
|
2010-10-18 15:10:59 +08:00
|
|
|
DoubleAlign = LongLongAlign = 64;
|
2010-07-21 10:02:56 +08:00
|
|
|
IntMaxType = SignedLongLong;
|
|
|
|
UIntMaxType = UnsignedLongLong;
|
|
|
|
Int64Type = SignedLongLong;
|
2010-09-15 08:28:12 +08:00
|
|
|
SizeType = UnsignedLongLong;
|
|
|
|
PtrDiffType = SignedLongLong;
|
|
|
|
IntPtrType = SignedLongLong;
|
2009-09-23 15:31:35 +08:00
|
|
|
}
|
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
2010-01-10 01:55:51 +08:00
|
|
|
MacroBuilder &Builder) const {
|
2010-10-21 13:21:48 +08:00
|
|
|
WindowsTargetInfo<X86_64TargetInfo>::getTargetDefines(Opts, Builder);
|
|
|
|
Builder.defineMacro("_WIN64");
|
2010-10-21 16:22:51 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
} // end anonymous namespace
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
// x86-64 Windows Visual Studio target
|
|
|
|
class VisualStudioWindowsX86_64TargetInfo : public WindowsX86_64TargetInfo {
|
|
|
|
public:
|
|
|
|
VisualStudioWindowsX86_64TargetInfo(const std::string& triple)
|
|
|
|
: WindowsX86_64TargetInfo(triple) {
|
|
|
|
}
|
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
|
|
|
|
WindowsX86_64TargetInfo::getVisualStudioDefines(Opts, Builder);
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("_M_X64");
|
2010-10-21 13:21:48 +08:00
|
|
|
Builder.defineMacro("_M_AMD64");
|
2009-09-23 15:31:35 +08:00
|
|
|
}
|
2010-09-01 00:44:54 +08:00
|
|
|
virtual const char *getVAListDeclaration() const {
|
|
|
|
return "typedef char* __builtin_va_list;";
|
|
|
|
}
|
2009-09-23 15:31:35 +08:00
|
|
|
};
|
|
|
|
} // end anonymous namespace
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
// x86-64 MinGW target
|
|
|
|
class MinGWX86_64TargetInfo : public WindowsX86_64TargetInfo {
|
|
|
|
public:
|
|
|
|
MinGWX86_64TargetInfo(const std::string& triple)
|
|
|
|
: WindowsX86_64TargetInfo(triple) {
|
|
|
|
}
|
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
2010-01-10 01:55:51 +08:00
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
|
2010-10-21 16:22:51 +08:00
|
|
|
DefineStd(Builder, "WIN64", Opts);
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__MSVCRT__");
|
|
|
|
Builder.defineMacro("__MINGW64__");
|
|
|
|
Builder.defineMacro("__declspec");
|
2009-09-23 15:31:35 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
} // end anonymous namespace
|
|
|
|
|
2009-07-01 11:36:11 +08:00
|
|
|
namespace {
|
|
|
|
class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> {
|
|
|
|
public:
|
2009-09-09 23:08:12 +08:00
|
|
|
DarwinX86_64TargetInfo(const std::string& triple)
|
2009-07-01 11:36:11 +08:00
|
|
|
: DarwinTargetInfo<X86_64TargetInfo>(triple) {
|
|
|
|
Int64Type = SignedLongLong;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
} // end anonymous namespace
|
|
|
|
|
2009-07-06 06:31:18 +08:00
|
|
|
namespace {
|
|
|
|
class OpenBSDX86_64TargetInfo : public OpenBSDTargetInfo<X86_64TargetInfo> {
|
|
|
|
public:
|
2009-09-09 23:08:12 +08:00
|
|
|
OpenBSDX86_64TargetInfo(const std::string& triple)
|
2009-07-06 06:31:18 +08:00
|
|
|
: OpenBSDTargetInfo<X86_64TargetInfo>(triple) {
|
|
|
|
IntMaxType = SignedLongLong;
|
|
|
|
UIntMaxType = UnsignedLongLong;
|
|
|
|
Int64Type = SignedLongLong;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
} // end anonymous namespace
|
|
|
|
|
2008-04-22 02:56:49 +08:00
|
|
|
namespace {
|
2008-08-20 15:44:10 +08:00
|
|
|
class ARMTargetInfo : public TargetInfo {
|
2009-12-22 07:28:17 +08:00
|
|
|
// Possible FPU choices.
|
|
|
|
enum FPUMode {
|
|
|
|
NoFPU,
|
|
|
|
VFP2FPU,
|
|
|
|
VFP3FPU,
|
|
|
|
NeonFPU
|
|
|
|
};
|
|
|
|
|
|
|
|
static bool FPUModeIsVFP(FPUMode Mode) {
|
|
|
|
return Mode >= VFP2FPU && Mode <= NeonFPU;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const TargetInfo::GCCRegAlias GCCRegAliases[];
|
|
|
|
static const char * const GCCRegNames[];
|
2009-09-17 15:03:19 +08:00
|
|
|
|
2009-12-19 02:42:37 +08:00
|
|
|
std::string ABI, CPU;
|
2009-12-22 07:28:17 +08:00
|
|
|
|
|
|
|
unsigned FPU : 3;
|
|
|
|
|
2009-12-19 12:15:38 +08:00
|
|
|
unsigned IsThumb : 1;
|
|
|
|
|
|
|
|
// Initialized via features.
|
|
|
|
unsigned SoftFloat : 1;
|
|
|
|
unsigned SoftFloatABI : 1;
|
2009-09-14 08:35:03 +08:00
|
|
|
|
2010-03-04 03:03:45 +08:00
|
|
|
static const Builtin::Info BuiltinInfo[];
|
|
|
|
|
2008-04-22 02:56:49 +08:00
|
|
|
public:
|
2009-09-18 00:21:10 +08:00
|
|
|
ARMTargetInfo(const std::string &TripleStr)
|
2009-12-19 02:42:37 +08:00
|
|
|
: TargetInfo(TripleStr), ABI("aapcs-linux"), CPU("arm1136j-s")
|
2009-09-14 08:35:03 +08:00
|
|
|
{
|
2009-09-14 08:02:24 +08:00
|
|
|
SizeType = UnsignedInt;
|
|
|
|
PtrDiffType = SignedInt;
|
2009-09-18 00:21:10 +08:00
|
|
|
|
2010-04-24 00:29:58 +08:00
|
|
|
// {} in inline assembly are neon specifiers, not assembly variant
|
|
|
|
// specifiers.
|
|
|
|
NoAsmVariants = true;
|
2010-10-21 11:16:25 +08:00
|
|
|
|
2009-12-19 02:42:37 +08:00
|
|
|
// FIXME: Should we just treat this as a feature?
|
2009-12-19 03:57:13 +08:00
|
|
|
IsThumb = getTriple().getArchName().startswith("thumb");
|
2009-09-23 05:44:58 +08:00
|
|
|
if (IsThumb) {
|
|
|
|
DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
|
|
|
|
"i64:64:64-f32:32:32-f64:64:64-"
|
2009-11-08 02:59:41 +08:00
|
|
|
"v64:64:64-v128:128:128-a0:0:32-n32");
|
2009-09-23 05:44:58 +08:00
|
|
|
} else {
|
|
|
|
DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
|
|
|
|
"i64:64:64-f32:32:32-f64:64:64-"
|
2009-11-08 02:59:41 +08:00
|
|
|
"v64:64:64-v128:128:128-a0:0:64-n32");
|
2009-09-23 05:44:58 +08:00
|
|
|
}
|
2010-08-22 06:46:04 +08:00
|
|
|
|
|
|
|
// ARM targets default to using the ARM C++ ABI.
|
|
|
|
CXXABI = CXXABI_ARM;
|
2008-05-20 22:21:01 +08:00
|
|
|
}
|
2009-09-14 08:35:03 +08:00
|
|
|
virtual const char *getABI() const { return ABI.c_str(); }
|
2009-09-14 08:02:24 +08:00
|
|
|
virtual bool setABI(const std::string &Name) {
|
2009-09-14 08:35:03 +08:00
|
|
|
ABI = Name;
|
|
|
|
|
2009-09-14 08:02:24 +08:00
|
|
|
// The defaults (above) are for AAPCS, check if we need to change them.
|
|
|
|
//
|
|
|
|
// FIXME: We need support for -meabi... we could just mangle it into the
|
|
|
|
// name.
|
|
|
|
if (Name == "apcs-gnu") {
|
2010-01-28 04:23:08 +08:00
|
|
|
DoubleAlign = LongLongAlign = LongDoubleAlign = 32;
|
2009-09-14 08:02:24 +08:00
|
|
|
SizeType = UnsignedLong;
|
|
|
|
|
2010-04-23 00:14:54 +08:00
|
|
|
// Do not respect the alignment of bit-field types when laying out
|
|
|
|
// structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
|
|
|
|
UseBitFieldTypeAlignment = false;
|
|
|
|
|
2009-09-23 05:44:58 +08:00
|
|
|
if (IsThumb) {
|
|
|
|
DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
|
|
|
|
"i64:32:32-f32:32:32-f64:32:32-"
|
2009-11-08 02:59:41 +08:00
|
|
|
"v64:64:64-v128:128:128-a0:0:32-n32");
|
2009-09-23 05:44:58 +08:00
|
|
|
} else {
|
|
|
|
DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
|
|
|
|
"i64:32:32-f32:32:32-f64:32:32-"
|
2009-11-08 02:59:41 +08:00
|
|
|
"v64:64:64-v128:128:128-a0:0:64-n32");
|
2009-09-23 05:44:58 +08:00
|
|
|
}
|
|
|
|
|
2009-09-14 08:02:24 +08:00
|
|
|
// FIXME: Override "preferred align" for double and long long.
|
|
|
|
} else if (Name == "aapcs") {
|
|
|
|
// FIXME: Enumerated types are variable width in straight AAPCS.
|
|
|
|
} else if (Name == "aapcs-linux") {
|
|
|
|
;
|
|
|
|
} else
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2009-12-19 12:15:38 +08:00
|
|
|
|
2009-12-22 07:28:17 +08:00
|
|
|
void getDefaultFeatures(const std::string &CPU,
|
|
|
|
llvm::StringMap<bool> &Features) const {
|
|
|
|
// FIXME: This should not be here.
|
|
|
|
Features["vfp2"] = false;
|
|
|
|
Features["vfp3"] = false;
|
|
|
|
Features["neon"] = false;
|
|
|
|
|
|
|
|
if (CPU == "arm1136jf-s" || CPU == "arm1176jzf-s" || CPU == "mpcore")
|
|
|
|
Features["vfp2"] = true;
|
|
|
|
else if (CPU == "cortex-a8" || CPU == "cortex-a9")
|
|
|
|
Features["neon"] = true;
|
|
|
|
}
|
2010-10-21 11:16:25 +08:00
|
|
|
|
2009-12-19 12:15:38 +08:00
|
|
|
virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
|
|
|
|
const std::string &Name,
|
|
|
|
bool Enabled) const {
|
2009-12-22 07:28:17 +08:00
|
|
|
if (Name == "soft-float" || Name == "soft-float-abi") {
|
|
|
|
Features[Name] = Enabled;
|
|
|
|
} else if (Name == "vfp2" || Name == "vfp3" || Name == "neon") {
|
|
|
|
// These effectively are a single option, reset them when any is enabled.
|
|
|
|
if (Enabled)
|
|
|
|
Features["vfp2"] = Features["vfp3"] = Features["neon"] = false;
|
|
|
|
Features[Name] = Enabled;
|
|
|
|
} else
|
2009-12-19 12:15:38 +08:00
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
|
2009-12-22 07:28:17 +08:00
|
|
|
FPU = NoFPU;
|
2009-12-19 12:15:38 +08:00
|
|
|
SoftFloat = SoftFloatABI = false;
|
|
|
|
for (unsigned i = 0, e = Features.size(); i != e; ++i) {
|
|
|
|
if (Features[i] == "+soft-float")
|
|
|
|
SoftFloat = true;
|
|
|
|
else if (Features[i] == "+soft-float-abi")
|
|
|
|
SoftFloatABI = true;
|
2009-12-22 07:28:17 +08:00
|
|
|
else if (Features[i] == "+vfp2")
|
|
|
|
FPU = VFP2FPU;
|
|
|
|
else if (Features[i] == "+vfp3")
|
|
|
|
FPU = VFP3FPU;
|
|
|
|
else if (Features[i] == "+neon")
|
|
|
|
FPU = NeonFPU;
|
2009-12-19 12:15:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Remove front-end specific options which the backend handles differently.
|
|
|
|
std::vector<std::string>::iterator it;
|
|
|
|
it = std::find(Features.begin(), Features.end(), "+soft-float");
|
|
|
|
if (it != Features.end())
|
|
|
|
Features.erase(it);
|
|
|
|
it = std::find(Features.begin(), Features.end(), "+soft-float-abi");
|
|
|
|
if (it != Features.end())
|
|
|
|
Features.erase(it);
|
|
|
|
}
|
|
|
|
|
2009-12-19 02:42:37 +08:00
|
|
|
static const char *getCPUDefineSuffix(llvm::StringRef Name) {
|
|
|
|
return llvm::StringSwitch<const char*>(Name)
|
|
|
|
.Cases("arm8", "arm810", "4")
|
|
|
|
.Cases("strongarm", "strongarm110", "strongarm1100", "strongarm1110", "4")
|
|
|
|
.Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "arm720t", "arm9", "4T")
|
|
|
|
.Cases("arm9tdmi", "arm920", "arm920t", "arm922t", "arm940t", "4T")
|
|
|
|
.Case("ep9312", "4T")
|
|
|
|
.Cases("arm10tdmi", "arm1020t", "5T")
|
|
|
|
.Cases("arm9e", "arm946e-s", "arm966e-s", "arm968e-s", "5TE")
|
|
|
|
.Case("arm926ej-s", "5TEJ")
|
|
|
|
.Cases("arm10e", "arm1020e", "arm1022e", "5TE")
|
|
|
|
.Cases("xscale", "iwmmxt", "5TE")
|
2009-12-22 07:28:17 +08:00
|
|
|
.Case("arm1136j-s", "6J")
|
2009-12-19 02:42:37 +08:00
|
|
|
.Cases("arm1176jz-s", "arm1176jzf-s", "6ZK")
|
2009-12-22 07:28:17 +08:00
|
|
|
.Cases("arm1136jf-s", "mpcorenovfp", "mpcore", "6K")
|
2009-12-19 02:42:37 +08:00
|
|
|
.Cases("arm1156t2-s", "arm1156t2f-s", "6T2")
|
|
|
|
.Cases("cortex-a8", "cortex-a9", "7A")
|
|
|
|
.Default(0);
|
|
|
|
}
|
|
|
|
virtual bool setCPU(const std::string &Name) {
|
|
|
|
if (!getCPUDefineSuffix(Name))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
CPU = Name;
|
|
|
|
return true;
|
|
|
|
}
|
2009-03-20 23:52:06 +08:00
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
2010-01-10 01:55:51 +08:00
|
|
|
MacroBuilder &Builder) const {
|
2009-03-03 06:27:17 +08:00
|
|
|
// Target identification.
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__arm");
|
|
|
|
Builder.defineMacro("__arm__");
|
2009-05-03 21:42:53 +08:00
|
|
|
|
2009-03-03 06:27:17 +08:00
|
|
|
// Target properties.
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__ARMEL__");
|
|
|
|
Builder.defineMacro("__LITTLE_ENDIAN__");
|
|
|
|
Builder.defineMacro("__REGISTER_PREFIX__", "");
|
2009-12-19 02:42:37 +08:00
|
|
|
|
|
|
|
llvm::StringRef CPUArch = getCPUDefineSuffix(CPU);
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__ARM_ARCH_" + CPUArch + "__");
|
2009-05-03 21:42:53 +08:00
|
|
|
|
2009-04-08 10:07:04 +08:00
|
|
|
// Subtarget options.
|
2009-12-19 02:42:37 +08:00
|
|
|
|
|
|
|
// FIXME: It's more complicated than this and we don't really support
|
|
|
|
// interworking.
|
|
|
|
if ('5' <= CPUArch[0] && CPUArch[0] <= '7')
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__THUMB_INTERWORK__");
|
2009-12-19 02:42:37 +08:00
|
|
|
|
|
|
|
if (ABI == "aapcs" || ABI == "aapcs-linux")
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__ARM_EABI__");
|
2009-12-19 02:42:37 +08:00
|
|
|
|
2009-12-19 12:15:38 +08:00
|
|
|
if (SoftFloat)
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__SOFTFP__");
|
2009-09-18 00:21:10 +08:00
|
|
|
|
2009-12-19 02:42:37 +08:00
|
|
|
if (CPU == "xscale")
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__XSCALE__");
|
2009-09-18 00:21:10 +08:00
|
|
|
|
2009-12-22 07:28:17 +08:00
|
|
|
bool IsThumb2 = IsThumb && (CPUArch == "6T2" || CPUArch.startswith("7"));
|
2009-09-18 00:21:10 +08:00
|
|
|
if (IsThumb) {
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__THUMBEL__");
|
|
|
|
Builder.defineMacro("__thumb__");
|
2009-12-22 07:28:17 +08:00
|
|
|
if (IsThumb2)
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__thumb2__");
|
2009-09-18 00:21:10 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Note, this is always on in gcc, even though it doesn't make sense.
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__APCS_32__");
|
2009-12-22 07:28:17 +08:00
|
|
|
|
|
|
|
if (FPUModeIsVFP((FPUMode) FPU))
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__VFP_FP__");
|
2009-12-22 07:28:17 +08:00
|
|
|
|
|
|
|
// This only gets set when Neon instructions are actually available, unlike
|
|
|
|
// the VFP define, hence the soft float and arch check. This is subtly
|
|
|
|
// different from gcc, we follow the intent which was that it should be set
|
|
|
|
// when Neon instructions are actually available.
|
|
|
|
if (FPU == NeonFPU && !SoftFloat && IsThumb2)
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__ARM_NEON__");
|
2008-04-22 02:56:49 +08:00
|
|
|
}
|
|
|
|
virtual void getTargetBuiltins(const Builtin::Info *&Records,
|
|
|
|
unsigned &NumRecords) const {
|
2010-03-04 03:03:45 +08:00
|
|
|
Records = BuiltinInfo;
|
|
|
|
NumRecords = clang::ARM::LastTSBuiltin-Builtin::FirstTSBuiltin;
|
2008-04-22 02:56:49 +08:00
|
|
|
}
|
|
|
|
virtual const char *getVAListDeclaration() const {
|
2008-08-20 15:44:10 +08:00
|
|
|
return "typedef char* __builtin_va_list;";
|
2008-04-22 02:56:49 +08:00
|
|
|
}
|
2009-05-03 21:42:53 +08:00
|
|
|
virtual void getGCCRegNames(const char * const *&Names,
|
2009-09-17 15:03:19 +08:00
|
|
|
unsigned &NumNames) const;
|
2009-05-03 21:42:53 +08:00
|
|
|
virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
|
2009-09-17 15:03:19 +08:00
|
|
|
unsigned &NumAliases) const;
|
2009-03-01 01:11:49 +08:00
|
|
|
virtual bool validateAsmConstraint(const char *&Name,
|
2009-04-26 15:16:29 +08:00
|
|
|
TargetInfo::ConstraintInfo &Info) const {
|
2008-08-20 15:44:10 +08:00
|
|
|
// FIXME: Check if this is complete
|
2009-03-01 01:11:49 +08:00
|
|
|
switch (*Name) {
|
2008-08-20 15:44:10 +08:00
|
|
|
default:
|
2008-04-22 13:03:19 +08:00
|
|
|
case 'l': // r0-r7
|
|
|
|
case 'h': // r8-r15
|
|
|
|
case 'w': // VFP Floating point register single precision
|
|
|
|
case 'P': // VFP Floating point register double precision
|
2009-04-26 15:16:29 +08:00
|
|
|
Info.setAllowsRegister();
|
2008-04-22 13:03:19 +08:00
|
|
|
return true;
|
|
|
|
}
|
2008-04-22 02:56:49 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
virtual const char *getClobbers() const {
|
2008-08-20 15:44:10 +08:00
|
|
|
// FIXME: Is this really right?
|
2008-04-22 02:56:49 +08:00
|
|
|
return "";
|
|
|
|
}
|
|
|
|
};
|
2009-09-17 15:03:19 +08:00
|
|
|
|
|
|
|
const char * const ARMTargetInfo::GCCRegNames[] = {
|
2010-08-11 10:17:20 +08:00
|
|
|
// Integer registers
|
2009-09-17 15:03:19 +08:00
|
|
|
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
2010-08-11 10:17:20 +08:00
|
|
|
"r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc",
|
|
|
|
|
|
|
|
// Float registers
|
|
|
|
"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
|
|
|
|
"s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15",
|
|
|
|
"s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23",
|
2010-10-28 07:34:42 +08:00
|
|
|
"s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
|
2010-08-11 10:17:20 +08:00
|
|
|
|
2010-10-28 07:34:42 +08:00
|
|
|
// Double registers
|
|
|
|
"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
|
|
|
|
"d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15",
|
2010-10-28 09:05:37 +08:00
|
|
|
"d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23",
|
|
|
|
"d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
|
2010-10-28 07:34:42 +08:00
|
|
|
|
|
|
|
// Quad registers
|
2010-10-28 09:05:37 +08:00
|
|
|
"q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7",
|
|
|
|
"q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
|
2009-09-17 15:03:19 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
void ARMTargetInfo::getGCCRegNames(const char * const *&Names,
|
2010-08-11 10:17:11 +08:00
|
|
|
unsigned &NumNames) const {
|
2009-09-17 15:03:19 +08:00
|
|
|
Names = GCCRegNames;
|
|
|
|
NumNames = llvm::array_lengthof(GCCRegNames);
|
|
|
|
}
|
|
|
|
|
|
|
|
const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
|
|
|
|
{ { "a1" }, "r0" },
|
|
|
|
{ { "a2" }, "r1" },
|
|
|
|
{ { "a3" }, "r2" },
|
|
|
|
{ { "a4" }, "r3" },
|
|
|
|
{ { "v1" }, "r4" },
|
|
|
|
{ { "v2" }, "r5" },
|
|
|
|
{ { "v3" }, "r6" },
|
|
|
|
{ { "v4" }, "r7" },
|
|
|
|
{ { "v5" }, "r8" },
|
|
|
|
{ { "v6", "rfp" }, "r9" },
|
|
|
|
{ { "sl" }, "r10" },
|
|
|
|
{ { "fp" }, "r11" },
|
|
|
|
{ { "ip" }, "r12" },
|
2010-08-11 10:17:11 +08:00
|
|
|
{ { "r13" }, "sp" },
|
|
|
|
{ { "r14" }, "lr" },
|
|
|
|
{ { "r15" }, "pc" },
|
2010-10-28 07:34:42 +08:00
|
|
|
// The S, D and Q registers overlap, but aren't really aliases; we
|
|
|
|
// don't want to substitute one of these for a different-sized one.
|
2009-09-17 15:03:19 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
void ARMTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
|
|
|
|
unsigned &NumAliases) const {
|
|
|
|
Aliases = GCCRegAliases;
|
|
|
|
NumAliases = llvm::array_lengthof(GCCRegAliases);
|
|
|
|
}
|
2010-03-04 03:03:45 +08:00
|
|
|
|
|
|
|
const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
|
2010-12-01 01:35:24 +08:00
|
|
|
#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES, false },
|
|
|
|
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
|
|
|
|
ALL_LANGUAGES, false },
|
2010-03-04 03:03:45 +08:00
|
|
|
#include "clang/Basic/BuiltinsARM.def"
|
|
|
|
};
|
2008-04-22 02:56:49 +08:00
|
|
|
} // end anonymous namespace.
|
|
|
|
|
2008-08-20 15:44:10 +08:00
|
|
|
|
|
|
|
namespace {
|
2009-09-09 23:08:12 +08:00
|
|
|
class DarwinARMTargetInfo :
|
2009-07-01 01:10:35 +08:00
|
|
|
public DarwinTargetInfo<ARMTargetInfo> {
|
|
|
|
protected:
|
2009-08-24 17:10:05 +08:00
|
|
|
virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
2010-01-10 01:55:51 +08:00
|
|
|
MacroBuilder &Builder) const {
|
2010-01-26 09:44:04 +08:00
|
|
|
getDarwinDefines(Builder, Opts, Triple);
|
2008-08-20 15:44:10 +08:00
|
|
|
}
|
|
|
|
|
2009-03-24 00:09:04 +08:00
|
|
|
public:
|
2009-09-09 23:08:12 +08:00
|
|
|
DarwinARMTargetInfo(const std::string& triple)
|
2010-05-27 15:00:26 +08:00
|
|
|
: DarwinTargetInfo<ARMTargetInfo>(triple) {
|
|
|
|
HasAlignMac68kSupport = true;
|
|
|
|
}
|
2009-03-24 00:09:04 +08:00
|
|
|
};
|
2009-07-01 01:10:35 +08:00
|
|
|
} // end anonymous namespace.
|
2009-03-24 00:09:04 +08:00
|
|
|
|
2008-02-22 00:29:08 +08:00
|
|
|
namespace {
|
2008-08-20 15:28:14 +08:00
|
|
|
class SparcV8TargetInfo : public TargetInfo {
|
2009-01-27 09:58:38 +08:00
|
|
|
static const TargetInfo::GCCRegAlias GCCRegAliases[];
|
|
|
|
static const char * const GCCRegNames[];
|
2010-11-10 01:21:19 +08:00
|
|
|
bool SoftFloat;
|
2008-02-22 00:29:08 +08:00
|
|
|
public:
|
2008-08-20 15:28:14 +08:00
|
|
|
SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
|
|
|
|
// FIXME: Support Sparc quad-precision long double?
|
2008-08-21 08:13:15 +08:00
|
|
|
DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
|
2009-11-08 02:59:41 +08:00
|
|
|
"i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
|
2008-08-20 15:28:14 +08:00
|
|
|
}
|
2010-11-10 01:21:19 +08:00
|
|
|
virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
|
|
|
|
const std::string &Name,
|
|
|
|
bool Enabled) const {
|
|
|
|
if (Name == "soft-float")
|
|
|
|
Features[Name] = Enabled;
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
|
|
|
|
SoftFloat = false;
|
|
|
|
for (unsigned i = 0, e = Features.size(); i != e; ++i)
|
|
|
|
if (Features[i] == "+soft-float")
|
|
|
|
SoftFloat = true;
|
|
|
|
}
|
2009-03-20 23:52:06 +08:00
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
2010-01-10 01:55:51 +08:00
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
DefineStd(Builder, "sparc", Opts);
|
|
|
|
Builder.defineMacro("__sparcv8");
|
|
|
|
Builder.defineMacro("__REGISTER_PREFIX__", "");
|
2010-11-10 01:21:19 +08:00
|
|
|
|
|
|
|
if (SoftFloat)
|
|
|
|
Builder.defineMacro("SOFT_FLOAT", "1");
|
2008-02-22 00:29:08 +08:00
|
|
|
}
|
|
|
|
virtual void getTargetBuiltins(const Builtin::Info *&Records,
|
|
|
|
unsigned &NumRecords) const {
|
2008-08-20 15:28:14 +08:00
|
|
|
// FIXME: Implement!
|
2008-02-22 00:29:08 +08:00
|
|
|
}
|
|
|
|
virtual const char *getVAListDeclaration() const {
|
2008-08-20 15:28:14 +08:00
|
|
|
return "typedef void* __builtin_va_list;";
|
2008-02-22 00:29:08 +08:00
|
|
|
}
|
2009-05-03 21:42:53 +08:00
|
|
|
virtual void getGCCRegNames(const char * const *&Names,
|
2009-01-27 09:58:38 +08:00
|
|
|
unsigned &NumNames) const;
|
2009-05-03 21:42:53 +08:00
|
|
|
virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
|
2009-01-27 09:58:38 +08:00
|
|
|
unsigned &NumAliases) const;
|
2009-03-01 01:11:49 +08:00
|
|
|
virtual bool validateAsmConstraint(const char *&Name,
|
2008-02-22 00:29:08 +08:00
|
|
|
TargetInfo::ConstraintInfo &info) const {
|
2008-08-20 15:28:14 +08:00
|
|
|
// FIXME: Implement!
|
|
|
|
return false;
|
2008-02-22 00:29:08 +08:00
|
|
|
}
|
|
|
|
virtual const char *getClobbers() const {
|
2008-08-20 15:28:14 +08:00
|
|
|
// FIXME: Implement!
|
|
|
|
return "";
|
2008-02-22 00:29:08 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2009-01-27 09:58:38 +08:00
|
|
|
const char * const SparcV8TargetInfo::GCCRegNames[] = {
|
|
|
|
"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"
|
|
|
|
};
|
|
|
|
|
2009-05-03 21:42:53 +08:00
|
|
|
void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names,
|
2009-01-27 09:58:38 +08:00
|
|
|
unsigned &NumNames) const {
|
|
|
|
Names = GCCRegNames;
|
|
|
|
NumNames = llvm::array_lengthof(GCCRegNames);
|
|
|
|
}
|
|
|
|
|
|
|
|
const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = {
|
2009-05-03 21:42:53 +08:00
|
|
|
{ { "g0" }, "r0" },
|
|
|
|
{ { "g1" }, "r1" },
|
|
|
|
{ { "g2" }, "r2" },
|
|
|
|
{ { "g3" }, "r3" },
|
|
|
|
{ { "g4" }, "r4" },
|
|
|
|
{ { "g5" }, "r5" },
|
|
|
|
{ { "g6" }, "r6" },
|
|
|
|
{ { "g7" }, "r7" },
|
|
|
|
{ { "o0" }, "r8" },
|
|
|
|
{ { "o1" }, "r9" },
|
|
|
|
{ { "o2" }, "r10" },
|
|
|
|
{ { "o3" }, "r11" },
|
|
|
|
{ { "o4" }, "r12" },
|
|
|
|
{ { "o5" }, "r13" },
|
|
|
|
{ { "o6", "sp" }, "r14" },
|
|
|
|
{ { "o7" }, "r15" },
|
|
|
|
{ { "l0" }, "r16" },
|
|
|
|
{ { "l1" }, "r17" },
|
|
|
|
{ { "l2" }, "r18" },
|
|
|
|
{ { "l3" }, "r19" },
|
|
|
|
{ { "l4" }, "r20" },
|
|
|
|
{ { "l5" }, "r21" },
|
|
|
|
{ { "l6" }, "r22" },
|
|
|
|
{ { "l7" }, "r23" },
|
|
|
|
{ { "i0" }, "r24" },
|
|
|
|
{ { "i1" }, "r25" },
|
|
|
|
{ { "i2" }, "r26" },
|
|
|
|
{ { "i3" }, "r27" },
|
|
|
|
{ { "i4" }, "r28" },
|
|
|
|
{ { "i5" }, "r29" },
|
|
|
|
{ { "i6", "fp" }, "r30" },
|
|
|
|
{ { "i7" }, "r31" },
|
2009-01-27 09:58:38 +08:00
|
|
|
};
|
|
|
|
|
2009-05-03 21:42:53 +08:00
|
|
|
void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
|
2009-01-27 09:58:38 +08:00
|
|
|
unsigned &NumAliases) const {
|
|
|
|
Aliases = GCCRegAliases;
|
|
|
|
NumAliases = llvm::array_lengthof(GCCRegAliases);
|
|
|
|
}
|
2008-02-22 00:29:08 +08:00
|
|
|
} // end anonymous namespace.
|
|
|
|
|
2008-08-20 15:28:14 +08:00
|
|
|
namespace {
|
2009-10-18 21:33:59 +08:00
|
|
|
class AuroraUXSparcV8TargetInfo : public AuroraUXTargetInfo<SparcV8TargetInfo> {
|
|
|
|
public:
|
|
|
|
AuroraUXSparcV8TargetInfo(const std::string& triple) :
|
|
|
|
AuroraUXTargetInfo<SparcV8TargetInfo>(triple) {
|
|
|
|
SizeType = UnsignedInt;
|
|
|
|
PtrDiffType = SignedInt;
|
|
|
|
}
|
|
|
|
};
|
2009-07-01 01:10:35 +08:00
|
|
|
class SolarisSparcV8TargetInfo : public SolarisTargetInfo<SparcV8TargetInfo> {
|
2008-08-20 15:28:14 +08:00
|
|
|
public:
|
|
|
|
SolarisSparcV8TargetInfo(const std::string& triple) :
|
2009-07-01 01:10:35 +08:00
|
|
|
SolarisTargetInfo<SparcV8TargetInfo>(triple) {
|
2008-11-02 10:43:55 +08:00
|
|
|
SizeType = UnsignedInt;
|
|
|
|
PtrDiffType = SignedInt;
|
2008-08-20 15:28:14 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
} // end anonymous namespace.
|
2006-10-14 15:39:34 +08:00
|
|
|
|
2009-05-03 21:43:08 +08:00
|
|
|
namespace {
|
|
|
|
class MSP430TargetInfo : public TargetInfo {
|
|
|
|
static const char * const GCCRegNames[];
|
|
|
|
public:
|
|
|
|
MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) {
|
|
|
|
TLSSupported = false;
|
2010-01-30 20:55:11 +08:00
|
|
|
IntWidth = 16; IntAlign = 16;
|
|
|
|
LongWidth = 32; LongLongWidth = 64;
|
|
|
|
LongAlign = LongLongAlign = 16;
|
|
|
|
PointerWidth = 16; PointerAlign = 16;
|
2009-05-03 21:43:08 +08:00
|
|
|
SizeType = UnsignedInt;
|
|
|
|
IntMaxType = SignedLong;
|
|
|
|
UIntMaxType = UnsignedLong;
|
|
|
|
IntPtrType = SignedShort;
|
|
|
|
PtrDiffType = SignedInt;
|
2009-11-21 08:49:54 +08:00
|
|
|
SigAtomicType = SignedLong;
|
2009-12-19 09:32:37 +08:00
|
|
|
DescriptionString = "e-p:16:16:16-i8:8:8-i16:16:16-i32:16:32-n8:16";
|
2009-05-03 21:43:08 +08:00
|
|
|
}
|
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
2010-01-10 01:55:51 +08:00
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
Builder.defineMacro("MSP430");
|
|
|
|
Builder.defineMacro("__MSP430__");
|
2009-05-03 21:43:08 +08:00
|
|
|
// FIXME: defines for different 'flavours' of MCU
|
|
|
|
}
|
|
|
|
virtual void getTargetBuiltins(const Builtin::Info *&Records,
|
|
|
|
unsigned &NumRecords) const {
|
|
|
|
// FIXME: Implement.
|
|
|
|
Records = 0;
|
|
|
|
NumRecords = 0;
|
|
|
|
}
|
|
|
|
virtual void getGCCRegNames(const char * const *&Names,
|
|
|
|
unsigned &NumNames) const;
|
|
|
|
virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
|
|
|
|
unsigned &NumAliases) const {
|
|
|
|
// No aliases.
|
|
|
|
Aliases = 0;
|
|
|
|
NumAliases = 0;
|
|
|
|
}
|
|
|
|
virtual bool validateAsmConstraint(const char *&Name,
|
|
|
|
TargetInfo::ConstraintInfo &info) const {
|
2009-10-16 07:17:13 +08:00
|
|
|
// No target constraints for now.
|
|
|
|
return false;
|
2009-05-03 21:43:08 +08:00
|
|
|
}
|
|
|
|
virtual const char *getClobbers() const {
|
|
|
|
// FIXME: Is this really right?
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
virtual const char *getVAListDeclaration() const {
|
|
|
|
// FIXME: implement
|
2009-05-09 02:24:57 +08:00
|
|
|
return "typedef char* __builtin_va_list;";
|
2009-05-03 21:43:08 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const char * const MSP430TargetInfo::GCCRegNames[] = {
|
|
|
|
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
|
|
|
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
|
|
|
|
};
|
|
|
|
|
|
|
|
void MSP430TargetInfo::getGCCRegNames(const char * const *&Names,
|
|
|
|
unsigned &NumNames) const {
|
|
|
|
Names = GCCRegNames;
|
|
|
|
NumNames = llvm::array_lengthof(GCCRegNames);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-07-17 04:09:57 +08:00
|
|
|
namespace {
|
|
|
|
class SystemZTargetInfo : public TargetInfo {
|
|
|
|
static const char * const GCCRegNames[];
|
|
|
|
public:
|
|
|
|
SystemZTargetInfo(const std::string& triple) : TargetInfo(triple) {
|
|
|
|
TLSSupported = false;
|
|
|
|
IntWidth = IntAlign = 32;
|
|
|
|
LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64;
|
|
|
|
PointerWidth = PointerAlign = 64;
|
2009-11-08 02:59:41 +08:00
|
|
|
DescriptionString = "E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-"
|
|
|
|
"i64:64:64-f32:32:32-f64:64:64-f128:128:128-a0:16:16-n32:64";
|
2009-07-17 04:09:57 +08:00
|
|
|
}
|
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
2010-01-10 01:55:51 +08:00
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
Builder.defineMacro("__s390__");
|
|
|
|
Builder.defineMacro("__s390x__");
|
2009-07-17 04:09:57 +08:00
|
|
|
}
|
|
|
|
virtual void getTargetBuiltins(const Builtin::Info *&Records,
|
|
|
|
unsigned &NumRecords) const {
|
|
|
|
// FIXME: Implement.
|
|
|
|
Records = 0;
|
|
|
|
NumRecords = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void getGCCRegNames(const char * const *&Names,
|
|
|
|
unsigned &NumNames) const;
|
|
|
|
virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
|
|
|
|
unsigned &NumAliases) const {
|
|
|
|
// No aliases.
|
|
|
|
Aliases = 0;
|
|
|
|
NumAliases = 0;
|
|
|
|
}
|
|
|
|
virtual bool validateAsmConstraint(const char *&Name,
|
|
|
|
TargetInfo::ConstraintInfo &info) const {
|
|
|
|
// FIXME: implement
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
virtual const char *getClobbers() const {
|
|
|
|
// FIXME: Is this really right?
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
virtual const char *getVAListDeclaration() const {
|
|
|
|
// FIXME: implement
|
|
|
|
return "typedef char* __builtin_va_list;";
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const char * const SystemZTargetInfo::GCCRegNames[] = {
|
|
|
|
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
|
|
|
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
|
|
|
|
};
|
|
|
|
|
|
|
|
void SystemZTargetInfo::getGCCRegNames(const char * const *&Names,
|
|
|
|
unsigned &NumNames) const {
|
|
|
|
Names = GCCRegNames;
|
|
|
|
NumNames = llvm::array_lengthof(GCCRegNames);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-08-18 04:08:44 +08:00
|
|
|
namespace {
|
|
|
|
class BlackfinTargetInfo : public TargetInfo {
|
|
|
|
static const char * const GCCRegNames[];
|
|
|
|
public:
|
|
|
|
BlackfinTargetInfo(const std::string& triple) : TargetInfo(triple) {
|
|
|
|
TLSSupported = false;
|
|
|
|
DoubleAlign = 32;
|
|
|
|
LongLongAlign = 32;
|
|
|
|
LongDoubleAlign = 32;
|
2009-11-08 02:59:41 +08:00
|
|
|
DescriptionString = "e-p:32:32-i64:32-f64:32-n32";
|
2009-08-18 04:08:44 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
2010-01-10 01:55:51 +08:00
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
DefineStd(Builder, "bfin", Opts);
|
|
|
|
DefineStd(Builder, "BFIN", Opts);
|
|
|
|
Builder.defineMacro("__ADSPBLACKFIN__");
|
2009-08-18 04:08:44 +08:00
|
|
|
// FIXME: This one is really dependent on -mcpu
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__ADSPLPBLACKFIN__");
|
2009-08-18 04:08:44 +08:00
|
|
|
// FIXME: Add cpu-dependent defines and __SILICON_REVISION__
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void getTargetBuiltins(const Builtin::Info *&Records,
|
|
|
|
unsigned &NumRecords) const {
|
|
|
|
// FIXME: Implement.
|
|
|
|
Records = 0;
|
|
|
|
NumRecords = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void getGCCRegNames(const char * const *&Names,
|
|
|
|
unsigned &NumNames) const;
|
|
|
|
|
|
|
|
virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
|
|
|
|
unsigned &NumAliases) const {
|
|
|
|
// No aliases.
|
|
|
|
Aliases = 0;
|
|
|
|
NumAliases = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual bool validateAsmConstraint(const char *&Name,
|
|
|
|
TargetInfo::ConstraintInfo &Info) const {
|
|
|
|
if (strchr("adzDWeABbvfcCtukxywZY", Name[0])) {
|
|
|
|
Info.setAllowsRegister();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual const char *getClobbers() const {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual const char *getVAListDeclaration() const {
|
|
|
|
return "typedef char* __builtin_va_list;";
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const char * const BlackfinTargetInfo::GCCRegNames[] = {
|
|
|
|
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
|
|
|
"p0", "p1", "p2", "p3", "p4", "p5", "sp", "fp",
|
|
|
|
"i0", "i1", "i2", "i3", "b0", "b1", "b2", "b3",
|
|
|
|
"l0", "l1", "l2", "l3", "m0", "m1", "m2", "m3",
|
|
|
|
"a0", "a1", "cc",
|
|
|
|
"rets", "reti", "retx", "retn", "rete", "astat", "seqstat", "usp",
|
|
|
|
"argp", "lt0", "lt1", "lc0", "lc1", "lb0", "lb1"
|
|
|
|
};
|
|
|
|
|
|
|
|
void BlackfinTargetInfo::getGCCRegNames(const char * const *&Names,
|
|
|
|
unsigned &NumNames) const {
|
|
|
|
Names = GCCRegNames;
|
|
|
|
NumNames = llvm::array_lengthof(GCCRegNames);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-08-20 04:47:07 +08:00
|
|
|
namespace {
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
// LLVM and Clang cannot be used directly to output native binaries for
|
|
|
|
// target, but is used to compile C code to llvm bitcode with correct
|
2009-08-20 04:47:07 +08:00
|
|
|
// type and alignment information.
|
2009-09-09 23:08:12 +08:00
|
|
|
//
|
|
|
|
// TCE uses the llvm bitcode as input and uses it for generating customized
|
|
|
|
// target processor and program binary. TCE co-design environment is
|
2009-08-20 04:47:07 +08:00
|
|
|
// publicly available in http://tce.cs.tut.fi
|
|
|
|
|
|
|
|
class TCETargetInfo : public TargetInfo{
|
|
|
|
public:
|
|
|
|
TCETargetInfo(const std::string& triple) : TargetInfo(triple) {
|
|
|
|
TLSSupported = false;
|
|
|
|
IntWidth = 32;
|
|
|
|
LongWidth = LongLongWidth = 32;
|
|
|
|
PointerWidth = 32;
|
|
|
|
IntAlign = 32;
|
|
|
|
LongAlign = LongLongAlign = 32;
|
|
|
|
PointerAlign = 32;
|
|
|
|
SizeType = UnsignedInt;
|
|
|
|
IntMaxType = SignedLong;
|
|
|
|
UIntMaxType = UnsignedLong;
|
|
|
|
IntPtrType = SignedInt;
|
|
|
|
PtrDiffType = SignedInt;
|
|
|
|
FloatWidth = 32;
|
|
|
|
FloatAlign = 32;
|
|
|
|
DoubleWidth = 32;
|
|
|
|
DoubleAlign = 32;
|
|
|
|
LongDoubleWidth = 32;
|
|
|
|
LongDoubleAlign = 32;
|
|
|
|
FloatFormat = &llvm::APFloat::IEEEsingle;
|
|
|
|
DoubleFormat = &llvm::APFloat::IEEEsingle;
|
|
|
|
LongDoubleFormat = &llvm::APFloat::IEEEsingle;
|
2010-03-05 05:07:38 +08:00
|
|
|
DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-"
|
|
|
|
"i16:16:32-i32:32:32-i64:32:32-"
|
|
|
|
"f32:32:32-f64:64:64-v64:64:64-"
|
|
|
|
"v128:128:128-a0:0:64-n32";
|
2009-08-20 04:47:07 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
2010-01-10 01:55:51 +08:00
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
DefineStd(Builder, "tce", Opts);
|
|
|
|
Builder.defineMacro("__TCE__");
|
|
|
|
Builder.defineMacro("__TCE_V1__");
|
2009-08-20 04:47:07 +08:00
|
|
|
}
|
|
|
|
virtual void getTargetBuiltins(const Builtin::Info *&Records,
|
|
|
|
unsigned &NumRecords) const {}
|
2009-08-24 17:54:37 +08:00
|
|
|
virtual const char *getClobbers() const {
|
|
|
|
return "";
|
|
|
|
}
|
2009-08-20 04:47:07 +08:00
|
|
|
virtual const char *getVAListDeclaration() const {
|
|
|
|
return "typedef void* __builtin_va_list;";
|
|
|
|
}
|
|
|
|
virtual void getGCCRegNames(const char * const *&Names,
|
|
|
|
unsigned &NumNames) const {}
|
|
|
|
virtual bool validateAsmConstraint(const char *&Name,
|
|
|
|
TargetInfo::ConstraintInfo &info) const {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
|
|
|
|
unsigned &NumAliases) const {}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2009-11-15 18:22:07 +08:00
|
|
|
namespace {
|
|
|
|
class MipsTargetInfo : public TargetInfo {
|
2010-03-02 10:41:08 +08:00
|
|
|
std::string ABI, CPU;
|
2009-11-15 18:22:07 +08:00
|
|
|
static const TargetInfo::GCCRegAlias GCCRegAliases[];
|
|
|
|
static const char * const GCCRegNames[];
|
|
|
|
public:
|
2010-03-02 10:41:08 +08:00
|
|
|
MipsTargetInfo(const std::string& triple) : TargetInfo(triple), ABI("o32") {
|
2009-11-15 18:22:07 +08:00
|
|
|
DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
|
|
|
|
"i64:32:64-f32:32:32-f64:64:64-v64:64:64-n32";
|
|
|
|
}
|
2010-03-02 10:41:08 +08:00
|
|
|
virtual const char *getABI() const { return ABI.c_str(); }
|
|
|
|
virtual bool setABI(const std::string &Name) {
|
|
|
|
|
|
|
|
if ((Name == "o32") || (Name == "eabi")) {
|
|
|
|
ABI = Name;
|
|
|
|
return true;
|
|
|
|
} else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
virtual bool setCPU(const std::string &Name) {
|
|
|
|
CPU = Name;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
void getDefaultFeatures(const std::string &CPU,
|
|
|
|
llvm::StringMap<bool> &Features) const {
|
|
|
|
Features[ABI] = true;
|
|
|
|
Features[CPU] = true;
|
|
|
|
}
|
|
|
|
virtual void getArchDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
if (ABI == "o32")
|
|
|
|
Builder.defineMacro("__mips_o32");
|
|
|
|
else if (ABI == "eabi")
|
|
|
|
Builder.defineMacro("__mips_eabi");
|
|
|
|
}
|
2009-11-15 18:22:07 +08:00
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
2010-01-10 01:55:51 +08:00
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
DefineStd(Builder, "mips", Opts);
|
|
|
|
Builder.defineMacro("_mips");
|
|
|
|
DefineStd(Builder, "MIPSEB", Opts);
|
|
|
|
Builder.defineMacro("_MIPSEB");
|
|
|
|
Builder.defineMacro("__REGISTER_PREFIX__", "");
|
2010-03-02 10:41:08 +08:00
|
|
|
getArchDefines(Opts, Builder);
|
2009-11-15 18:22:07 +08:00
|
|
|
}
|
|
|
|
virtual void getTargetBuiltins(const Builtin::Info *&Records,
|
|
|
|
unsigned &NumRecords) const {
|
|
|
|
// FIXME: Implement!
|
|
|
|
}
|
|
|
|
virtual const char *getVAListDeclaration() const {
|
|
|
|
return "typedef void* __builtin_va_list;";
|
|
|
|
}
|
|
|
|
virtual void getGCCRegNames(const char * const *&Names,
|
|
|
|
unsigned &NumNames) const;
|
|
|
|
virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
|
|
|
|
unsigned &NumAliases) const;
|
|
|
|
virtual bool validateAsmConstraint(const char *&Name,
|
|
|
|
TargetInfo::ConstraintInfo &Info) const {
|
|
|
|
switch (*Name) {
|
|
|
|
default:
|
|
|
|
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.
|
|
|
|
Info.setAllowsRegister();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual const char *getClobbers() const {
|
|
|
|
// FIXME: Implement!
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const char * const MipsTargetInfo::GCCRegNames[] = {
|
2010-10-21 11:16:25 +08:00
|
|
|
"$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
|
2009-11-15 18:22:07 +08:00
|
|
|
"$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
|
|
|
|
"$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
|
|
|
|
"$24", "$25", "$26", "$27", "$28", "$sp", "$fp", "$31",
|
|
|
|
"$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
|
|
|
|
"$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
|
|
|
|
"$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
|
|
|
|
"$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
|
|
|
|
"hi", "lo", "", "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
|
|
|
|
"$fcc5","$fcc6","$fcc7"
|
|
|
|
};
|
|
|
|
|
|
|
|
void MipsTargetInfo::getGCCRegNames(const char * const *&Names,
|
|
|
|
unsigned &NumNames) const {
|
|
|
|
Names = GCCRegNames;
|
|
|
|
NumNames = llvm::array_lengthof(GCCRegNames);
|
|
|
|
}
|
|
|
|
|
|
|
|
const TargetInfo::GCCRegAlias MipsTargetInfo::GCCRegAliases[] = {
|
|
|
|
{ { "at" }, "$1" },
|
|
|
|
{ { "v0" }, "$2" },
|
|
|
|
{ { "v1" }, "$3" },
|
|
|
|
{ { "a0" }, "$4" },
|
|
|
|
{ { "a1" }, "$5" },
|
|
|
|
{ { "a2" }, "$6" },
|
|
|
|
{ { "a3" }, "$7" },
|
|
|
|
{ { "t0" }, "$8" },
|
|
|
|
{ { "t1" }, "$9" },
|
|
|
|
{ { "t2" }, "$10" },
|
|
|
|
{ { "t3" }, "$11" },
|
|
|
|
{ { "t4" }, "$12" },
|
|
|
|
{ { "t5" }, "$13" },
|
|
|
|
{ { "t6" }, "$14" },
|
|
|
|
{ { "t7" }, "$15" },
|
|
|
|
{ { "s0" }, "$16" },
|
|
|
|
{ { "s1" }, "$17" },
|
|
|
|
{ { "s2" }, "$18" },
|
|
|
|
{ { "s3" }, "$19" },
|
|
|
|
{ { "s4" }, "$20" },
|
|
|
|
{ { "s5" }, "$21" },
|
|
|
|
{ { "s6" }, "$22" },
|
|
|
|
{ { "s7" }, "$23" },
|
|
|
|
{ { "t8" }, "$24" },
|
|
|
|
{ { "t9" }, "$25" },
|
|
|
|
{ { "k0" }, "$26" },
|
|
|
|
{ { "k1" }, "$27" },
|
|
|
|
{ { "gp" }, "$28" },
|
|
|
|
{ { "sp" }, "$29" },
|
|
|
|
{ { "fp" }, "$30" },
|
|
|
|
{ { "ra" }, "$31" }
|
|
|
|
};
|
|
|
|
|
|
|
|
void MipsTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
|
|
|
|
unsigned &NumAliases) const {
|
|
|
|
Aliases = GCCRegAliases;
|
|
|
|
NumAliases = llvm::array_lengthof(GCCRegAliases);
|
|
|
|
}
|
|
|
|
} // end anonymous namespace.
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
class MipselTargetInfo : public MipsTargetInfo {
|
|
|
|
public:
|
|
|
|
MipselTargetInfo(const std::string& triple) : MipsTargetInfo(triple) {
|
|
|
|
DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
|
|
|
|
"i64:32:64-f32:32:32-f64:64:64-v64:64:64-n32";
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
2010-01-10 01:55:51 +08:00
|
|
|
MacroBuilder &Builder) const;
|
2009-11-15 18:22:07 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
void MipselTargetInfo::getTargetDefines(const LangOptions &Opts,
|
2010-01-10 01:55:51 +08:00
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
DefineStd(Builder, "mips", Opts);
|
|
|
|
Builder.defineMacro("_mips");
|
|
|
|
DefineStd(Builder, "MIPSEL", Opts);
|
|
|
|
Builder.defineMacro("_MIPSEL");
|
|
|
|
Builder.defineMacro("__REGISTER_PREFIX__", "");
|
2010-03-02 10:41:08 +08:00
|
|
|
getArchDefines(Opts, Builder);
|
2009-11-15 18:22:07 +08:00
|
|
|
}
|
|
|
|
} // end anonymous namespace.
|
|
|
|
|
2006-10-14 15:39:34 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Driver code
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2009-11-15 14:48:46 +08:00
|
|
|
static TargetInfo *AllocateTarget(const std::string &T) {
|
2009-08-18 13:47:58 +08:00
|
|
|
llvm::Triple Triple(T);
|
|
|
|
llvm::Triple::OSType os = Triple.getOS();
|
2008-05-20 22:21:01 +08:00
|
|
|
|
2009-08-18 13:47:58 +08:00
|
|
|
switch (Triple.getArch()) {
|
|
|
|
default:
|
|
|
|
return NULL;
|
2008-05-20 22:21:01 +08:00
|
|
|
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::arm:
|
2009-09-11 09:14:50 +08:00
|
|
|
case llvm::Triple::thumb:
|
2009-08-18 13:47:58 +08:00
|
|
|
switch (os) {
|
2010-06-10 08:46:51 +08:00
|
|
|
case llvm::Triple::Linux:
|
|
|
|
return new LinuxTargetInfo<ARMTargetInfo>(T);
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::Darwin:
|
2008-08-21 08:13:15 +08:00
|
|
|
return new DarwinARMTargetInfo(T);
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::FreeBSD:
|
2009-07-01 01:10:35 +08:00
|
|
|
return new FreeBSDTargetInfo<ARMTargetInfo>(T);
|
2009-08-18 13:47:58 +08:00
|
|
|
default:
|
|
|
|
return new ARMTargetInfo(T);
|
|
|
|
}
|
2008-04-22 02:56:49 +08:00
|
|
|
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::bfin:
|
|
|
|
return new BlackfinTargetInfo(T);
|
2008-05-20 22:21:01 +08:00
|
|
|
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::msp430:
|
|
|
|
return new MSP430TargetInfo(T);
|
2008-05-20 22:21:01 +08:00
|
|
|
|
2009-11-15 18:22:07 +08:00
|
|
|
case llvm::Triple::mips:
|
|
|
|
if (os == llvm::Triple::Psp)
|
|
|
|
return new PSPTargetInfo<MipsTargetInfo>(T);
|
|
|
|
if (os == llvm::Triple::Linux)
|
|
|
|
return new LinuxTargetInfo<MipsTargetInfo>(T);
|
|
|
|
return new MipsTargetInfo(T);
|
|
|
|
|
|
|
|
case llvm::Triple::mipsel:
|
|
|
|
if (os == llvm::Triple::Psp)
|
|
|
|
return new PSPTargetInfo<MipselTargetInfo>(T);
|
|
|
|
if (os == llvm::Triple::Linux)
|
|
|
|
return new LinuxTargetInfo<MipselTargetInfo>(T);
|
|
|
|
return new MipselTargetInfo(T);
|
|
|
|
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::ppc:
|
|
|
|
if (os == llvm::Triple::Darwin)
|
2010-05-30 08:07:30 +08:00
|
|
|
return new DarwinPPCTargetInfo(T);
|
2010-02-17 02:14:57 +08:00
|
|
|
else if (os == llvm::Triple::FreeBSD)
|
|
|
|
return new FreeBSDTargetInfo<PPC32TargetInfo>(T);
|
2009-08-18 13:47:58 +08:00
|
|
|
return new PPC32TargetInfo(T);
|
2009-05-03 21:43:08 +08:00
|
|
|
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::ppc64:
|
|
|
|
if (os == llvm::Triple::Darwin)
|
2010-05-30 08:07:30 +08:00
|
|
|
return new DarwinPPC64TargetInfo(T);
|
2009-11-20 01:18:50 +08:00
|
|
|
else if (os == llvm::Triple::Lv2)
|
|
|
|
return new PS3PPUTargetInfo<PPC64TargetInfo>(T);
|
2010-02-17 02:14:57 +08:00
|
|
|
else if (os == llvm::Triple::FreeBSD)
|
|
|
|
return new FreeBSDTargetInfo<PPC64TargetInfo>(T);
|
2009-08-18 13:47:58 +08:00
|
|
|
return new PPC64TargetInfo(T);
|
2009-07-17 04:09:57 +08:00
|
|
|
|
2010-03-07 05:21:27 +08:00
|
|
|
case llvm::Triple::mblaze:
|
|
|
|
return new MBlazeTargetInfo(T);
|
|
|
|
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::sparc:
|
2009-10-18 21:33:59 +08:00
|
|
|
if (os == llvm::Triple::AuroraUX)
|
|
|
|
return new AuroraUXSparcV8TargetInfo(T);
|
2009-08-18 13:47:58 +08:00
|
|
|
if (os == llvm::Triple::Solaris)
|
|
|
|
return new SolarisSparcV8TargetInfo(T);
|
|
|
|
return new SparcV8TargetInfo(T);
|
2009-08-18 04:08:44 +08:00
|
|
|
|
2009-11-20 01:18:50 +08:00
|
|
|
// FIXME: Need a real SPU target.
|
|
|
|
case llvm::Triple::cellspu:
|
|
|
|
return new PS3SPUTargetInfo<PPC64TargetInfo>(T);
|
|
|
|
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::systemz:
|
|
|
|
return new SystemZTargetInfo(T);
|
|
|
|
|
2009-08-20 04:47:07 +08:00
|
|
|
case llvm::Triple::tce:
|
|
|
|
return new TCETargetInfo(T);
|
|
|
|
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::x86:
|
|
|
|
switch (os) {
|
2009-10-18 21:33:59 +08:00
|
|
|
case llvm::Triple::AuroraUX:
|
|
|
|
return new AuroraUXTargetInfo<X86_32TargetInfo>(T);
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::Darwin:
|
2008-08-21 08:13:15 +08:00
|
|
|
return new DarwinI386TargetInfo(T);
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::Linux:
|
2009-07-01 01:10:35 +08:00
|
|
|
return new LinuxTargetInfo<X86_32TargetInfo>(T);
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::DragonFly:
|
2009-07-01 01:10:35 +08:00
|
|
|
return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(T);
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::NetBSD:
|
2009-07-14 04:29:08 +08:00
|
|
|
return new NetBSDTargetInfo<X86_32TargetInfo>(T);
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::OpenBSD:
|
2009-07-06 02:47:56 +08:00
|
|
|
return new OpenBSDI386TargetInfo(T);
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::FreeBSD:
|
2009-07-01 01:10:35 +08:00
|
|
|
return new FreeBSDTargetInfo<X86_32TargetInfo>(T);
|
2010-07-08 00:01:42 +08:00
|
|
|
case llvm::Triple::Minix:
|
|
|
|
return new MinixTargetInfo<X86_32TargetInfo>(T);
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::Solaris:
|
2009-07-01 01:10:35 +08:00
|
|
|
return new SolarisTargetInfo<X86_32TargetInfo>(T);
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::Cygwin:
|
2009-09-23 15:31:35 +08:00
|
|
|
return new CygwinX86_32TargetInfo(T);
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::MinGW32:
|
2009-09-23 15:31:35 +08:00
|
|
|
return new MinGWX86_32TargetInfo(T);
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::Win32:
|
2010-10-21 16:22:51 +08:00
|
|
|
return new VisualStudioWindowsX86_32TargetInfo(T);
|
2010-04-12 03:29:39 +08:00
|
|
|
case llvm::Triple::Haiku:
|
|
|
|
return new HaikuX86_32TargetInfo(T);
|
2009-08-18 13:47:58 +08:00
|
|
|
default:
|
|
|
|
return new X86_32TargetInfo(T);
|
|
|
|
}
|
2008-05-20 22:21:01 +08:00
|
|
|
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::x86_64:
|
|
|
|
switch (os) {
|
2009-10-18 21:33:59 +08:00
|
|
|
case llvm::Triple::AuroraUX:
|
|
|
|
return new AuroraUXTargetInfo<X86_64TargetInfo>(T);
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::Darwin:
|
|
|
|
return new DarwinX86_64TargetInfo(T);
|
|
|
|
case llvm::Triple::Linux:
|
|
|
|
return new LinuxTargetInfo<X86_64TargetInfo>(T);
|
2010-01-09 13:41:14 +08:00
|
|
|
case llvm::Triple::DragonFly:
|
|
|
|
return new DragonFlyBSDTargetInfo<X86_64TargetInfo>(T);
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::NetBSD:
|
|
|
|
return new NetBSDTargetInfo<X86_64TargetInfo>(T);
|
|
|
|
case llvm::Triple::OpenBSD:
|
|
|
|
return new OpenBSDX86_64TargetInfo(T);
|
|
|
|
case llvm::Triple::FreeBSD:
|
|
|
|
return new FreeBSDTargetInfo<X86_64TargetInfo>(T);
|
|
|
|
case llvm::Triple::Solaris:
|
|
|
|
return new SolarisTargetInfo<X86_64TargetInfo>(T);
|
2009-09-23 15:31:35 +08:00
|
|
|
case llvm::Triple::MinGW64:
|
|
|
|
return new MinGWX86_64TargetInfo(T);
|
|
|
|
case llvm::Triple::Win32: // This is what Triple.h supports now.
|
2010-10-21 16:22:51 +08:00
|
|
|
return new VisualStudioWindowsX86_64TargetInfo(T);
|
2009-08-18 13:47:58 +08:00
|
|
|
default:
|
|
|
|
return new X86_64TargetInfo(T);
|
|
|
|
}
|
|
|
|
}
|
2006-10-14 15:39:34 +08:00
|
|
|
}
|
2009-11-15 14:48:46 +08:00
|
|
|
|
|
|
|
/// CreateTargetInfo - Return the target info object for the specified target
|
|
|
|
/// triple.
|
|
|
|
TargetInfo *TargetInfo::CreateTargetInfo(Diagnostic &Diags,
|
2009-12-19 11:30:57 +08:00
|
|
|
TargetOptions &Opts) {
|
2009-11-15 14:48:46 +08:00
|
|
|
llvm::Triple Triple(Opts.Triple);
|
|
|
|
|
|
|
|
// Construct the target
|
|
|
|
llvm::OwningPtr<TargetInfo> Target(AllocateTarget(Triple.str()));
|
|
|
|
if (!Target) {
|
|
|
|
Diags.Report(diag::err_target_unknown_triple) << Triple.str();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-12-19 02:42:37 +08:00
|
|
|
// Set the target CPU if specified.
|
|
|
|
if (!Opts.CPU.empty() && !Target->setCPU(Opts.CPU)) {
|
|
|
|
Diags.Report(diag::err_target_unknown_cpu) << Opts.CPU;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-11-15 14:48:46 +08:00
|
|
|
// Set the target ABI if specified.
|
|
|
|
if (!Opts.ABI.empty() && !Target->setABI(Opts.ABI)) {
|
|
|
|
Diags.Report(diag::err_target_unknown_abi) << Opts.ABI;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-06-11 09:06:47 +08:00
|
|
|
// Set the target C++ ABI.
|
2010-08-22 06:46:04 +08:00
|
|
|
if (!Opts.CXXABI.empty() && !Target->setCXXABI(Opts.CXXABI)) {
|
2010-06-11 09:06:47 +08:00
|
|
|
Diags.Report(diag::err_target_unknown_cxxabi) << Opts.CXXABI;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-11-15 14:48:46 +08:00
|
|
|
// Compute the default target features, we need the target to handle this
|
|
|
|
// because features may have dependencies on one another.
|
|
|
|
llvm::StringMap<bool> Features;
|
|
|
|
Target->getDefaultFeatures(Opts.CPU, Features);
|
|
|
|
|
|
|
|
// Apply the user specified deltas.
|
|
|
|
for (std::vector<std::string>::const_iterator it = Opts.Features.begin(),
|
|
|
|
ie = Opts.Features.end(); it != ie; ++it) {
|
|
|
|
const char *Name = it->c_str();
|
|
|
|
|
|
|
|
// Apply the feature via the target.
|
|
|
|
if ((Name[0] != '-' && Name[0] != '+') ||
|
|
|
|
!Target->setFeatureEnabled(Features, Name + 1, (Name[0] == '+'))) {
|
|
|
|
Diags.Report(diag::err_target_invalid_feature) << Name;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add the features to the compile options.
|
|
|
|
//
|
|
|
|
// FIXME: If we are completely confident that we have the right set, we only
|
|
|
|
// need to pass the minuses.
|
2009-12-19 11:30:57 +08:00
|
|
|
Opts.Features.clear();
|
2009-11-15 14:48:46 +08:00
|
|
|
for (llvm::StringMap<bool>::const_iterator it = Features.begin(),
|
|
|
|
ie = Features.end(); it != ie; ++it)
|
2009-12-19 11:30:57 +08:00
|
|
|
Opts.Features.push_back(std::string(it->second ? "+" : "-") + it->first());
|
|
|
|
Target->HandleTargetFeatures(Opts.Features);
|
2009-11-15 14:48:46 +08:00
|
|
|
|
|
|
|
return Target.take();
|
|
|
|
}
|