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
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2009-06-14 09:05:48 +08:00
|
|
|
#include "clang/Basic/Builtins.h"
|
|
|
|
#include "clang/Basic/TargetBuiltins.h"
|
2006-10-14 15:39:34 +08:00
|
|
|
#include "clang/Basic/TargetInfo.h"
|
2008-12-05 06:54:33 +08:00
|
|
|
#include "clang/Basic/LangOptions.h"
|
2008-05-20 22:27:34 +08:00
|
|
|
#include "llvm/ADT/APFloat.h"
|
2009-03-21 00:06:38 +08:00
|
|
|
#include "llvm/ADT/SmallString.h"
|
2009-08-12 14:24:27 +08:00
|
|
|
#include "llvm/ADT/STLExtras.h"
|
|
|
|
#include "llvm/ADT/Triple.h"
|
2009-08-11 03:03:04 +08:00
|
|
|
#include "llvm/MC/MCSectionMachO.h"
|
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
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2007-10-06 14:57:34 +08:00
|
|
|
static void Define(std::vector<char> &Buf, const char *Macro,
|
|
|
|
const char *Val = "1") {
|
|
|
|
const char *Def = "#define ";
|
|
|
|
Buf.insert(Buf.end(), Def, Def+strlen(Def));
|
|
|
|
Buf.insert(Buf.end(), Macro, Macro+strlen(Macro));
|
|
|
|
Buf.push_back(' ');
|
|
|
|
Buf.insert(Buf.end(), Val, Val+strlen(Val));
|
|
|
|
Buf.push_back('\n');
|
|
|
|
}
|
|
|
|
|
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.
|
2009-05-03 21:42:53 +08:00
|
|
|
static void DefineStd(std::vector<char> &Buf, const char *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)
|
|
|
|
Define(Buf, MacroName);
|
2009-05-03 21:42:53 +08:00
|
|
|
|
2009-03-21 00:06:38 +08:00
|
|
|
// Define __unix.
|
|
|
|
llvm::SmallString<20> TmpStr;
|
|
|
|
TmpStr = "__";
|
|
|
|
TmpStr += MacroName;
|
|
|
|
Define(Buf, TmpStr.c_str());
|
2009-05-03 21:42:53 +08:00
|
|
|
|
2009-03-21 00:06:38 +08:00
|
|
|
// Define __unix__.
|
|
|
|
TmpStr += "__";
|
|
|
|
Define(Buf, TmpStr.c_str());
|
|
|
|
}
|
|
|
|
|
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:
|
|
|
|
virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
|
|
|
|
std::vector<char> &Defines) const=0;
|
|
|
|
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,
|
|
|
|
std::vector<char> &Defines) const {
|
2009-07-01 23:12:53 +08:00
|
|
|
TgtInfo::getTargetDefines(Opts, Defines);
|
|
|
|
getOSDefines(Opts, TgtInfo::getTargetTriple(), Defines);
|
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
|
|
|
|
2009-04-11 03:52:24 +08:00
|
|
|
static void getDarwinDefines(std::vector<char> &Defs, const LangOptions &Opts) {
|
2009-06-23 08:43:21 +08:00
|
|
|
Define(Defs, "__APPLE_CC__", "5621");
|
2008-08-20 10:34:37 +08:00
|
|
|
Define(Defs, "__APPLE__");
|
|
|
|
Define(Defs, "__MACH__");
|
2009-02-05 15:19:24 +08:00
|
|
|
Define(Defs, "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.
|
|
|
|
Define(Defs, "__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)
|
2009-04-07 12:48:21 +08:00
|
|
|
Define(Defs, "__strong", "");
|
2009-04-08 00:50:40 +08:00
|
|
|
else
|
2009-04-07 12:48:21 +08:00
|
|
|
Define(Defs, "__strong", "__attribute__((objc_gc(strong)))");
|
2009-06-05 07:00:29 +08:00
|
|
|
|
|
|
|
if (Opts.Static)
|
|
|
|
Define(Defs, "__STATIC__");
|
|
|
|
else
|
|
|
|
Define(Defs, "__DYNAMIC__");
|
2009-04-11 03:52:24 +08:00
|
|
|
}
|
|
|
|
|
2009-08-12 14:24:27 +08:00
|
|
|
static void getDarwinOSXDefines(std::vector<char> &Defs, const char *TripleStr){
|
|
|
|
llvm::Triple TheTriple(TripleStr);
|
|
|
|
if (TheTriple.getOS() != llvm::Triple::Darwin)
|
|
|
|
return;
|
|
|
|
|
2008-09-30 09:00:25 +08:00
|
|
|
// Figure out which "darwin number" the target triple is. "darwin9" -> 10.5.
|
2009-04-11 03:52:24 +08:00
|
|
|
unsigned Maj, Min, Rev;
|
2009-08-12 14:24:27 +08:00
|
|
|
TheTriple.getDarwinNumber(Maj, Min, Rev);
|
|
|
|
|
|
|
|
char MacOSXStr[] = "1000";
|
|
|
|
if (Maj >= 4 && Maj <= 13) { // 10.0-10.9
|
|
|
|
// darwin7 -> 1030, darwin8 -> 1040, darwin9 -> 1050, etc.
|
|
|
|
MacOSXStr[2] = '0' + Maj-4;
|
2009-04-11 03:52:24 +08:00
|
|
|
}
|
2009-08-12 14:24:27 +08:00
|
|
|
|
|
|
|
// Handle minor version: 10.4.9 -> darwin8.9 -> "1049"
|
|
|
|
// Cap 10.4.11 -> darwin8.11 -> "1049"
|
|
|
|
MacOSXStr[3] = std::min(Min, 9U)+'0';
|
|
|
|
Define(Defs, "__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", MacOSXStr);
|
2009-04-11 03:52:24 +08:00
|
|
|
}
|
|
|
|
|
2009-05-03 21:42:53 +08:00
|
|
|
static void getDarwinIPhoneOSDefines(std::vector<char> &Defs,
|
2009-08-12 14:24:27 +08:00
|
|
|
const char *TripleStr) {
|
|
|
|
llvm::Triple TheTriple(TripleStr);
|
|
|
|
if (TheTriple.getOS() != llvm::Triple::Darwin)
|
|
|
|
return;
|
|
|
|
|
2009-04-11 03:52:24 +08:00
|
|
|
// Figure out which "darwin number" the target triple is. "darwin9" -> 10.5.
|
|
|
|
unsigned Maj, Min, Rev;
|
2009-08-12 14:24:27 +08:00
|
|
|
TheTriple.getDarwinNumber(Maj, Min, Rev);
|
|
|
|
|
|
|
|
// When targetting iPhone OS, interpret the minor version and
|
|
|
|
// revision as the iPhone OS version
|
|
|
|
char iPhoneOSStr[] = "10000";
|
|
|
|
if (Min >= 2 && Min <= 9) { // iPhone OS 2.0-9.0
|
|
|
|
// darwin9.2.0 -> 20000, darwin9.3.0 -> 30000, etc.
|
|
|
|
iPhoneOSStr[0] = '0' + Min;
|
2008-09-30 09:00:25 +08:00
|
|
|
}
|
2009-08-12 14:24:27 +08:00
|
|
|
|
|
|
|
// Handle minor version: 2.2 -> darwin9.2.2 -> 20200
|
|
|
|
iPhoneOSStr[2] = std::min(Rev, 9U)+'0';
|
|
|
|
Define(Defs, "__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__",
|
|
|
|
iPhoneOSStr);
|
2008-08-20 10:34:37 +08:00
|
|
|
}
|
2006-10-14 15:39:34 +08:00
|
|
|
|
2008-12-05 07:20:07 +08:00
|
|
|
/// GetDarwinLanguageOptions - Set the default language options for darwin.
|
|
|
|
static void GetDarwinLanguageOptions(LangOptions &Opts,
|
2009-08-12 14:24:27 +08:00
|
|
|
const char *TripleStr) {
|
2008-12-05 07:20:07 +08:00
|
|
|
Opts.NeXTRuntime = true;
|
2009-08-12 14:24:27 +08:00
|
|
|
|
|
|
|
llvm::Triple TheTriple(TripleStr);
|
|
|
|
if (TheTriple.getOS() != llvm::Triple::Darwin)
|
2008-12-05 07:20:07 +08:00
|
|
|
return;
|
2009-05-03 21:42:53 +08:00
|
|
|
|
2009-08-12 14:24:27 +08:00
|
|
|
unsigned MajorVersion = TheTriple.getDarwinMajorNumber();
|
|
|
|
|
2009-06-28 15:36:13 +08:00
|
|
|
// Blocks and stack protectors default to on for 10.6 (darwin10) and beyond.
|
2009-08-12 14:24:27 +08:00
|
|
|
if (MajorVersion > 9) {
|
2008-12-05 07:20:07 +08:00
|
|
|
Opts.Blocks = 1;
|
2009-06-29 07:01:01 +08:00
|
|
|
Opts.setStackProtectorMode(LangOptions::SSPOn);
|
2009-06-28 15:36:13 +08:00
|
|
|
}
|
2009-02-25 07:34:44 +08:00
|
|
|
|
2009-06-28 15:36:13 +08:00
|
|
|
// Non-fragile ABI (in 64-bit mode) default to on for 10.5 (darwin9) and
|
|
|
|
// beyond.
|
2009-08-12 14:24:27 +08:00
|
|
|
if (MajorVersion >= 9 && Opts.ObjC1 &&
|
|
|
|
TheTriple.getArch() == llvm::Triple::x86_64)
|
2009-02-25 07:38:42 +08:00
|
|
|
Opts.ObjCNonFragileABI = 1;
|
2008-12-05 07:20:07 +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:
|
|
|
|
virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
|
|
|
|
std::vector<char> &Defines) const {
|
|
|
|
getDarwinDefines(Defines, Opts);
|
|
|
|
getDarwinOSXDefines(Defines, Triple);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// getDefaultLangOptions - Allow the target to specify default settings for
|
|
|
|
/// various language options. These may be overridden by command line
|
|
|
|
/// options.
|
|
|
|
virtual void getDefaultLangOptions(LangOptions &Opts) {
|
|
|
|
TargetInfo::getDefaultLangOptions(Opts);
|
|
|
|
GetDarwinLanguageOptions(Opts, TargetInfo::getTargetTriple());
|
|
|
|
}
|
|
|
|
public:
|
|
|
|
DarwinTargetInfo(const std::string& triple) :
|
|
|
|
OSTargetInfo<Target>(triple) {
|
|
|
|
this->TLSSupported = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual const char *getUnicodeStringSymbolPrefix() const {
|
|
|
|
return "__utf16_string_";
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual const char *getUnicodeStringSection() const {
|
|
|
|
return "__TEXT,__ustring";
|
|
|
|
}
|
2009-08-11 03:03:04 +08:00
|
|
|
|
|
|
|
virtual std::string isValidSectionSpecifier(const llvm::StringRef &SR) const {
|
|
|
|
// Let MCSectionMachO validate this.
|
|
|
|
llvm::StringRef Segment, Section;
|
|
|
|
unsigned TAA, StubSize;
|
|
|
|
return llvm::MCSectionMachO::ParseSectionSpecifier(SR, Segment, Section,
|
|
|
|
TAA, StubSize);
|
|
|
|
}
|
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:
|
|
|
|
virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
|
|
|
|
std::vector<char> &Defs) const {
|
|
|
|
// DragonFly defines; list based off of gcc output
|
|
|
|
Define(Defs, "__DragonFly__");
|
|
|
|
Define(Defs, "__DragonFly_cc_version", "100001");
|
|
|
|
Define(Defs, "__ELF__");
|
|
|
|
Define(Defs, "__KPRINTF_ATTRIBUTE__");
|
|
|
|
Define(Defs, "__tune_i386__");
|
|
|
|
DefineStd(Defs, "unix", Opts);
|
|
|
|
}
|
|
|
|
public:
|
|
|
|
DragonFlyBSDTargetInfo(const std::string &triple)
|
|
|
|
: OSTargetInfo<Target>(triple) {}
|
|
|
|
};
|
|
|
|
|
|
|
|
// FreeBSD Target
|
|
|
|
template<typename Target>
|
|
|
|
class FreeBSDTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
|
|
|
virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
|
|
|
|
std::vector<char> &Defs) const {
|
|
|
|
// FreeBSD defines; list based off of gcc output
|
|
|
|
|
|
|
|
const char *FreeBSD = strstr(Triple, "-freebsd");
|
|
|
|
FreeBSD += strlen("-freebsd");
|
|
|
|
char release[] = "X";
|
|
|
|
release[0] = FreeBSD[0];
|
|
|
|
char version[] = "X00001";
|
|
|
|
version[0] = FreeBSD[0];
|
|
|
|
|
|
|
|
Define(Defs, "__FreeBSD__", release);
|
|
|
|
Define(Defs, "__FreeBSD_cc_version", version);
|
|
|
|
Define(Defs, "__KPRINTF_ATTRIBUTE__");
|
|
|
|
DefineStd(Defs, "unix", Opts);
|
|
|
|
Define(Defs, "__ELF__", "1");
|
|
|
|
}
|
|
|
|
public:
|
|
|
|
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
|
|
|
};
|
|
|
|
|
|
|
|
// Linux target
|
|
|
|
template<typename Target>
|
|
|
|
class LinuxTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
|
|
|
virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
|
|
|
|
std::vector<char> &Defs) const {
|
|
|
|
// Linux defines; list based off of gcc output
|
|
|
|
DefineStd(Defs, "unix", Opts);
|
|
|
|
DefineStd(Defs, "linux", Opts);
|
|
|
|
Define(Defs, "__gnu_linux__");
|
|
|
|
Define(Defs, "__ELF__", "1");
|
|
|
|
}
|
|
|
|
public:
|
|
|
|
LinuxTargetInfo(const std::string& triple)
|
|
|
|
: OSTargetInfo<Target>(triple) {
|
|
|
|
this->UserLabelPrefix = "";
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2009-07-14 04:29:08 +08:00
|
|
|
// NetBSD Target
|
|
|
|
template<typename Target>
|
|
|
|
class NetBSDTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
|
|
|
virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
|
|
|
|
std::vector<char> &Defs) const {
|
|
|
|
// NetBSD defines; list based off of gcc output
|
|
|
|
Define(Defs, "__NetBSD__", "1");
|
|
|
|
Define(Defs, "__unix__", "1");
|
|
|
|
Define(Defs, "__ELF__", "1");
|
|
|
|
}
|
|
|
|
public:
|
|
|
|
NetBSDTargetInfo(const std::string &triple)
|
|
|
|
: OSTargetInfo<Target>(triple) {
|
|
|
|
this->UserLabelPrefix = "";
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2009-07-01 01:10:35 +08:00
|
|
|
// OpenBSD Target
|
|
|
|
template<typename Target>
|
|
|
|
class OpenBSDTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
|
|
|
virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
|
|
|
|
std::vector<char> &Defs) const {
|
|
|
|
// OpenBSD defines; list based off of gcc output
|
|
|
|
|
|
|
|
Define(Defs, "__OpenBSD__", "1");
|
|
|
|
DefineStd(Defs, "unix", Opts);
|
|
|
|
Define(Defs, "__ELF__", "1");
|
|
|
|
}
|
|
|
|
public:
|
|
|
|
OpenBSDTargetInfo(const std::string &triple)
|
|
|
|
: OSTargetInfo<Target>(triple) {}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Solaris target
|
|
|
|
template<typename Target>
|
|
|
|
class SolarisTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
|
|
|
virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
|
|
|
|
std::vector<char> &Defs) const {
|
|
|
|
DefineStd(Defs, "sun", Opts);
|
|
|
|
DefineStd(Defs, "unix", Opts);
|
|
|
|
Define(Defs, "__ELF__");
|
|
|
|
Define(Defs, "__svr4__");
|
|
|
|
Define(Defs, "__SVR4");
|
|
|
|
}
|
|
|
|
public:
|
|
|
|
SolarisTargetInfo(const std::string& triple)
|
|
|
|
: OSTargetInfo<Target>(triple) {
|
|
|
|
this->UserLabelPrefix = "";
|
|
|
|
this->WCharType = this->SignedLong;
|
|
|
|
// FIXME: WIntType should be SignedLong
|
|
|
|
}
|
|
|
|
};
|
|
|
|
} // end anonymous namespace.
|
|
|
|
|
2009-06-08 14:11:14 +08:00
|
|
|
/// GetWindowsLanguageOptions - Set the default language options for Windows.
|
|
|
|
static void GetWindowsLanguageOptions(LangOptions &Opts,
|
|
|
|
const char *Triple) {
|
|
|
|
Opts.Microsoft = true;
|
|
|
|
}
|
2008-12-05 07:20:07 +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,
|
|
|
|
std::vector<char> &Defines) 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
|
|
|
}
|
2008-08-21 07:11:40 +08:00
|
|
|
virtual const char *getTargetPrefix() const {
|
|
|
|
return "ppc";
|
2007-11-27 12:11:28 +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
|
|
|
|
return true;
|
|
|
|
case 'b': // Base register
|
|
|
|
case 'f': // Floating point register
|
2009-04-26 15:16:29 +08:00
|
|
|
Info.setAllowsRegister();
|
2007-11-27 12:11:28 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
2009-06-05 15:05:05 +08:00
|
|
|
virtual void getDefaultLangOptions(LangOptions &Opts) {
|
|
|
|
TargetInfo::getDefaultLangOptions(Opts);
|
|
|
|
Opts.CharIsSigned = false;
|
|
|
|
}
|
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[] = {
|
2009-02-17 05:58:21 +08:00
|
|
|
#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
|
|
|
|
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, 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,
|
|
|
|
std::vector<char> &Defs) const {
|
2009-03-03 06:27:17 +08:00
|
|
|
// Target identification.
|
|
|
|
Define(Defs, "__ppc__");
|
|
|
|
Define(Defs, "_ARCH_PPC");
|
|
|
|
Define(Defs, "__POWERPC__");
|
|
|
|
if (PointerWidth == 64) {
|
|
|
|
Define(Defs, "_ARCH_PPC64");
|
|
|
|
Define(Defs, "_LP64");
|
|
|
|
Define(Defs, "__LP64__");
|
|
|
|
Define(Defs, "__ppc64__");
|
|
|
|
} else {
|
|
|
|
Define(Defs, "__ppc__");
|
|
|
|
}
|
2009-05-03 21:42:53 +08:00
|
|
|
|
2009-03-03 06:27:17 +08:00
|
|
|
// Target properties.
|
|
|
|
Define(Defs, "_BIG_ENDIAN");
|
|
|
|
Define(Defs, "__BIG_ENDIAN__");
|
2009-05-03 21:42:53 +08:00
|
|
|
|
2009-03-03 06:27:17 +08:00
|
|
|
// Subtarget options.
|
|
|
|
Define(Defs, "__NATURAL_ALIGNMENT__");
|
|
|
|
Define(Defs, "__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.
|
|
|
|
Define(Defs, "__LONG_DOUBLE_128__");
|
|
|
|
}
|
|
|
|
|
2008-04-22 02:56:49 +08:00
|
|
|
|
2008-08-21 07:11:40 +08:00
|
|
|
const char * const PPCTargetInfo::GCCRegNames[] = {
|
|
|
|
"0", "1", "2", "3", "4", "5", "6", "7",
|
|
|
|
"8", "9", "10", "11", "12", "13", "14", "15",
|
|
|
|
"16", "17", "18", "19", "20", "21", "22", "23",
|
|
|
|
"24", "25", "26", "27", "28", "29", "30", "31",
|
|
|
|
"0", "1", "2", "3", "4", "5", "6", "7",
|
|
|
|
"8", "9", "10", "11", "12", "13", "14", "15",
|
|
|
|
"16", "17", "18", "19", "20", "21", "22", "23",
|
|
|
|
"24", "25", "26", "27", "28", "29", "30", "31",
|
|
|
|
"mq", "lr", "ctr", "ap",
|
|
|
|
"0", "1", "2", "3", "4", "5", "6", "7",
|
|
|
|
"xer",
|
|
|
|
"0", "1", "2", "3", "4", "5", "6", "7",
|
|
|
|
"8", "9", "10", "11", "12", "13", "14", "15",
|
|
|
|
"16", "17", "18", "19", "20", "21", "22", "23",
|
|
|
|
"24", "25", "26", "27", "28", "29", "30", "31",
|
|
|
|
"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-05-03 21:42:53 +08:00
|
|
|
{ { "cc", "cr0", "fr0", "r0", "v0"}, "0" },
|
|
|
|
{ { "cr1", "fr1", "r1", "sp", "v1"}, "1" },
|
|
|
|
{ { "cr2", "fr2", "r2", "toc", "v2"}, "2" },
|
|
|
|
{ { "cr3", "fr3", "r3", "v3"}, "3" },
|
|
|
|
{ { "cr4", "fr4", "r4", "v4"}, "4" },
|
|
|
|
{ { "cr5", "fr5", "r5", "v5"}, "5" },
|
|
|
|
{ { "cr6", "fr6", "r6", "v6"}, "6" },
|
|
|
|
{ { "cr7", "fr7", "r7", "v7"}, "7" },
|
|
|
|
{ { "fr8", "r8", "v8"}, "8" },
|
|
|
|
{ { "fr9", "r9", "v9"}, "9" },
|
|
|
|
{ { "fr10", "r10", "v10"}, "10" },
|
|
|
|
{ { "fr11", "r11", "v11"}, "11" },
|
|
|
|
{ { "fr12", "r12", "v12"}, "12" },
|
|
|
|
{ { "fr13", "r13", "v13"}, "13" },
|
|
|
|
{ { "fr14", "r14", "v14"}, "14" },
|
|
|
|
{ { "fr15", "r15", "v15"}, "15" },
|
|
|
|
{ { "fr16", "r16", "v16"}, "16" },
|
|
|
|
{ { "fr17", "r17", "v17"}, "17" },
|
|
|
|
{ { "fr18", "r18", "v18"}, "18" },
|
|
|
|
{ { "fr19", "r19", "v19"}, "19" },
|
|
|
|
{ { "fr20", "r20", "v20"}, "20" },
|
|
|
|
{ { "fr21", "r21", "v21"}, "21" },
|
|
|
|
{ { "fr22", "r22", "v22"}, "22" },
|
|
|
|
{ { "fr23", "r23", "v23"}, "23" },
|
|
|
|
{ { "fr24", "r24", "v24"}, "24" },
|
|
|
|
{ { "fr25", "r25", "v25"}, "25" },
|
|
|
|
{ { "fr26", "r26", "v26"}, "26" },
|
|
|
|
{ { "fr27", "r27", "v27"}, "27" },
|
|
|
|
{ { "fr28", "r28", "v28"}, "28" },
|
|
|
|
{ { "fr29", "r29", "v29"}, "29" },
|
|
|
|
{ { "fr30", "r30", "v30"}, "30" },
|
|
|
|
{ { "fr31", "r31", "v31"}, "31" },
|
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:
|
2008-08-21 08:13:15 +08:00
|
|
|
PPC32TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
|
|
|
|
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";
|
|
|
|
}
|
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-"
|
|
|
|
"i64:64:64-f32:32:32-f64:64:64-v128:128:128";
|
2008-05-09 14:17:04 +08:00
|
|
|
}
|
2008-08-21 07:11:40 +08:00
|
|
|
};
|
|
|
|
} // 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[] = {
|
2009-02-17 05:58:21 +08:00
|
|
|
#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
|
|
|
|
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
|
2009-06-14 09:05:48 +08:00
|
|
|
#include "clang/Basic/BuiltinsX86.def"
|
2008-08-20 10:34:37 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
const char *GCCRegNames[] = {
|
|
|
|
"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;
|
2006-10-14 15:39:34 +08:00
|
|
|
public:
|
2009-05-03 21:42:53 +08:00
|
|
|
X86TargetInfo(const std::string& triple)
|
2009-05-06 11:16:41 +08:00
|
|
|
: TargetInfo(triple), SSELevel(NoMMXSSE) {
|
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
|
|
|
}
|
2007-12-09 03:32:57 +08:00
|
|
|
virtual const char *getTargetPrefix() const {
|
2008-08-20 10:34:37 +08:00
|
|
|
return "x86";
|
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;
|
|
|
|
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,
|
|
|
|
std::vector<char> &Defines) const;
|
2009-05-07 05:07:50 +08:00
|
|
|
virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
|
|
|
|
const std::string &Name,
|
|
|
|
bool Enabled) const;
|
2009-05-06 11:16:41 +08:00
|
|
|
virtual void 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
|
|
|
virtual void HandleTargetFeatures(const llvm::StringMap<bool> &Features);
|
2008-08-20 10:34:37 +08:00
|
|
|
};
|
2009-03-03 06:20:04 +08:00
|
|
|
|
2009-05-06 11:16:41 +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;
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
else if (CPU == "corei7")
|
|
|
|
setFeatureEnabled(Features, "sse4", true);
|
|
|
|
else if (CPU == "k6" || CPU == "winchip-c6")
|
|
|
|
setFeatureEnabled(Features, "mmx", true);
|
|
|
|
else if (CPU == "k6-2" || CPU == "k6-3" || CPU == "athlon" ||
|
|
|
|
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") {
|
|
|
|
setFeatureEnabled(Features, "sse2", true);
|
|
|
|
setFeatureEnabled(Features, "3dnowa", true);
|
|
|
|
} 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,
|
|
|
|
const std::string &Name,
|
|
|
|
bool Enabled) const {
|
|
|
|
// FIXME: This *really* should not be here.
|
|
|
|
if (!Features.count(Name) && Name != "sse4")
|
|
|
|
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")
|
|
|
|
Features["mmx"] = Features["sse"] = Features["sse2"] =
|
|
|
|
Features["sse3"] = true;
|
|
|
|
else if (Name == "ssse3")
|
|
|
|
Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
|
|
|
|
Features["ssse3"] = true;
|
|
|
|
else if (Name == "sse4")
|
|
|
|
Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
|
|
|
|
Features["ssse3"] = Features["sse41"] = Features["sse42"] = true;
|
|
|
|
else if (Name == "3dnow")
|
|
|
|
Features["3dnowa"] = true;
|
|
|
|
else if (Name == "3dnowa")
|
|
|
|
Features["3dnow"] = Features["3dnowa"] = true;
|
|
|
|
} else {
|
|
|
|
if (Name == "mmx")
|
|
|
|
Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
|
|
|
|
Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
|
|
|
|
else if (Name == "sse")
|
|
|
|
Features["sse"] = Features["sse2"] = Features["sse3"] =
|
|
|
|
Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
|
|
|
|
else if (Name == "sse2")
|
|
|
|
Features["sse2"] = Features["sse3"] = Features["ssse3"] =
|
|
|
|
Features["sse41"] = Features["sse42"] = false;
|
|
|
|
else if (Name == "sse3")
|
|
|
|
Features["sse3"] = Features["ssse3"] = Features["sse41"] =
|
|
|
|
Features["sse42"] = false;
|
|
|
|
else if (Name == "ssse3")
|
|
|
|
Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
|
|
|
|
else if (Name == "sse4")
|
|
|
|
Features["sse41"] = Features["sse42"] = false;
|
|
|
|
else if (Name == "3dnow")
|
|
|
|
Features["3dnow"] = Features["3dnowa"] = false;
|
|
|
|
else if (Name == "3dnowa")
|
|
|
|
Features["3dnowa"] = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2009-05-06 11:16:41 +08:00
|
|
|
/// HandleTargetOptions - Perform initialization based on the user
|
|
|
|
/// configured set of features.
|
|
|
|
void X86TargetInfo::HandleTargetFeatures(const llvm::StringMap<bool>&Features) {
|
|
|
|
if (Features.lookup("sse42"))
|
|
|
|
SSELevel = SSE42;
|
|
|
|
else if (Features.lookup("sse41"))
|
|
|
|
SSELevel = SSE41;
|
|
|
|
else if (Features.lookup("ssse3"))
|
|
|
|
SSELevel = SSSE3;
|
|
|
|
else if (Features.lookup("sse3"))
|
|
|
|
SSELevel = SSE3;
|
|
|
|
else if (Features.lookup("sse2"))
|
|
|
|
SSELevel = SSE2;
|
|
|
|
else if (Features.lookup("sse"))
|
|
|
|
SSELevel = SSE1;
|
|
|
|
else if (Features.lookup("mmx"))
|
|
|
|
SSELevel = MMX;
|
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,
|
|
|
|
std::vector<char> &Defs) const {
|
2009-03-03 06:27:17 +08:00
|
|
|
// Target identification.
|
|
|
|
if (PointerWidth == 64) {
|
|
|
|
Define(Defs, "_LP64");
|
|
|
|
Define(Defs, "__LP64__");
|
|
|
|
Define(Defs, "__amd64__");
|
|
|
|
Define(Defs, "__amd64");
|
|
|
|
Define(Defs, "__x86_64");
|
|
|
|
Define(Defs, "__x86_64__");
|
|
|
|
} else {
|
2009-03-21 00:06:38 +08:00
|
|
|
DefineStd(Defs, "i386", Opts);
|
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.
|
|
|
|
Define(Defs, "__LITTLE_ENDIAN__");
|
2009-05-03 21:42:53 +08:00
|
|
|
|
2009-03-03 06:27:17 +08:00
|
|
|
// Subtarget options.
|
|
|
|
Define(Defs, "__nocona");
|
|
|
|
Define(Defs, "__nocona__");
|
|
|
|
Define(Defs, "__tune_nocona__");
|
|
|
|
Define(Defs, "__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).
|
|
|
|
Define(Defs, "__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:
|
|
|
|
Define(Defs, "__SSE4_2__");
|
|
|
|
case SSE41:
|
|
|
|
Define(Defs, "__SSE4_1__");
|
|
|
|
case SSSE3:
|
|
|
|
Define(Defs, "__SSSE3__");
|
|
|
|
case SSE3:
|
|
|
|
Define(Defs, "__SSE3__");
|
|
|
|
case SSE2:
|
|
|
|
Define(Defs, "__SSE2__");
|
|
|
|
Define(Defs, "__SSE2_MATH__"); // -mfp-math=sse always implied.
|
|
|
|
case SSE1:
|
|
|
|
Define(Defs, "__SSE__");
|
|
|
|
Define(Defs, "__SSE_MATH__"); // -mfp-math=sse always implied.
|
|
|
|
case MMX:
|
|
|
|
Define(Defs, "__MMX__");
|
|
|
|
case NoMMXSSE:
|
|
|
|
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;
|
|
|
|
case 'a': // eax.
|
|
|
|
case 'b': // ebx.
|
|
|
|
case 'c': // ecx.
|
|
|
|
case 'd': // edx.
|
|
|
|
case 'S': // esi.
|
|
|
|
case 'D': // edi.
|
|
|
|
case 'A': // edx:eax.
|
|
|
|
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.
|
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
|
|
|
case 'N': // unsigned 8-bit integer constant for use with in and out
|
|
|
|
// instructions.
|
2009-06-09 04:45:44 +08:00
|
|
|
case 'R': // "legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
|
2009-04-26 15:16:29 +08:00
|
|
|
Info.setAllowsRegister();
|
2008-08-20 10:34:37 +08:00
|
|
|
return true;
|
2007-11-27 12:11:28 +08:00
|
|
|
}
|
2008-08-20 10:34:37 +08:00
|
|
|
}
|
2008-02-27 02:33:46 +08:00
|
|
|
|
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}");
|
|
|
|
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-"
|
|
|
|
"a0:0:64-f80:32: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;
|
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
|
|
|
}
|
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-"
|
|
|
|
"a0:0:64-f80:128:128";
|
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
|
|
|
|
class WindowsX86_32TargetInfo : public X86_32TargetInfo {
|
|
|
|
public:
|
|
|
|
WindowsX86_32TargetInfo(const std::string& triple)
|
|
|
|
: 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-08 14:11:14 +08:00
|
|
|
WCharWidth = WCharAlign = 16;
|
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-"
|
|
|
|
"i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
|
|
|
|
"a0:0:64-f80:32: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
|
|
|
}
|
2009-03-20 23:52:06 +08:00
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
|
|
|
std::vector<char> &Defines) const {
|
|
|
|
X86_32TargetInfo::getTargetDefines(Opts, Defines);
|
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
|
|
|
// This list is based off of the the list of things MingW defines
|
|
|
|
Define(Defines, "_WIN32");
|
2009-03-21 00:06:38 +08:00
|
|
|
DefineStd(Defines, "WIN32", Opts);
|
|
|
|
DefineStd(Defines, "WINNT", Opts);
|
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
|
|
|
Define(Defines, "_X86_");
|
|
|
|
Define(Defines, "__MSVCRT__");
|
|
|
|
}
|
2009-06-08 14:11:14 +08:00
|
|
|
|
|
|
|
virtual void getDefaultLangOptions(LangOptions &Opts) {
|
|
|
|
X86_32TargetInfo::getDefaultLangOptions(Opts);
|
|
|
|
GetWindowsLanguageOptions(Opts, getTargetTriple());
|
|
|
|
}
|
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
|
|
|
|
|
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;
|
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-06-09 06:39:13 +08:00
|
|
|
"a0:0:64-s0:64:64-f80:128:128";
|
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;"
|
2009-07-03 08:45:06 +08:00
|
|
|
"} __va_list_tag;"
|
|
|
|
"typedef __va_list_tag __builtin_va_list[1];";
|
2007-11-25 07:38:12 +08:00
|
|
|
}
|
2008-08-20 10:34:37 +08:00
|
|
|
};
|
|
|
|
} // end anonymous namespace
|
|
|
|
|
2009-07-01 11:36:11 +08:00
|
|
|
namespace {
|
|
|
|
class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> {
|
|
|
|
public:
|
|
|
|
DarwinX86_64TargetInfo(const std::string& triple)
|
|
|
|
: 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:
|
|
|
|
OpenBSDX86_64TargetInfo(const std::string& triple)
|
|
|
|
: 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-04-08 10:07:04 +08:00
|
|
|
enum {
|
|
|
|
Armv4t,
|
|
|
|
Armv5,
|
|
|
|
Armv6,
|
2009-08-05 03:48:52 +08:00
|
|
|
Armv7a,
|
2009-04-08 10:07:04 +08:00
|
|
|
XScale
|
|
|
|
} ArmArch;
|
2008-04-22 02:56:49 +08:00
|
|
|
public:
|
2008-08-20 15:44:10 +08:00
|
|
|
ARMTargetInfo(const std::string& triple) : TargetInfo(triple) {
|
|
|
|
// FIXME: Are the defaults correct for ARM?
|
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:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:64";
|
2009-08-05 03:48:52 +08:00
|
|
|
if (triple.find("armv7-") == 0)
|
|
|
|
ArmArch = Armv7a;
|
|
|
|
else if (triple.find("arm-") == 0 || triple.find("armv6-") == 0)
|
2009-04-08 10:07:04 +08:00
|
|
|
ArmArch = Armv6;
|
2009-04-23 12:22:04 +08:00
|
|
|
else if (triple.find("armv5-") == 0)
|
2009-04-08 10:07:04 +08:00
|
|
|
ArmArch = Armv5;
|
2009-04-23 12:22:04 +08:00
|
|
|
else if (triple.find("armv4t-") == 0)
|
2009-04-08 10:07:04 +08:00
|
|
|
ArmArch = Armv4t;
|
2009-04-23 12:22:04 +08:00
|
|
|
else if (triple.find("xscale-") == 0)
|
2009-04-08 10:07:04 +08:00
|
|
|
ArmArch = XScale;
|
2009-04-23 12:22:04 +08:00
|
|
|
else if (triple.find("armv") == 0) {
|
|
|
|
// FIXME: fuzzy match for other random weird arm triples. This is useful
|
|
|
|
// for the static analyzer and other clients, but probably should be
|
|
|
|
// re-evaluated when codegen is brought up.
|
|
|
|
ArmArch = Armv6;
|
|
|
|
}
|
2008-05-20 22:21:01 +08:00
|
|
|
}
|
2009-03-20 23:52:06 +08:00
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
|
|
|
std::vector<char> &Defs) const {
|
2009-03-03 06:27:17 +08:00
|
|
|
// Target identification.
|
|
|
|
Define(Defs, "__arm");
|
|
|
|
Define(Defs, "__arm__");
|
2009-05-03 21:42:53 +08:00
|
|
|
|
2009-03-03 06:27:17 +08:00
|
|
|
// Target properties.
|
|
|
|
Define(Defs, "__LITTLE_ENDIAN__");
|
2009-05-03 21:42:53 +08:00
|
|
|
|
2009-04-08 10:07:04 +08:00
|
|
|
// Subtarget options.
|
2009-08-05 03:48:52 +08:00
|
|
|
if (ArmArch == Armv7a) {
|
|
|
|
Define(Defs, "__ARM_ARCH_7A__");
|
|
|
|
Define(Defs, "__THUMB_INTERWORK__");
|
|
|
|
} else if (ArmArch == Armv6) {
|
2009-04-08 10:07:04 +08:00
|
|
|
Define(Defs, "__ARM_ARCH_6K__");
|
|
|
|
Define(Defs, "__THUMB_INTERWORK__");
|
|
|
|
} else if (ArmArch == Armv5) {
|
|
|
|
Define(Defs, "__ARM_ARCH_5TEJ__");
|
|
|
|
Define(Defs, "__THUMB_INTERWORK__");
|
|
|
|
Define(Defs, "__SOFTFP__");
|
|
|
|
} else if (ArmArch == Armv4t) {
|
|
|
|
Define(Defs, "__ARM_ARCH_4T__");
|
|
|
|
Define(Defs, "__SOFTFP__");
|
|
|
|
} else if (ArmArch == XScale) {
|
|
|
|
Define(Defs, "__ARM_ARCH_5TE__");
|
|
|
|
Define(Defs, "__XSCALE__");
|
|
|
|
Define(Defs, "__SOFTFP__");
|
|
|
|
}
|
2009-03-03 06:27:17 +08:00
|
|
|
Define(Defs, "__ARMEL__");
|
2009-05-30 03:00:15 +08:00
|
|
|
Define(Defs, "__APCS_32__");
|
|
|
|
Define(Defs, "__VFP_FP__");
|
2008-04-22 02:56:49 +08:00
|
|
|
}
|
|
|
|
virtual void getTargetBuiltins(const Builtin::Info *&Records,
|
|
|
|
unsigned &NumRecords) const {
|
2008-08-20 15:44:10 +08:00
|
|
|
// FIXME: Implement.
|
|
|
|
Records = 0;
|
2008-04-22 02:56:49 +08:00
|
|
|
NumRecords = 0;
|
|
|
|
}
|
|
|
|
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
|
|
|
}
|
|
|
|
virtual const char *getTargetPrefix() const {
|
2008-08-20 15:44:10 +08:00
|
|
|
return "arm";
|
2008-04-22 02:56:49 +08:00
|
|
|
}
|
2009-05-03 21:42:53 +08:00
|
|
|
virtual void getGCCRegNames(const char * const *&Names,
|
2008-04-22 02:56:49 +08:00
|
|
|
unsigned &NumNames) const {
|
2008-08-20 15:44:10 +08:00
|
|
|
// FIXME: Implement.
|
|
|
|
Names = 0;
|
2008-04-22 02:56:49 +08:00
|
|
|
NumNames = 0;
|
|
|
|
}
|
2009-05-03 21:42:53 +08:00
|
|
|
virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
|
2008-04-22 02:56:49 +08:00
|
|
|
unsigned &NumAliases) const {
|
2008-08-20 15:44:10 +08:00
|
|
|
// FIXME: Implement.
|
|
|
|
Aliases = 0;
|
2008-04-22 02:56:49 +08:00
|
|
|
NumAliases = 0;
|
|
|
|
}
|
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 "";
|
|
|
|
}
|
|
|
|
};
|
|
|
|
} // end anonymous namespace.
|
|
|
|
|
2008-08-20 15:44:10 +08:00
|
|
|
|
|
|
|
namespace {
|
2009-07-01 01:10:35 +08:00
|
|
|
class DarwinARMTargetInfo :
|
|
|
|
public DarwinTargetInfo<ARMTargetInfo> {
|
|
|
|
protected:
|
|
|
|
virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
|
|
|
|
std::vector<char> &Defines) const {
|
2009-04-11 03:52:24 +08:00
|
|
|
getDarwinDefines(Defines, Opts);
|
2009-07-01 01:10:35 +08:00
|
|
|
getDarwinIPhoneOSDefines(Defines, Triple);
|
2008-08-20 15:44:10 +08:00
|
|
|
}
|
|
|
|
|
2009-03-24 00:09:04 +08:00
|
|
|
public:
|
2009-07-01 01:10:35 +08:00
|
|
|
DarwinARMTargetInfo(const std::string& triple)
|
|
|
|
: DarwinTargetInfo<ARMTargetInfo>(triple) {}
|
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[];
|
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-"
|
|
|
|
"i64:64:64-f32:32:32-f64:64:64-v64:64:64";
|
2008-08-20 15:28:14 +08:00
|
|
|
}
|
2009-03-20 23:52:06 +08:00
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
|
|
|
std::vector<char> &Defines) const {
|
2009-05-22 09:12:57 +08:00
|
|
|
DefineStd(Defines, "sparc", Opts);
|
2008-02-22 00:29:08 +08:00
|
|
|
Define(Defines, "__sparcv8");
|
2009-05-22 09:12:57 +08:00
|
|
|
Define(Defines, "__REGISTER_PREFIX__", "");
|
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
|
|
|
}
|
|
|
|
virtual const char *getTargetPrefix() const {
|
2008-08-20 15:28:14 +08:00
|
|
|
return "sparc";
|
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-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
|
|
|
|
2008-05-08 13:58:21 +08:00
|
|
|
namespace {
|
|
|
|
class PIC16TargetInfo : public TargetInfo{
|
|
|
|
public:
|
|
|
|
PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) {
|
2009-04-20 05:38:35 +08:00
|
|
|
TLSSupported = false;
|
2008-10-31 17:52:39 +08:00
|
|
|
IntWidth = 16;
|
|
|
|
LongWidth = LongLongWidth = 32;
|
2009-05-17 07:30:57 +08:00
|
|
|
IntMaxTWidth = 32;
|
2008-10-31 17:52:39 +08:00
|
|
|
PointerWidth = 16;
|
|
|
|
IntAlign = 8;
|
|
|
|
LongAlign = LongLongAlign = 8;
|
2008-05-20 22:21:01 +08:00
|
|
|
PointerAlign = 8;
|
2008-10-31 17:52:39 +08:00
|
|
|
SizeType = UnsignedInt;
|
|
|
|
IntMaxType = SignedLong;
|
|
|
|
UIntMaxType = UnsignedLong;
|
2009-02-14 06:28:55 +08:00
|
|
|
IntPtrType = SignedShort;
|
2008-11-02 10:43:55 +08:00
|
|
|
PtrDiffType = SignedInt;
|
2009-06-02 12:43:46 +08:00
|
|
|
FloatWidth = 32;
|
|
|
|
FloatAlign = 32;
|
|
|
|
DoubleWidth = 32;
|
|
|
|
DoubleAlign = 32;
|
|
|
|
LongDoubleWidth = 32;
|
|
|
|
LongDoubleAlign = 32;
|
|
|
|
FloatFormat = &llvm::APFloat::IEEEsingle;
|
|
|
|
DoubleFormat = &llvm::APFloat::IEEEsingle;
|
|
|
|
LongDoubleFormat = &llvm::APFloat::IEEEsingle;
|
|
|
|
DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-f32:32:32";
|
|
|
|
|
2008-05-08 13:58:21 +08:00
|
|
|
}
|
2008-05-09 14:08:39 +08:00
|
|
|
virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; }
|
|
|
|
virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; }
|
2009-03-20 23:52:06 +08:00
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
|
|
|
std::vector<char> &Defines) const {
|
2008-05-08 13:58:21 +08:00
|
|
|
Define(Defines, "__pic16");
|
2009-07-07 12:42:23 +08:00
|
|
|
Define(Defines, "rom", "__attribute__((address_space(1)))");
|
|
|
|
Define(Defines, "ram", "__attribute__((address_space(0)))");
|
|
|
|
Define(Defines, "_section(SectName)", "__attribute__((section(SectName)))");
|
|
|
|
Define(Defines, "_address(Addr)","__attribute__((section(\"Address=\"#Addr)))");
|
|
|
|
Define(Defines, "_CONFIG(conf)", "asm(\"CONFIG \"#conf)");
|
2008-05-08 13:58:21 +08:00
|
|
|
}
|
|
|
|
virtual void getTargetBuiltins(const Builtin::Info *&Records,
|
|
|
|
unsigned &NumRecords) const {}
|
|
|
|
virtual const char *getVAListDeclaration() const { return "";}
|
|
|
|
virtual const char *getClobbers() const {return "";}
|
2009-04-21 14:01:16 +08:00
|
|
|
virtual const char *getTargetPrefix() const {return "pic16";}
|
2009-05-03 21:42:53 +08:00
|
|
|
virtual void getGCCRegNames(const char * const *&Names,
|
|
|
|
unsigned &NumNames) const {}
|
|
|
|
virtual bool validateAsmConstraint(const char *&Name,
|
2008-05-08 13:58:21 +08:00
|
|
|
TargetInfo::ConstraintInfo &info) const {
|
|
|
|
return true;
|
|
|
|
}
|
2009-05-03 21:42:53 +08:00
|
|
|
virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
|
2008-05-08 13:58:21 +08:00
|
|
|
unsigned &NumAliases) const {}
|
|
|
|
virtual bool useGlobalsForAutomaticVariables() const {return true;}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
IntWidth = 16;
|
|
|
|
LongWidth = LongLongWidth = 32;
|
2009-05-17 07:30:57 +08:00
|
|
|
IntMaxTWidth = 32;
|
2009-05-03 21:43:08 +08:00
|
|
|
PointerWidth = 16;
|
|
|
|
IntAlign = 8;
|
|
|
|
LongAlign = LongLongAlign = 8;
|
|
|
|
PointerAlign = 8;
|
|
|
|
SizeType = UnsignedInt;
|
|
|
|
IntMaxType = SignedLong;
|
|
|
|
UIntMaxType = UnsignedLong;
|
|
|
|
IntPtrType = SignedShort;
|
|
|
|
PtrDiffType = SignedInt;
|
|
|
|
DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8";
|
|
|
|
}
|
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
|
|
|
std::vector<char> &Defines) const {
|
|
|
|
Define(Defines, "MSP430");
|
|
|
|
Define(Defines, "__MSP430__");
|
|
|
|
// FIXME: defines for different 'flavours' of MCU
|
|
|
|
}
|
|
|
|
virtual void getTargetBuiltins(const Builtin::Info *&Records,
|
|
|
|
unsigned &NumRecords) const {
|
|
|
|
// FIXME: Implement.
|
|
|
|
Records = 0;
|
|
|
|
NumRecords = 0;
|
|
|
|
}
|
|
|
|
virtual const char *getTargetPrefix() const {
|
|
|
|
return "msp430";
|
|
|
|
}
|
|
|
|
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
|
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;
|
|
|
|
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";
|
|
|
|
}
|
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
|
|
|
std::vector<char> &Defines) const {
|
|
|
|
Define(Defines, "__s390__");
|
|
|
|
Define(Defines, "__s390x__");
|
|
|
|
}
|
|
|
|
virtual void getTargetBuiltins(const Builtin::Info *&Records,
|
|
|
|
unsigned &NumRecords) const {
|
|
|
|
// FIXME: Implement.
|
|
|
|
Records = 0;
|
|
|
|
NumRecords = 0;
|
|
|
|
}
|
|
|
|
virtual const char *getTargetPrefix() const {
|
|
|
|
return "s390x";
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void getDefaultLangOptions(LangOptions &Opts) {
|
|
|
|
TargetInfo::getDefaultLangOptions(Opts);
|
|
|
|
Opts.CharIsSigned = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-10-14 15:39:34 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Driver code
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2007-12-05 01:07:35 +08:00
|
|
|
static inline bool IsX86(const std::string& TT) {
|
2007-12-04 06:06:55 +08:00
|
|
|
return (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' &&
|
|
|
|
TT[4] == '-' && TT[1] - '3' < 6);
|
|
|
|
}
|
|
|
|
|
2008-03-05 09:18:20 +08:00
|
|
|
/// CreateTargetInfo - Return the target info object for the specified target
|
|
|
|
/// triple.
|
|
|
|
TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
|
2008-08-21 08:13:15 +08:00
|
|
|
// OS detection; this isn't really anywhere near complete.
|
|
|
|
// Additions and corrections are welcome.
|
|
|
|
bool isDarwin = T.find("-darwin") != std::string::npos;
|
2008-08-24 02:23:14 +08:00
|
|
|
bool isDragonFly = T.find("-dragonfly") != std::string::npos;
|
2009-07-14 04:29:08 +08:00
|
|
|
bool isNetBSD = T.find("-netbsd") != std::string::npos;
|
2009-06-30 04:52:51 +08:00
|
|
|
bool isOpenBSD = T.find("-openbsd") != std::string::npos;
|
2008-10-17 01:04:31 +08:00
|
|
|
bool isFreeBSD = T.find("-freebsd") != std::string::npos;
|
2008-08-21 08:13:15 +08:00
|
|
|
bool isSolaris = T.find("-solaris") != std::string::npos;
|
|
|
|
bool isLinux = T.find("-linux") != std::string::npos;
|
|
|
|
bool isWindows = T.find("-windows") != std::string::npos ||
|
|
|
|
T.find("-win32") != std::string::npos ||
|
|
|
|
T.find("-mingw") != std::string::npos;
|
|
|
|
|
|
|
|
if (T.find("ppc-") == 0 || T.find("powerpc-") == 0) {
|
|
|
|
if (isDarwin)
|
2009-07-01 01:10:35 +08:00
|
|
|
return new DarwinTargetInfo<PPCTargetInfo>(T);
|
2008-08-21 08:13:15 +08:00
|
|
|
return new PPC32TargetInfo(T);
|
|
|
|
}
|
2008-05-20 22:21:01 +08:00
|
|
|
|
2008-08-21 08:13:15 +08:00
|
|
|
if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0) {
|
|
|
|
if (isDarwin)
|
2009-07-01 01:10:35 +08:00
|
|
|
return new DarwinTargetInfo<PPC64TargetInfo>(T);
|
2008-08-21 08:13:15 +08:00
|
|
|
return new PPC64TargetInfo(T);
|
|
|
|
}
|
2008-05-20 22:21:01 +08:00
|
|
|
|
2009-04-23 12:22:04 +08:00
|
|
|
if (T.find("armv") == 0 || T.find("arm-") == 0 || T.find("xscale") == 0) {
|
2008-08-21 08:13:15 +08:00
|
|
|
if (isDarwin)
|
|
|
|
return new DarwinARMTargetInfo(T);
|
2009-03-24 00:09:04 +08:00
|
|
|
if (isFreeBSD)
|
2009-07-01 01:10:35 +08:00
|
|
|
return new FreeBSDTargetInfo<ARMTargetInfo>(T);
|
2008-08-21 08:13:15 +08:00
|
|
|
return new ARMTargetInfo(T);
|
|
|
|
}
|
2008-04-22 02:56:49 +08:00
|
|
|
|
2008-08-21 08:13:15 +08:00
|
|
|
if (T.find("sparc-") == 0) {
|
|
|
|
if (isSolaris)
|
|
|
|
return new SolarisSparcV8TargetInfo(T);
|
|
|
|
return new SparcV8TargetInfo(T);
|
|
|
|
}
|
2008-05-20 22:21:01 +08:00
|
|
|
|
2009-02-21 01:04:14 +08:00
|
|
|
if (T.find("x86_64-") == 0 || T.find("amd64-") == 0) {
|
2008-08-21 08:13:15 +08:00
|
|
|
if (isDarwin)
|
2009-07-01 11:36:11 +08:00
|
|
|
return new DarwinX86_64TargetInfo(T);
|
2008-09-24 01:37:57 +08:00
|
|
|
if (isLinux)
|
2009-07-01 01:10:35 +08:00
|
|
|
return new LinuxTargetInfo<X86_64TargetInfo>(T);
|
2009-07-14 04:29:08 +08:00
|
|
|
if (isNetBSD)
|
|
|
|
return new NetBSDTargetInfo<X86_64TargetInfo>(T);
|
2009-06-30 04:52:51 +08:00
|
|
|
if (isOpenBSD)
|
2009-07-06 06:31:18 +08:00
|
|
|
return new OpenBSDX86_64TargetInfo(T);
|
2008-10-17 01:04:31 +08:00
|
|
|
if (isFreeBSD)
|
2009-07-01 01:10:35 +08:00
|
|
|
return new FreeBSDTargetInfo<X86_64TargetInfo>(T);
|
2009-05-22 07:51:30 +08:00
|
|
|
if (isSolaris)
|
2009-07-01 01:10:35 +08:00
|
|
|
return new SolarisTargetInfo<X86_64TargetInfo>(T);
|
2008-08-21 08:13:15 +08:00
|
|
|
return new X86_64TargetInfo(T);
|
|
|
|
}
|
2008-05-20 22:21:01 +08:00
|
|
|
|
2008-05-08 13:58:21 +08:00
|
|
|
if (T.find("pic16-") == 0)
|
|
|
|
return new PIC16TargetInfo(T);
|
|
|
|
|
2009-05-03 21:43:08 +08:00
|
|
|
if (T.find("msp430-") == 0)
|
|
|
|
return new MSP430TargetInfo(T);
|
|
|
|
|
2009-07-17 04:09:57 +08:00
|
|
|
if (T.find("s390x-") == 0)
|
|
|
|
return new SystemZTargetInfo(T);
|
|
|
|
|
2008-08-21 08:13:15 +08:00
|
|
|
if (IsX86(T)) {
|
|
|
|
if (isDarwin)
|
|
|
|
return new DarwinI386TargetInfo(T);
|
2008-08-21 08:24:02 +08:00
|
|
|
if (isLinux)
|
2009-07-01 01:10:35 +08:00
|
|
|
return new LinuxTargetInfo<X86_32TargetInfo>(T);
|
2008-08-24 02:23:14 +08:00
|
|
|
if (isDragonFly)
|
2009-07-01 01:10:35 +08:00
|
|
|
return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(T);
|
2009-07-14 04:29:08 +08:00
|
|
|
if (isNetBSD)
|
|
|
|
return new NetBSDTargetInfo<X86_32TargetInfo>(T);
|
2009-06-30 04:52:51 +08:00
|
|
|
if (isOpenBSD)
|
2009-07-06 02:47:56 +08:00
|
|
|
return new OpenBSDI386TargetInfo(T);
|
2008-10-17 01:04:31 +08:00
|
|
|
if (isFreeBSD)
|
2009-07-01 01:10:35 +08:00
|
|
|
return new FreeBSDTargetInfo<X86_32TargetInfo>(T);
|
2009-05-22 07:51:30 +08:00
|
|
|
if (isSolaris)
|
2009-07-01 01:10:35 +08:00
|
|
|
return new SolarisTargetInfo<X86_32TargetInfo>(T);
|
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
|
|
|
if (isWindows)
|
|
|
|
return new WindowsX86_32TargetInfo(T);
|
2008-08-21 08:13:15 +08:00
|
|
|
return new X86_32TargetInfo(T);
|
|
|
|
}
|
2008-05-20 22:21:01 +08:00
|
|
|
|
2008-03-05 09:18:20 +08:00
|
|
|
return NULL;
|
2006-10-14 15:39:34 +08:00
|
|
|
}
|