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"
|
2013-01-02 19:45:17 +08:00
|
|
|
#include "llvm/IR/Type.h"
|
2009-08-11 03:03:04 +08:00
|
|
|
#include "llvm/MC/MCSectionMachO.h"
|
2011-09-23 13:35:21 +08:00
|
|
|
#include "llvm/Support/ErrorHandling.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.
|
2011-07-23 18:55:15 +08:00
|
|
|
static void DefineStd(MacroBuilder &Builder, 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
|
|
|
}
|
|
|
|
|
2012-01-10 19:50:09 +08:00
|
|
|
static void defineCPUMacros(MacroBuilder &Builder, StringRef CPUName,
|
|
|
|
bool Tuning = true) {
|
|
|
|
Builder.defineMacro("__" + CPUName);
|
|
|
|
Builder.defineMacro("__" + CPUName + "__");
|
|
|
|
if (Tuning)
|
|
|
|
Builder.defineMacro("__tune_" + CPUName + "__");
|
|
|
|
}
|
|
|
|
|
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:
|
2013-06-30 00:37:14 +08:00
|
|
|
OSTargetInfo(const llvm::Triple &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,
|
Implement a new 'availability' attribute, that allows one to specify
which versions of an OS provide a certain facility. For example,
void foo()
__attribute__((availability(macosx,introduced=10.2,deprecated=10.4,obsoleted=10.6)));
says that the function "foo" was introduced in 10.2, deprecated in
10.4, and completely obsoleted in 10.6. This attribute ties in with
the deployment targets (e.g., -mmacosx-version-min=10.1 specifies that
we want to deploy back to Mac OS X 10.1). There are several concrete
behaviors that this attribute enables, as illustrated with the
function foo() above:
- If we choose a deployment target >= Mac OS X 10.4, uses of "foo"
will result in a deprecation warning, as if we had placed
attribute((deprecated)) on it (but with a better diagnostic)
- If we choose a deployment target >= Mac OS X 10.6, uses of "foo"
will result in an "unavailable" warning (in C)/error (in C++), as
if we had placed attribute((unavailable)) on it
- If we choose a deployment target prior to 10.2, foo() is
weak-imported (if it is a kind of entity that can be weak
imported), as if we had placed the weak_import attribute on it.
Naturally, there can be multiple availability attributes on a
declaration, for different platforms; only the current platform
matters when checking availability attributes.
The only platforms this attribute currently works for are "ios" and
"macosx", since we already have -mxxxx-version-min flags for them and we
have experience there with macro tricks translating down to the
deprecated/unavailable/weak_import attributes. The end goal is to open
this up to other platforms, and even extension to other "platforms"
that are really libraries (say, through a #pragma clang
define_system), but that hasn't yet been designed and we may want to
shake out more issues with this narrower problem first.
Addresses <rdar://problem/6690412>.
As a drive-by bug-fix, if an entity is both deprecated and
unavailable, we only emit the "unavailable" diagnostic.
llvm-svn: 128127
2011-03-23 08:50:03 +08:00
|
|
|
const llvm::Triple &Triple,
|
2011-07-23 18:55:15 +08:00
|
|
|
StringRef &PlatformName,
|
Implement a new 'availability' attribute, that allows one to specify
which versions of an OS provide a certain facility. For example,
void foo()
__attribute__((availability(macosx,introduced=10.2,deprecated=10.4,obsoleted=10.6)));
says that the function "foo" was introduced in 10.2, deprecated in
10.4, and completely obsoleted in 10.6. This attribute ties in with
the deployment targets (e.g., -mmacosx-version-min=10.1 specifies that
we want to deploy back to Mac OS X 10.1). There are several concrete
behaviors that this attribute enables, as illustrated with the
function foo() above:
- If we choose a deployment target >= Mac OS X 10.4, uses of "foo"
will result in a deprecation warning, as if we had placed
attribute((deprecated)) on it (but with a better diagnostic)
- If we choose a deployment target >= Mac OS X 10.6, uses of "foo"
will result in an "unavailable" warning (in C)/error (in C++), as
if we had placed attribute((unavailable)) on it
- If we choose a deployment target prior to 10.2, foo() is
weak-imported (if it is a kind of entity that can be weak
imported), as if we had placed the weak_import attribute on it.
Naturally, there can be multiple availability attributes on a
declaration, for different platforms; only the current platform
matters when checking availability attributes.
The only platforms this attribute currently works for are "ios" and
"macosx", since we already have -mxxxx-version-min flags for them and we
have experience there with macro tricks translating down to the
deprecated/unavailable/weak_import attributes. The end goal is to open
this up to other platforms, and even extension to other "platforms"
that are really libraries (say, through a #pragma clang
define_system), but that hasn't yet been designed and we may want to
shake out more issues with this narrower problem first.
Addresses <rdar://problem/6690412>.
As a drive-by bug-fix, if an entity is both deprecated and
unavailable, we only emit the "unavailable" diagnostic.
llvm-svn: 128127
2011-03-23 08:50:03 +08:00
|
|
|
VersionTuple &PlatformMinVersion) {
|
2013-08-20 04:23:37 +08:00
|
|
|
Builder.defineMacro("__APPLE_CC__", "6000");
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__APPLE__");
|
|
|
|
Builder.defineMacro("__MACH__");
|
|
|
|
Builder.defineMacro("OBJC_NEW_PROPERTIES");
|
2012-09-20 18:10:01 +08:00
|
|
|
// AddressSanitizer doesn't play well with source fortification, which is on
|
|
|
|
// by default on Darwin.
|
2013-01-18 19:30:38 +08:00
|
|
|
if (Opts.Sanitize.Address) Builder.defineMacro("_FORTIFY_SOURCE", "0");
|
2009-05-03 21:42:53 +08:00
|
|
|
|
2011-06-16 08:03:19 +08:00
|
|
|
if (!Opts.ObjCAutoRefCount) {
|
2011-06-16 07:02:42 +08:00
|
|
|
// __weak is always defined, for use in blocks and with objc pointers.
|
|
|
|
Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))");
|
|
|
|
|
|
|
|
// Darwin defines __strong even in C mode (just to nothing).
|
2011-09-14 01:21:33 +08:00
|
|
|
if (Opts.getGC() != LangOptions::NonGC)
|
2011-06-16 07:02:42 +08:00
|
|
|
Builder.defineMacro("__strong", "__attribute__((objc_gc(strong)))");
|
|
|
|
else
|
|
|
|
Builder.defineMacro("__strong", "");
|
2011-07-08 06:55:26 +08:00
|
|
|
|
2011-06-16 07:02:42 +08:00
|
|
|
// __unsafe_unretained is defined to nothing in non-ARC mode. We even
|
|
|
|
// allow this in C, since one might have block pointers in structs that
|
|
|
|
// are used in pure C code and in Objective-C ARC.
|
|
|
|
Builder.defineMacro("__unsafe_unretained", "");
|
|
|
|
}
|
2011-07-08 06:55:26 +08:00
|
|
|
|
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
|
|
|
|
2011-04-20 05:40:34 +08:00
|
|
|
// Get the platform type and version number from the triple.
|
2009-04-11 03:52:24 +08:00
|
|
|
unsigned Maj, Min, Rev;
|
2012-02-01 07:52:58 +08:00
|
|
|
if (Triple.isMacOSX()) {
|
|
|
|
Triple.getMacOSXVersion(Maj, Min, Rev);
|
2011-04-20 05:40:34 +08:00
|
|
|
PlatformName = "macosx";
|
|
|
|
} else {
|
2012-02-01 07:52:58 +08:00
|
|
|
Triple.getOSVersion(Maj, Min, Rev);
|
|
|
|
PlatformName = llvm::Triple::getOSTypeName(Triple.getOS());
|
2011-04-20 05:40:34 +08:00
|
|
|
}
|
2010-01-26 09:44:04 +08:00
|
|
|
|
2012-01-21 06:01:23 +08:00
|
|
|
// If -target arch-pc-win32-macho option specified, we're
|
2011-07-30 05:20:35 +08:00
|
|
|
// generating code for Win32 ABI. No need to emit
|
2011-07-20 04:00:06 +08:00
|
|
|
// __ENVIRONMENT_XX_OS_VERSION_MIN_REQUIRED__.
|
|
|
|
if (PlatformName == "win32") {
|
|
|
|
PlatformMinVersion = VersionTuple(Maj, Min, Rev);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-11-20 04:18:39 +08:00
|
|
|
// If there's an environment specified in the triple, that means we're dealing
|
|
|
|
// with an embedded variant of some sort and don't want the platform
|
|
|
|
// version-min defines, so only add them if there's not one.
|
|
|
|
if (Triple.getEnvironmentName().empty()) {
|
|
|
|
// Set the appropriate OS version define.
|
|
|
|
if (Triple.isiOS()) {
|
|
|
|
assert(Maj < 10 && Min < 100 && Rev < 100 && "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 {
|
|
|
|
// Note that the Driver allows versions which aren't representable in the
|
|
|
|
// define (because we only get a single digit for the minor and micro
|
|
|
|
// revision numbers). So, we limit them to the maximum representable
|
|
|
|
// version.
|
|
|
|
assert(Triple.getEnvironmentName().empty() && "Invalid environment!");
|
|
|
|
assert(Maj < 100 && Min < 100 && Rev < 100 && "Invalid version!");
|
|
|
|
char Str[5];
|
|
|
|
Str[0] = '0' + (Maj / 10);
|
|
|
|
Str[1] = '0' + (Maj % 10);
|
|
|
|
Str[2] = '0' + std::min(Min, 9U);
|
|
|
|
Str[3] = '0' + std::min(Rev, 9U);
|
|
|
|
Str[4] = '\0';
|
|
|
|
Builder.defineMacro("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", Str);
|
|
|
|
}
|
2008-09-30 09:00:25 +08:00
|
|
|
}
|
2011-04-20 05:40:34 +08:00
|
|
|
|
|
|
|
PlatformMinVersion = VersionTuple(Maj, Min, Rev);
|
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 {
|
2011-07-08 06:55:26 +08:00
|
|
|
getDarwinDefines(Builder, Opts, Triple, this->PlatformName,
|
Implement a new 'availability' attribute, that allows one to specify
which versions of an OS provide a certain facility. For example,
void foo()
__attribute__((availability(macosx,introduced=10.2,deprecated=10.4,obsoleted=10.6)));
says that the function "foo" was introduced in 10.2, deprecated in
10.4, and completely obsoleted in 10.6. This attribute ties in with
the deployment targets (e.g., -mmacosx-version-min=10.1 specifies that
we want to deploy back to Mac OS X 10.1). There are several concrete
behaviors that this attribute enables, as illustrated with the
function foo() above:
- If we choose a deployment target >= Mac OS X 10.4, uses of "foo"
will result in a deprecation warning, as if we had placed
attribute((deprecated)) on it (but with a better diagnostic)
- If we choose a deployment target >= Mac OS X 10.6, uses of "foo"
will result in an "unavailable" warning (in C)/error (in C++), as
if we had placed attribute((unavailable)) on it
- If we choose a deployment target prior to 10.2, foo() is
weak-imported (if it is a kind of entity that can be weak
imported), as if we had placed the weak_import attribute on it.
Naturally, there can be multiple availability attributes on a
declaration, for different platforms; only the current platform
matters when checking availability attributes.
The only platforms this attribute currently works for are "ios" and
"macosx", since we already have -mxxxx-version-min flags for them and we
have experience there with macro tricks translating down to the
deprecated/unavailable/weak_import attributes. The end goal is to open
this up to other platforms, and even extension to other "platforms"
that are really libraries (say, through a #pragma clang
define_system), but that hasn't yet been designed and we may want to
shake out more issues with this narrower problem first.
Addresses <rdar://problem/6690412>.
As a drive-by bug-fix, if an entity is both deprecated and
unavailable, we only emit the "unavailable" diagnostic.
llvm-svn: 128127
2011-03-23 08:50:03 +08:00
|
|
|
this->PlatformMinVersion);
|
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:
|
2013-06-30 00:37:14 +08:00
|
|
|
DarwinTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
|
|
|
|
this->TLSSupported = Triple.isMacOSX() && !Triple.isMacOSXVersionLT(10, 7);
|
|
|
|
this->MCountName = "\01mcount";
|
|
|
|
}
|
2009-07-01 01:10:35 +08:00
|
|
|
|
2011-07-23 18:55:15 +08:00
|
|
|
virtual std::string isValidSectionSpecifier(StringRef SR) const {
|
2009-08-11 03:03:04 +08:00
|
|
|
// Let MCSectionMachO validate this.
|
2011-07-23 18:55:15 +08:00
|
|
|
StringRef Segment, Section;
|
2009-08-11 03:03:04 +08:00
|
|
|
unsigned TAA, StubSize;
|
2011-03-19 10:06:21 +08:00
|
|
|
bool HasTAA;
|
2009-08-11 03:03:04 +08:00
|
|
|
return llvm::MCSectionMachO::ParseSectionSpecifier(SR, Segment, Section,
|
2011-03-19 10:06:21 +08:00
|
|
|
TAA, HasTAA, StubSize);
|
2009-08-11 03:03:04 +08:00
|
|
|
}
|
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
|
|
|
|
2012-01-29 09:20:30 +08:00
|
|
|
/// Darwin does not support protected visibility. Darwin's "default"
|
|
|
|
/// is very similar to ELF's "protected"; Darwin requires a "weak"
|
|
|
|
/// attribute on declarations that can be dynamically replaced.
|
|
|
|
virtual bool hasProtectedVisibility() const {
|
|
|
|
return false;
|
|
|
|
}
|
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:
|
2013-06-30 00:37:14 +08:00
|
|
|
DragonFlyBSDTargetInfo(const llvm::Triple &Triple)
|
|
|
|
: OSTargetInfo<Target>(Triple) {
|
|
|
|
this->UserLabelPrefix = "";
|
2012-02-11 07:02:29 +08:00
|
|
|
|
2013-06-30 00:37:14 +08:00
|
|
|
switch (Triple.getArch()) {
|
|
|
|
default:
|
|
|
|
case llvm::Triple::x86:
|
|
|
|
case llvm::Triple::x86_64:
|
|
|
|
this->MCountName = ".mcount";
|
|
|
|
break;
|
|
|
|
}
|
2012-02-11 07:02:29 +08:00
|
|
|
}
|
2009-07-01 01:10:35 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
// 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
|
|
|
|
|
2011-10-18 18:10:08 +08:00
|
|
|
unsigned Release = Triple.getOSMajorVersion();
|
|
|
|
if (Release == 0U)
|
|
|
|
Release = 8;
|
2010-01-31 03:55:01 +08:00
|
|
|
|
2011-10-18 18:10:08 +08:00
|
|
|
Builder.defineMacro("__FreeBSD__", Twine(Release));
|
|
|
|
Builder.defineMacro("__FreeBSD_cc_version", Twine(Release * 100000U + 1U));
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
|
|
|
|
DefineStd(Builder, "unix", Opts);
|
|
|
|
Builder.defineMacro("__ELF__");
|
2013-09-29 15:54:52 +08:00
|
|
|
|
|
|
|
// On FreeBSD, wchar_t contains the number of the code point as
|
|
|
|
// used by the character set of the locale. These character sets are
|
|
|
|
// not necessarily a superset of ASCII.
|
|
|
|
Builder.defineMacro("__STDC_MB_MIGHT_NEQ_WC__", "1");
|
2009-07-01 01:10:35 +08:00
|
|
|
}
|
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
FreeBSDTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
|
|
|
|
this->UserLabelPrefix = "";
|
2011-02-11 00:52:03 +08:00
|
|
|
|
2013-06-30 00:37:14 +08:00
|
|
|
switch (Triple.getArch()) {
|
|
|
|
default:
|
|
|
|
case llvm::Triple::x86:
|
|
|
|
case llvm::Triple::x86_64:
|
|
|
|
this->MCountName = ".mcount";
|
|
|
|
break;
|
|
|
|
case llvm::Triple::mips:
|
|
|
|
case llvm::Triple::mipsel:
|
|
|
|
case llvm::Triple::ppc:
|
|
|
|
case llvm::Triple::ppc64:
|
2013-07-26 09:36:11 +08:00
|
|
|
case llvm::Triple::ppc64le:
|
2013-06-30 00:37:14 +08:00
|
|
|
this->MCountName = "_mcount";
|
|
|
|
break;
|
|
|
|
case llvm::Triple::arm:
|
|
|
|
this->MCountName = "__mcount";
|
|
|
|
break;
|
2009-07-08 21:55:08 +08:00
|
|
|
}
|
2013-06-30 00:37:14 +08:00
|
|
|
}
|
2009-07-01 01:10:35 +08:00
|
|
|
};
|
|
|
|
|
2013-09-05 21:47:07 +08:00
|
|
|
// GNU/kFreeBSD Target
|
|
|
|
template<typename Target>
|
|
|
|
class KFreeBSDTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
|
|
|
virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
// GNU/kFreeBSD defines; list based off of gcc output
|
|
|
|
|
|
|
|
DefineStd(Builder, "unix", Opts);
|
|
|
|
Builder.defineMacro("__FreeBSD_kernel__");
|
|
|
|
Builder.defineMacro("__GLIBC__");
|
|
|
|
Builder.defineMacro("__ELF__");
|
|
|
|
if (Opts.POSIXThreads)
|
|
|
|
Builder.defineMacro("_REENTRANT");
|
|
|
|
if (Opts.CPlusPlus)
|
|
|
|
Builder.defineMacro("_GNU_SOURCE");
|
|
|
|
}
|
|
|
|
public:
|
2013-09-05 21:58:07 +08:00
|
|
|
KFreeBSDTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
|
2013-09-05 21:47:07 +08:00
|
|
|
this->UserLabelPrefix = "";
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
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");
|
2011-12-09 07:54:21 +08:00
|
|
|
Builder.defineMacro("__ELF__");
|
2010-07-08 00:01:42 +08:00
|
|
|
DefineStd(Builder, "unix", Opts);
|
|
|
|
}
|
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
MinixTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
|
|
|
|
this->UserLabelPrefix = "";
|
|
|
|
}
|
2010-07-08 00:01:42 +08:00
|
|
|
};
|
|
|
|
|
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__");
|
2012-09-02 17:30:11 +08:00
|
|
|
if (Triple.getEnvironment() == llvm::Triple::Android)
|
2012-04-26 20:08:09 +08:00
|
|
|
Builder.defineMacro("__ANDROID__", "1");
|
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:
|
2013-06-30 00:37:14 +08:00
|
|
|
LinuxTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
|
2009-07-01 01:10:35 +08:00
|
|
|
this->UserLabelPrefix = "";
|
2011-01-13 05:19:25 +08:00
|
|
|
this->WIntType = TargetInfo::UnsignedInt;
|
2009-07-01 01:10:35 +08:00
|
|
|
}
|
2011-10-16 01:53:33 +08:00
|
|
|
|
|
|
|
virtual const char *getStaticInitSectionSpecifier() const {
|
|
|
|
return ".text.startup";
|
|
|
|
}
|
2009-07-01 01:10:35 +08:00
|
|
|
};
|
|
|
|
|
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:
|
2013-06-30 00:37:14 +08:00
|
|
|
NetBSDTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
|
|
|
|
this->UserLabelPrefix = "";
|
|
|
|
}
|
2009-07-14 04:29:08 +08:00
|
|
|
};
|
|
|
|
|
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)
|
2012-04-25 14:12:24 +08:00
|
|
|
Builder.defineMacro("_REENTRANT");
|
2009-07-01 01:10:35 +08:00
|
|
|
}
|
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
OpenBSDTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
|
|
|
|
this->UserLabelPrefix = "";
|
|
|
|
this->TLSSupported = false;
|
2011-12-15 10:15:56 +08:00
|
|
|
|
|
|
|
switch (Triple.getArch()) {
|
|
|
|
default:
|
|
|
|
case llvm::Triple::x86:
|
|
|
|
case llvm::Triple::x86_64:
|
|
|
|
case llvm::Triple::arm:
|
2012-11-15 06:08:59 +08:00
|
|
|
case llvm::Triple::sparc:
|
2011-12-15 10:15:56 +08:00
|
|
|
this->MCountName = "__mcount";
|
|
|
|
break;
|
|
|
|
case llvm::Triple::mips64:
|
|
|
|
case llvm::Triple::mips64el:
|
|
|
|
case llvm::Triple::ppc:
|
2012-11-15 06:08:59 +08:00
|
|
|
case llvm::Triple::sparcv9:
|
2011-12-15 10:15:56 +08:00
|
|
|
this->MCountName = "_mcount";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2009-07-01 01:10:35 +08:00
|
|
|
};
|
|
|
|
|
2012-08-09 07:57:20 +08:00
|
|
|
// Bitrig Target
|
|
|
|
template<typename Target>
|
|
|
|
class BitrigTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
|
|
|
virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
// Bitrig defines; list based off of gcc output
|
|
|
|
|
|
|
|
Builder.defineMacro("__Bitrig__");
|
|
|
|
DefineStd(Builder, "unix", Opts);
|
|
|
|
Builder.defineMacro("__ELF__");
|
|
|
|
if (Opts.POSIXThreads)
|
|
|
|
Builder.defineMacro("_REENTRANT");
|
|
|
|
}
|
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
BitrigTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
|
|
|
|
this->UserLabelPrefix = "";
|
|
|
|
this->TLSSupported = false;
|
|
|
|
this->MCountName = "__mcount";
|
2012-08-09 07:57:20 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
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:
|
2013-06-30 00:37:14 +08:00
|
|
|
PSPTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
|
2009-11-15 18:22:07 +08:00
|
|
|
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:
|
2013-06-30 00:37:14 +08:00
|
|
|
PS3PPUTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
|
2009-11-20 01:18:50 +08:00
|
|
|
this->UserLabelPrefix = "";
|
2011-12-17 06:32:39 +08:00
|
|
|
this->LongWidth = this->LongAlign = 32;
|
|
|
|
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;
|
2014-01-04 03:22:05 +08:00
|
|
|
this->DescriptionString = "E-m:e-p:32:32-i64:64-n32:64";
|
2009-11-20 01:18:50 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
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:
|
2013-06-30 00:37:14 +08:00
|
|
|
AuroraUXTargetInfo(const llvm::Triple &Triple)
|
|
|
|
: OSTargetInfo<Target>(Triple) {
|
2009-10-18 21:33:59 +08:00
|
|
|
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");
|
2012-02-29 01:10:04 +08:00
|
|
|
// Solaris headers require _XOPEN_SOURCE to be set to 600 for C99 and
|
|
|
|
// newer, but to 500 for everything else. feature_test.h has a check to
|
|
|
|
// ensure that you are not using C99 with an old version of X/Open or C89
|
|
|
|
// with a new version.
|
|
|
|
if (Opts.C99 || Opts.C11)
|
|
|
|
Builder.defineMacro("_XOPEN_SOURCE", "600");
|
|
|
|
else
|
|
|
|
Builder.defineMacro("_XOPEN_SOURCE", "500");
|
2012-03-02 18:49:52 +08:00
|
|
|
if (Opts.CPlusPlus)
|
2012-02-29 01:10:04 +08:00
|
|
|
Builder.defineMacro("__C99FEATURES__");
|
2012-02-18 02:35:11 +08:00
|
|
|
Builder.defineMacro("_LARGEFILE_SOURCE");
|
|
|
|
Builder.defineMacro("_LARGEFILE64_SOURCE");
|
|
|
|
Builder.defineMacro("__EXTENSIONS__");
|
2012-02-29 01:10:04 +08:00
|
|
|
Builder.defineMacro("_REENTRANT");
|
2009-07-01 01:10:35 +08:00
|
|
|
}
|
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
SolarisTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
|
2009-07-01 01:10:35 +08:00
|
|
|
this->UserLabelPrefix = "";
|
2012-03-29 02:04:14 +08:00
|
|
|
this->WCharType = this->SignedInt;
|
2009-07-01 01:10:35 +08:00
|
|
|
// 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)
|
2011-07-23 18:55:15 +08:00
|
|
|
Builder.defineMacro("_MSC_VER", Twine(Opts.MSCVersion));
|
2010-10-21 13:21:48 +08:00
|
|
|
|
2011-09-18 01:15:52 +08:00
|
|
|
if (Opts.MicrosoftExt) {
|
2010-10-21 13:21:48 +08:00
|
|
|
Builder.defineMacro("_MSC_EXTENSIONS");
|
|
|
|
|
2013-01-02 19:42:31 +08:00
|
|
|
if (Opts.CPlusPlus11) {
|
2010-10-21 13:21:48 +08:00
|
|
|
Builder.defineMacro("_RVALUE_REFERENCES_V2_SUPPORTED");
|
|
|
|
Builder.defineMacro("_RVALUE_REFERENCES_SUPPORTED");
|
|
|
|
Builder.defineMacro("_NATIVE_NULLPTR_SUPPORTED");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Builder.defineMacro("_INTEGRAL_MAX_BITS", "64");
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
WindowsTargetInfo(const llvm::Triple &Triple)
|
|
|
|
: OSTargetInfo<Target>(Triple) {}
|
2010-10-21 13:21:48 +08:00
|
|
|
};
|
|
|
|
|
2012-10-12 00:55:58 +08:00
|
|
|
template <typename Target>
|
|
|
|
class NaClTargetInfo : public OSTargetInfo<Target> {
|
2013-06-30 00:37:14 +08:00
|
|
|
protected:
|
2012-10-12 00:55:58 +08:00
|
|
|
virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
if (Opts.POSIXThreads)
|
|
|
|
Builder.defineMacro("_REENTRANT");
|
|
|
|
if (Opts.CPlusPlus)
|
|
|
|
Builder.defineMacro("_GNU_SOURCE");
|
|
|
|
|
|
|
|
DefineStd(Builder, "unix", Opts);
|
|
|
|
Builder.defineMacro("__ELF__");
|
|
|
|
Builder.defineMacro("__native_client__");
|
|
|
|
}
|
2013-06-30 00:37:14 +08:00
|
|
|
|
|
|
|
public:
|
|
|
|
NaClTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
|
2012-10-12 00:55:58 +08:00
|
|
|
this->UserLabelPrefix = "";
|
|
|
|
this->LongAlign = 32;
|
|
|
|
this->LongWidth = 32;
|
|
|
|
this->PointerAlign = 32;
|
|
|
|
this->PointerWidth = 32;
|
|
|
|
this->IntMaxType = TargetInfo::SignedLongLong;
|
|
|
|
this->UIntMaxType = TargetInfo::UnsignedLongLong;
|
|
|
|
this->Int64Type = TargetInfo::SignedLongLong;
|
|
|
|
this->DoubleAlign = 64;
|
|
|
|
this->LongDoubleWidth = 64;
|
|
|
|
this->LongDoubleAlign = 64;
|
2014-01-16 05:42:41 +08:00
|
|
|
this->LongLongWidth = 64;
|
|
|
|
this->LongLongAlign = 64;
|
2012-10-12 00:55:58 +08:00
|
|
|
this->SizeType = TargetInfo::UnsignedInt;
|
|
|
|
this->PtrDiffType = TargetInfo::SignedInt;
|
|
|
|
this->IntPtrType = TargetInfo::SignedInt;
|
2013-04-09 05:31:01 +08:00
|
|
|
// RegParmMax is inherited from the underlying architecture
|
2012-10-12 00:55:58 +08:00
|
|
|
this->LongDoubleFormat = &llvm::APFloat::IEEEdouble;
|
2013-12-19 07:41:04 +08:00
|
|
|
if (Triple.getArch() == llvm::Triple::arm) {
|
2014-01-04 03:22:05 +08:00
|
|
|
this->DescriptionString = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S128";
|
2013-12-19 07:41:04 +08:00
|
|
|
} else if (Triple.getArch() == llvm::Triple::x86) {
|
2014-01-04 03:22:05 +08:00
|
|
|
this->DescriptionString = "e-m:e-p:32:32-i64:64-n8:16:32-S128";
|
2013-12-19 07:41:04 +08:00
|
|
|
} else if (Triple.getArch() == llvm::Triple::x86_64) {
|
2014-01-04 03:22:05 +08:00
|
|
|
this->DescriptionString = "e-m:e-p:32:32-i64:64-n8:16:32:64-S128";
|
2013-12-19 07:41:04 +08:00
|
|
|
} else if (Triple.getArch() == llvm::Triple::mipsel) {
|
|
|
|
// Handled on mips' setDescriptionString.
|
|
|
|
} else {
|
|
|
|
assert(Triple.getArch() == llvm::Triple::le32);
|
|
|
|
this->DescriptionString = "e-p:32:32-i64:64";
|
|
|
|
}
|
2012-10-12 00:55:58 +08:00
|
|
|
}
|
2012-10-17 06:30:41 +08:00
|
|
|
virtual typename Target::CallingConvCheckResult checkCallingConvention(
|
|
|
|
CallingConv CC) const {
|
|
|
|
return CC == CC_PnaclCall ? Target::CCCR_OK :
|
|
|
|
Target::checkCallingConvention(CC);
|
|
|
|
}
|
2012-10-12 00:55:58 +08:00
|
|
|
};
|
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[];
|
2012-06-12 06:35:19 +08:00
|
|
|
std::string CPU;
|
2013-10-17 05:19:26 +08:00
|
|
|
|
|
|
|
// Target cpu features.
|
|
|
|
bool HasVSX;
|
|
|
|
|
2008-08-21 07:11:40 +08:00
|
|
|
public:
|
2013-10-17 05:19:26 +08:00
|
|
|
PPCTargetInfo(const llvm::Triple &Triple)
|
|
|
|
: TargetInfo(Triple), HasVSX(false) {
|
2013-07-26 09:36:11 +08:00
|
|
|
BigEndian = (Triple.getArch() != llvm::Triple::ppc64le);
|
2012-01-31 10:07:33 +08:00
|
|
|
LongDoubleWidth = LongDoubleAlign = 128;
|
|
|
|
LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble;
|
|
|
|
}
|
2009-06-05 15:05:05 +08:00
|
|
|
|
2012-07-04 00:51:04 +08:00
|
|
|
/// \brief Flags for architecture specific defines.
|
|
|
|
typedef enum {
|
|
|
|
ArchDefineNone = 0,
|
|
|
|
ArchDefineName = 1 << 0, // <name> is substituted for arch name.
|
|
|
|
ArchDefinePpcgr = 1 << 1,
|
|
|
|
ArchDefinePpcsq = 1 << 2,
|
|
|
|
ArchDefine440 = 1 << 3,
|
|
|
|
ArchDefine603 = 1 << 4,
|
|
|
|
ArchDefine604 = 1 << 5,
|
|
|
|
ArchDefinePwr4 = 1 << 6,
|
2013-02-02 04:23:10 +08:00
|
|
|
ArchDefinePwr5 = 1 << 7,
|
|
|
|
ArchDefinePwr5x = 1 << 8,
|
|
|
|
ArchDefinePwr6 = 1 << 9,
|
|
|
|
ArchDefinePwr6x = 1 << 10,
|
|
|
|
ArchDefinePwr7 = 1 << 11,
|
|
|
|
ArchDefineA2 = 1 << 12,
|
|
|
|
ArchDefineA2q = 1 << 13
|
2012-07-04 00:51:04 +08:00
|
|
|
} ArchDefineTypes;
|
|
|
|
|
2013-02-02 04:23:10 +08:00
|
|
|
// Note: GCC recognizes the following additional cpus:
|
|
|
|
// 401, 403, 405, 405fp, 440fp, 464, 464fp, 476, 476fp, 505, 740, 801,
|
|
|
|
// 821, 823, 8540, 8548, e300c2, e300c3, e500mc64, e6500, 860, cell,
|
|
|
|
// titan, rs64.
|
2012-06-12 06:35:19 +08:00
|
|
|
virtual bool setCPU(const std::string &Name) {
|
|
|
|
bool CPUKnown = llvm::StringSwitch<bool>(Name)
|
|
|
|
.Case("generic", true)
|
|
|
|
.Case("440", true)
|
|
|
|
.Case("450", true)
|
|
|
|
.Case("601", true)
|
|
|
|
.Case("602", true)
|
|
|
|
.Case("603", true)
|
|
|
|
.Case("603e", true)
|
|
|
|
.Case("603ev", true)
|
|
|
|
.Case("604", true)
|
|
|
|
.Case("604e", true)
|
|
|
|
.Case("620", true)
|
2013-02-02 04:23:10 +08:00
|
|
|
.Case("630", true)
|
2012-06-12 06:35:19 +08:00
|
|
|
.Case("g3", true)
|
|
|
|
.Case("7400", true)
|
|
|
|
.Case("g4", true)
|
|
|
|
.Case("7450", true)
|
|
|
|
.Case("g4+", true)
|
|
|
|
.Case("750", true)
|
|
|
|
.Case("970", true)
|
|
|
|
.Case("g5", true)
|
|
|
|
.Case("a2", true)
|
2013-02-01 13:53:33 +08:00
|
|
|
.Case("a2q", true)
|
2012-09-19 06:25:03 +08:00
|
|
|
.Case("e500mc", true)
|
|
|
|
.Case("e5500", true)
|
2013-02-02 04:23:10 +08:00
|
|
|
.Case("power3", true)
|
|
|
|
.Case("pwr3", true)
|
|
|
|
.Case("power4", true)
|
|
|
|
.Case("pwr4", true)
|
|
|
|
.Case("power5", true)
|
|
|
|
.Case("pwr5", true)
|
|
|
|
.Case("power5x", true)
|
|
|
|
.Case("pwr5x", true)
|
|
|
|
.Case("power6", true)
|
2012-06-12 06:35:19 +08:00
|
|
|
.Case("pwr6", true)
|
2013-02-02 04:23:10 +08:00
|
|
|
.Case("power6x", true)
|
|
|
|
.Case("pwr6x", true)
|
|
|
|
.Case("power7", true)
|
2012-06-12 06:35:19 +08:00
|
|
|
.Case("pwr7", true)
|
2013-02-02 04:23:10 +08:00
|
|
|
.Case("powerpc", true)
|
2012-06-12 06:35:19 +08:00
|
|
|
.Case("ppc", true)
|
2013-02-02 04:23:10 +08:00
|
|
|
.Case("powerpc64", true)
|
2012-06-12 06:35:19 +08:00
|
|
|
.Case("ppc64", true)
|
2013-07-26 09:36:11 +08:00
|
|
|
.Case("powerpc64le", true)
|
|
|
|
.Case("ppc64le", true)
|
2012-06-12 06:35:19 +08:00
|
|
|
.Default(false);
|
|
|
|
|
|
|
|
if (CPUKnown)
|
|
|
|
CPU = Name;
|
|
|
|
|
|
|
|
return CPUKnown;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
2012-01-29 02:02:29 +08:00
|
|
|
virtual bool isCLZForZeroUndef() const { return false; }
|
|
|
|
|
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
|
|
|
|
2013-02-01 10:14:03 +08:00
|
|
|
virtual void getDefaultFeatures(llvm::StringMap<bool> &Features) const;
|
|
|
|
|
2013-10-17 05:26:26 +08:00
|
|
|
virtual bool handleTargetFeatures(std::vector<std::string> &Features,
|
2013-10-17 05:19:26 +08:00
|
|
|
DiagnosticsEngine &Diags);
|
2012-01-30 14:38:25 +08:00
|
|
|
virtual bool hasFeature(StringRef Feature) const;
|
|
|
|
|
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
|
|
|
}
|
2013-01-23 04:02:45 +08:00
|
|
|
int getEHDataRegisterNumber(unsigned RegNo) const {
|
|
|
|
if (RegNo == 0) return 3;
|
|
|
|
if (RegNo == 1) return 4;
|
|
|
|
return -1;
|
|
|
|
}
|
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[] = {
|
2011-07-06 05:53:01 +08:00
|
|
|
#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
|
2010-12-01 01:35:24 +08:00
|
|
|
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
|
2011-07-06 05:53:01 +08:00
|
|
|
ALL_LANGUAGES },
|
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
|
|
|
|
2013-10-17 05:26:26 +08:00
|
|
|
/// handleTargetFeatures - Perform initialization based on the user
|
2013-10-17 05:19:26 +08:00
|
|
|
/// configured set of features.
|
2013-10-17 05:26:26 +08:00
|
|
|
bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
|
2013-10-17 05:19:26 +08:00
|
|
|
DiagnosticsEngine &Diags) {
|
|
|
|
// Remember the maximum enabled sselevel.
|
|
|
|
for (unsigned i = 0, e = Features.size(); i !=e; ++i) {
|
|
|
|
// Ignore disabled features.
|
|
|
|
if (Features[i][0] == '-')
|
|
|
|
continue;
|
|
|
|
|
|
|
|
StringRef Feature = StringRef(Features[i]).substr(1);
|
|
|
|
|
|
|
|
if (Feature == "vsx") {
|
|
|
|
HasVSX = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: Finish this list and add an assert that we've handled them
|
|
|
|
// all.
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
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__");
|
2013-06-25 19:13:47 +08:00
|
|
|
Builder.defineMacro("__PPC__");
|
2010-01-10 01:55:51 +08:00
|
|
|
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");
|
2010-02-17 02:14:57 +08:00
|
|
|
Builder.defineMacro("__powerpc64__");
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__ppc64__");
|
2013-06-25 19:13:47 +08:00
|
|
|
Builder.defineMacro("__PPC64__");
|
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.
|
2013-07-26 09:36:11 +08:00
|
|
|
if (getTriple().getArch() == llvm::Triple::ppc64le) {
|
|
|
|
Builder.defineMacro("_LITTLE_ENDIAN");
|
|
|
|
Builder.defineMacro("__LITTLE_ENDIAN__");
|
|
|
|
} else {
|
|
|
|
if (getTriple().getOS() != llvm::Triple::NetBSD &&
|
|
|
|
getTriple().getOS() != llvm::Triple::OpenBSD)
|
|
|
|
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.
|
2013-07-04 03:45:54 +08:00
|
|
|
if (LongDoubleWidth == 128)
|
|
|
|
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
|
|
|
}
|
2012-06-12 06:35:19 +08:00
|
|
|
|
|
|
|
// CPU identification.
|
2012-07-04 00:51:04 +08:00
|
|
|
ArchDefineTypes defs = (ArchDefineTypes)llvm::StringSwitch<int>(CPU)
|
|
|
|
.Case("440", ArchDefineName)
|
|
|
|
.Case("450", ArchDefineName | ArchDefine440)
|
|
|
|
.Case("601", ArchDefineName)
|
|
|
|
.Case("602", ArchDefineName | ArchDefinePpcgr)
|
|
|
|
.Case("603", ArchDefineName | ArchDefinePpcgr)
|
|
|
|
.Case("603e", ArchDefineName | ArchDefine603 | ArchDefinePpcgr)
|
|
|
|
.Case("603ev", ArchDefineName | ArchDefine603 | ArchDefinePpcgr)
|
|
|
|
.Case("604", ArchDefineName | ArchDefinePpcgr)
|
|
|
|
.Case("604e", ArchDefineName | ArchDefine604 | ArchDefinePpcgr)
|
|
|
|
.Case("620", ArchDefineName | ArchDefinePpcgr)
|
2013-02-02 04:23:10 +08:00
|
|
|
.Case("630", ArchDefineName | ArchDefinePpcgr)
|
2012-07-04 00:51:04 +08:00
|
|
|
.Case("7400", ArchDefineName | ArchDefinePpcgr)
|
|
|
|
.Case("7450", ArchDefineName | ArchDefinePpcgr)
|
|
|
|
.Case("750", ArchDefineName | ArchDefinePpcgr)
|
|
|
|
.Case("970", ArchDefineName | ArchDefinePwr4 | ArchDefinePpcgr
|
|
|
|
| ArchDefinePpcsq)
|
2013-02-01 13:53:33 +08:00
|
|
|
.Case("a2", ArchDefineA2)
|
|
|
|
.Case("a2q", ArchDefineName | ArchDefineA2 | ArchDefineA2q)
|
2013-02-02 04:23:10 +08:00
|
|
|
.Case("pwr3", ArchDefinePpcgr)
|
|
|
|
.Case("pwr4", ArchDefineName | ArchDefinePpcgr | ArchDefinePpcsq)
|
|
|
|
.Case("pwr5", ArchDefineName | ArchDefinePwr4 | ArchDefinePpcgr
|
|
|
|
| ArchDefinePpcsq)
|
|
|
|
.Case("pwr5x", ArchDefineName | ArchDefinePwr5 | ArchDefinePwr4
|
|
|
|
| ArchDefinePpcgr | ArchDefinePpcsq)
|
|
|
|
.Case("pwr6", ArchDefineName | ArchDefinePwr5x | ArchDefinePwr5
|
|
|
|
| ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
|
|
|
|
.Case("pwr6x", ArchDefineName | ArchDefinePwr6 | ArchDefinePwr5x
|
|
|
|
| ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr
|
|
|
|
| ArchDefinePpcsq)
|
|
|
|
.Case("pwr7", ArchDefineName | ArchDefinePwr6x | ArchDefinePwr6
|
|
|
|
| ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4
|
|
|
|
| ArchDefinePwr6 | ArchDefinePpcgr | ArchDefinePpcsq)
|
|
|
|
.Case("power3", ArchDefinePpcgr)
|
|
|
|
.Case("power4", ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
|
|
|
|
.Case("power5", ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr
|
|
|
|
| ArchDefinePpcsq)
|
|
|
|
.Case("power5x", ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4
|
|
|
|
| ArchDefinePpcgr | ArchDefinePpcsq)
|
|
|
|
.Case("power6", ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5
|
|
|
|
| ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
|
|
|
|
.Case("power6x", ArchDefinePwr6x | ArchDefinePwr6 | ArchDefinePwr5x
|
|
|
|
| ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr
|
|
|
|
| ArchDefinePpcsq)
|
|
|
|
.Case("power7", ArchDefinePwr7 | ArchDefinePwr6x | ArchDefinePwr6
|
|
|
|
| ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4
|
|
|
|
| ArchDefinePwr6 | ArchDefinePpcgr | ArchDefinePpcsq)
|
2012-07-04 00:51:04 +08:00
|
|
|
.Default(ArchDefineNone);
|
|
|
|
|
|
|
|
if (defs & ArchDefineName)
|
|
|
|
Builder.defineMacro(Twine("_ARCH_", StringRef(CPU).upper()));
|
|
|
|
if (defs & ArchDefinePpcgr)
|
|
|
|
Builder.defineMacro("_ARCH_PPCGR");
|
|
|
|
if (defs & ArchDefinePpcsq)
|
|
|
|
Builder.defineMacro("_ARCH_PPCSQ");
|
|
|
|
if (defs & ArchDefine440)
|
2012-06-12 06:35:19 +08:00
|
|
|
Builder.defineMacro("_ARCH_440");
|
2012-07-04 00:51:04 +08:00
|
|
|
if (defs & ArchDefine603)
|
|
|
|
Builder.defineMacro("_ARCH_603");
|
|
|
|
if (defs & ArchDefine604)
|
|
|
|
Builder.defineMacro("_ARCH_604");
|
2013-02-02 04:23:10 +08:00
|
|
|
if (defs & ArchDefinePwr4)
|
2012-07-04 00:51:04 +08:00
|
|
|
Builder.defineMacro("_ARCH_PWR4");
|
2013-02-02 04:23:10 +08:00
|
|
|
if (defs & ArchDefinePwr5)
|
2012-07-04 00:51:04 +08:00
|
|
|
Builder.defineMacro("_ARCH_PWR5");
|
2013-02-02 04:23:10 +08:00
|
|
|
if (defs & ArchDefinePwr5x)
|
|
|
|
Builder.defineMacro("_ARCH_PWR5X");
|
|
|
|
if (defs & ArchDefinePwr6)
|
2012-06-12 06:35:19 +08:00
|
|
|
Builder.defineMacro("_ARCH_PWR6");
|
2013-02-02 04:23:10 +08:00
|
|
|
if (defs & ArchDefinePwr6x)
|
|
|
|
Builder.defineMacro("_ARCH_PWR6X");
|
|
|
|
if (defs & ArchDefinePwr7)
|
|
|
|
Builder.defineMacro("_ARCH_PWR7");
|
2013-02-01 13:53:33 +08:00
|
|
|
if (defs & ArchDefineA2)
|
|
|
|
Builder.defineMacro("_ARCH_A2");
|
|
|
|
if (defs & ArchDefineA2q) {
|
|
|
|
Builder.defineMacro("_ARCH_A2Q");
|
|
|
|
Builder.defineMacro("_ARCH_QP");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (getTriple().getVendor() == llvm::Triple::BGQ) {
|
|
|
|
Builder.defineMacro("__bg__");
|
|
|
|
Builder.defineMacro("__THW_BLUEGENE__");
|
|
|
|
Builder.defineMacro("__bgq__");
|
|
|
|
Builder.defineMacro("__TOS_BGQ__");
|
|
|
|
}
|
2013-02-02 04:23:10 +08:00
|
|
|
|
2013-10-17 05:19:26 +08:00
|
|
|
if (HasVSX)
|
|
|
|
Builder.defineMacro("__VSX__");
|
|
|
|
|
2013-02-02 04:23:10 +08:00
|
|
|
// FIXME: The following are not yet generated here by Clang, but are
|
|
|
|
// generated by GCC:
|
|
|
|
//
|
|
|
|
// _SOFT_FLOAT_
|
|
|
|
// __RECIP_PRECISION__
|
|
|
|
// __APPLE_ALTIVEC__
|
|
|
|
// __RECIP__
|
|
|
|
// __RECIPF__
|
|
|
|
// __RSQRTE__
|
|
|
|
// __RSQRTEF__
|
|
|
|
// _SOFT_DOUBLE_
|
|
|
|
// __NO_LWSYNC__
|
|
|
|
// __HAVE_BSWAP__
|
|
|
|
// __LONGDOUBLE128
|
|
|
|
// __CMODEL_MEDIUM__
|
|
|
|
// __CMODEL_LARGE__
|
|
|
|
// _CALL_SYSV
|
|
|
|
// _CALL_DARWIN
|
|
|
|
// __NO_FPRS__
|
2013-02-01 10:14:03 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void PPCTargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const {
|
|
|
|
Features["altivec"] = llvm::StringSwitch<bool>(CPU)
|
|
|
|
.Case("7400", true)
|
|
|
|
.Case("g4", true)
|
|
|
|
.Case("7450", true)
|
|
|
|
.Case("g4+", true)
|
|
|
|
.Case("970", true)
|
|
|
|
.Case("g5", true)
|
|
|
|
.Case("pwr6", true)
|
|
|
|
.Case("pwr7", true)
|
|
|
|
.Case("ppc64", true)
|
2013-07-26 09:36:11 +08:00
|
|
|
.Case("ppc64le", true)
|
2013-02-01 10:14:03 +08:00
|
|
|
.Default(false);
|
2013-02-02 02:44:19 +08:00
|
|
|
|
|
|
|
Features["qpx"] = (CPU == "a2q");
|
2013-02-01 10:14:03 +08:00
|
|
|
}
|
|
|
|
|
2012-01-30 14:38:25 +08:00
|
|
|
bool PPCTargetInfo::hasFeature(StringRef Feature) const {
|
|
|
|
return Feature == "powerpc";
|
|
|
|
}
|
2008-04-22 02:56:49 +08:00
|
|
|
|
2012-01-30 14:38:25 +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:
|
2013-06-30 00:37:14 +08:00
|
|
|
PPC32TargetInfo(const llvm::Triple &Triple) : PPCTargetInfo(Triple) {
|
2014-01-04 03:22:05 +08:00
|
|
|
DescriptionString = "E-m:e-p:32:32-i64:64-n32";
|
2010-02-17 02:14:57 +08:00
|
|
|
|
2011-07-05 05:57:55 +08:00
|
|
|
switch (getTriple().getOS()) {
|
2012-01-31 10:07:33 +08:00
|
|
|
case llvm::Triple::Linux:
|
2011-07-05 05:57:55 +08:00
|
|
|
case llvm::Triple::FreeBSD:
|
|
|
|
case llvm::Triple::NetBSD:
|
2011-07-05 22:54:41 +08:00
|
|
|
SizeType = UnsignedInt;
|
2012-03-03 04:54:36 +08:00
|
|
|
PtrDiffType = SignedInt;
|
|
|
|
IntPtrType = SignedInt;
|
2011-07-05 22:54:41 +08:00
|
|
|
break;
|
2011-07-05 07:11:58 +08:00
|
|
|
default:
|
2011-07-05 22:54:41 +08:00
|
|
|
break;
|
2011-07-05 05:57:55 +08:00
|
|
|
}
|
2012-03-14 00:53:54 +08:00
|
|
|
|
2012-03-14 03:20:17 +08:00
|
|
|
if (getTriple().getOS() == llvm::Triple::FreeBSD) {
|
|
|
|
LongDoubleWidth = LongDoubleAlign = 64;
|
2012-03-14 00:53:54 +08:00
|
|
|
LongDoubleFormat = &llvm::APFloat::IEEEdouble;
|
2012-03-14 03:20:17 +08:00
|
|
|
}
|
2012-11-18 01:30:55 +08:00
|
|
|
|
|
|
|
// PPC32 supports atomics up to 4 bytes.
|
|
|
|
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32;
|
2011-01-06 16:27:10 +08:00
|
|
|
}
|
|
|
|
|
2012-06-16 11:34:49 +08:00
|
|
|
virtual BuiltinVaListKind getBuiltinVaListKind() const {
|
2011-01-06 16:27:10 +08:00
|
|
|
// This is the ELF definition, and is overridden by the Darwin sub-target
|
2012-06-16 11:34:49 +08:00
|
|
|
return TargetInfo::PowerABIBuiltinVaList;
|
2008-08-21 08:13:15 +08:00
|
|
|
}
|
2006-10-14 15:39:34 +08:00
|
|
|
};
|
|
|
|
} // end anonymous namespace.
|
|
|
|
|
2013-07-26 09:36:11 +08:00
|
|
|
// Note: ABI differences may eventually require us to have a separate
|
|
|
|
// TargetInfo for little endian.
|
2006-10-14 15:39:34 +08:00
|
|
|
namespace {
|
2008-08-21 07:11:40 +08:00
|
|
|
class PPC64TargetInfo : public PPCTargetInfo {
|
2006-10-14 15:39:34 +08:00
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
PPC64TargetInfo(const llvm::Triple &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;
|
2012-03-14 00:53:54 +08:00
|
|
|
|
2012-03-14 03:20:17 +08:00
|
|
|
if (getTriple().getOS() == llvm::Triple::FreeBSD) {
|
|
|
|
LongDoubleWidth = LongDoubleAlign = 64;
|
2012-03-14 00:53:54 +08:00
|
|
|
LongDoubleFormat = &llvm::APFloat::IEEEdouble;
|
2014-01-04 03:22:05 +08:00
|
|
|
DescriptionString = "E-m:e-i64:64-n32:64";
|
2012-10-29 22:59:24 +08:00
|
|
|
} else
|
2014-01-04 03:22:05 +08:00
|
|
|
DescriptionString = "E-m:e-i64:64-n32:64";
|
2012-11-18 01:30:55 +08:00
|
|
|
|
|
|
|
// PPC64 supports atomics up to 8 bytes.
|
|
|
|
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
|
2008-05-09 14:17:04 +08:00
|
|
|
}
|
2012-06-16 11:34:49 +08:00
|
|
|
virtual BuiltinVaListKind getBuiltinVaListKind() const {
|
|
|
|
return TargetInfo::CharPtrBuiltinVaList;
|
2011-01-06 16:27:10 +08:00
|
|
|
}
|
2008-08-21 07:11:40 +08:00
|
|
|
};
|
|
|
|
} // end anonymous namespace.
|
|
|
|
|
2010-05-30 08:07:30 +08:00
|
|
|
|
|
|
|
namespace {
|
2011-01-06 16:27:10 +08:00
|
|
|
class DarwinPPC32TargetInfo :
|
|
|
|
public DarwinTargetInfo<PPC32TargetInfo> {
|
2010-05-30 08:07:30 +08:00
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
DarwinPPC32TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: DarwinTargetInfo<PPC32TargetInfo>(Triple) {
|
2010-05-30 08:07:30 +08:00
|
|
|
HasAlignMac68kSupport = true;
|
2011-01-06 16:27:10 +08:00
|
|
|
BoolWidth = BoolAlign = 32; //XXX support -mone-byte-bool?
|
2013-10-17 05:19:19 +08:00
|
|
|
PtrDiffType = SignedInt; // for http://llvm.org/bugs/show_bug.cgi?id=15726
|
2012-01-18 06:40:00 +08:00
|
|
|
LongLongAlign = 32;
|
2011-12-21 12:25:47 +08:00
|
|
|
SuitableAlign = 128;
|
2014-01-04 03:22:05 +08:00
|
|
|
DescriptionString = "E-m:o-p:32:32-f64:32:64-n32";
|
2011-01-06 16:27:10 +08:00
|
|
|
}
|
2012-06-16 11:34:49 +08:00
|
|
|
virtual BuiltinVaListKind getBuiltinVaListKind() const {
|
|
|
|
return TargetInfo::CharPtrBuiltinVaList;
|
2010-05-30 08:07:30 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class DarwinPPC64TargetInfo :
|
|
|
|
public DarwinTargetInfo<PPC64TargetInfo> {
|
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
DarwinPPC64TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: DarwinTargetInfo<PPC64TargetInfo>(Triple) {
|
2010-05-30 08:07:30 +08:00
|
|
|
HasAlignMac68kSupport = true;
|
2011-12-21 12:25:47 +08:00
|
|
|
SuitableAlign = 128;
|
2014-01-04 03:22:05 +08:00
|
|
|
DescriptionString = "E-m:o-i64:64-n32:64";
|
2010-05-30 08:07:30 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
} // end anonymous namespace.
|
|
|
|
|
2011-04-21 03:34:15 +08:00
|
|
|
namespace {
|
2012-05-25 01:43:12 +08:00
|
|
|
static const unsigned NVPTXAddrSpaceMap[] = {
|
|
|
|
1, // opencl_global
|
|
|
|
3, // opencl_local
|
|
|
|
4, // opencl_constant
|
|
|
|
1, // cuda_device
|
|
|
|
4, // cuda_constant
|
|
|
|
3, // cuda_shared
|
2011-10-04 01:28:37 +08:00
|
|
|
};
|
2012-05-25 01:43:12 +08:00
|
|
|
class NVPTXTargetInfo : public TargetInfo {
|
2011-04-21 03:34:15 +08:00
|
|
|
static const char * const GCCRegNames[];
|
|
|
|
static const Builtin::Info BuiltinInfo[];
|
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
NVPTXTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
|
2011-12-22 11:51:45 +08:00
|
|
|
BigEndian = false;
|
2011-04-21 03:34:15 +08:00
|
|
|
TLSSupported = false;
|
|
|
|
LongWidth = LongAlign = 64;
|
2012-05-25 01:43:12 +08:00
|
|
|
AddrSpaceMap = &NVPTXAddrSpaceMap;
|
2013-09-13 20:04:22 +08:00
|
|
|
UseAddrSpaceMapMangling = true;
|
2011-09-23 01:57:40 +08:00
|
|
|
// Define available target features
|
2012-05-25 01:43:12 +08:00
|
|
|
// These must be defined in sorted order!
|
2012-07-11 23:34:55 +08:00
|
|
|
NoAsmVariants = true;
|
2011-04-21 03:34:15 +08:00
|
|
|
}
|
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
Builder.defineMacro("__PTX__");
|
2012-05-25 01:43:12 +08:00
|
|
|
Builder.defineMacro("__NVPTX__");
|
2011-04-21 03:34:15 +08:00
|
|
|
}
|
|
|
|
virtual void getTargetBuiltins(const Builtin::Info *&Records,
|
|
|
|
unsigned &NumRecords) const {
|
|
|
|
Records = BuiltinInfo;
|
2012-05-25 01:43:12 +08:00
|
|
|
NumRecords = clang::NVPTX::LastTSBuiltin-Builtin::FirstTSBuiltin;
|
2011-04-21 03:34:15 +08:00
|
|
|
}
|
2012-01-30 14:38:25 +08:00
|
|
|
virtual bool hasFeature(StringRef Feature) const {
|
2012-05-25 01:43:12 +08:00
|
|
|
return Feature == "ptx" || Feature == "nvptx";
|
2012-01-30 14:38:25 +08:00
|
|
|
}
|
|
|
|
|
2011-04-21 03:34:15 +08:00
|
|
|
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,
|
2013-06-22 02:51:24 +08:00
|
|
|
TargetInfo::ConstraintInfo &Info) const {
|
|
|
|
switch (*Name) {
|
|
|
|
default: return false;
|
|
|
|
case 'c':
|
|
|
|
case 'h':
|
|
|
|
case 'r':
|
|
|
|
case 'l':
|
|
|
|
case 'f':
|
|
|
|
case 'd':
|
|
|
|
Info.setAllowsRegister();
|
|
|
|
return true;
|
|
|
|
}
|
2011-04-21 03:34:15 +08:00
|
|
|
}
|
|
|
|
virtual const char *getClobbers() const {
|
|
|
|
// FIXME: Is this really right?
|
|
|
|
return "";
|
|
|
|
}
|
2012-06-16 11:34:49 +08:00
|
|
|
virtual BuiltinVaListKind getBuiltinVaListKind() const {
|
2011-04-21 03:34:15 +08:00
|
|
|
// FIXME: implement
|
2012-06-16 11:34:49 +08:00
|
|
|
return TargetInfo::CharPtrBuiltinVaList;
|
2011-04-21 03:34:15 +08:00
|
|
|
}
|
2012-05-25 01:43:12 +08:00
|
|
|
virtual bool setCPU(const std::string &Name) {
|
2013-03-30 22:38:26 +08:00
|
|
|
bool Valid = llvm::StringSwitch<bool>(Name)
|
|
|
|
.Case("sm_20", true)
|
|
|
|
.Case("sm_21", true)
|
|
|
|
.Case("sm_30", true)
|
|
|
|
.Case("sm_35", true)
|
|
|
|
.Default(false);
|
|
|
|
|
|
|
|
return Valid;
|
2012-05-25 01:43:12 +08:00
|
|
|
}
|
2011-04-21 03:34:15 +08:00
|
|
|
};
|
|
|
|
|
2012-05-25 01:43:12 +08:00
|
|
|
const Builtin::Info NVPTXTargetInfo::BuiltinInfo[] = {
|
2011-07-06 05:53:01 +08:00
|
|
|
#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
|
2011-04-21 03:34:15 +08:00
|
|
|
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
|
2011-07-06 05:53:01 +08:00
|
|
|
ALL_LANGUAGES },
|
2012-05-25 01:43:12 +08:00
|
|
|
#include "clang/Basic/BuiltinsNVPTX.def"
|
2011-04-21 03:34:15 +08:00
|
|
|
};
|
|
|
|
|
2012-05-25 01:43:12 +08:00
|
|
|
const char * const NVPTXTargetInfo::GCCRegNames[] = {
|
2011-04-21 03:34:15 +08:00
|
|
|
"r0"
|
|
|
|
};
|
|
|
|
|
2012-05-25 01:43:12 +08:00
|
|
|
void NVPTXTargetInfo::getGCCRegNames(const char * const *&Names,
|
2011-04-21 03:34:15 +08:00
|
|
|
unsigned &NumNames) const {
|
|
|
|
Names = GCCRegNames;
|
|
|
|
NumNames = llvm::array_lengthof(GCCRegNames);
|
|
|
|
}
|
|
|
|
|
2012-05-21 07:28:41 +08:00
|
|
|
class NVPTX32TargetInfo : public NVPTXTargetInfo {
|
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
NVPTX32TargetInfo(const llvm::Triple &Triple) : NVPTXTargetInfo(Triple) {
|
2012-05-21 07:28:41 +08:00
|
|
|
PointerWidth = PointerAlign = 32;
|
2012-05-25 01:43:12 +08:00
|
|
|
SizeType = PtrDiffType = IntPtrType = TargetInfo::UnsignedInt;
|
2014-01-04 02:13:17 +08:00
|
|
|
DescriptionString = "e-p:32:32-i64:64-v16:16-v32:32-n16:32:64";
|
2012-05-25 01:43:12 +08:00
|
|
|
}
|
2012-05-21 07:28:41 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
class NVPTX64TargetInfo : public NVPTXTargetInfo {
|
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
NVPTX64TargetInfo(const llvm::Triple &Triple) : NVPTXTargetInfo(Triple) {
|
2012-05-21 07:28:41 +08:00
|
|
|
PointerWidth = PointerAlign = 64;
|
2012-05-25 01:43:12 +08:00
|
|
|
SizeType = PtrDiffType = IntPtrType = TargetInfo::UnsignedLongLong;
|
2014-01-04 02:13:17 +08:00
|
|
|
DescriptionString = "e-i64:64-v16:16-v32:32-n16:32:64";
|
2012-05-25 01:43:12 +08:00
|
|
|
}
|
2012-05-21 07:28:41 +08:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2012-10-13 07:32:00 +08:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
static const unsigned R600AddrSpaceMap[] = {
|
|
|
|
1, // opencl_global
|
|
|
|
3, // opencl_local
|
|
|
|
2, // opencl_constant
|
|
|
|
1, // cuda_device
|
|
|
|
2, // cuda_constant
|
|
|
|
3 // cuda_shared
|
|
|
|
};
|
|
|
|
|
2013-03-05 01:40:53 +08:00
|
|
|
static const char *DescriptionStringR600 =
|
2014-01-04 02:13:17 +08:00
|
|
|
"e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128"
|
|
|
|
"-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64";
|
2013-03-05 01:40:53 +08:00
|
|
|
|
|
|
|
static const char *DescriptionStringR600DoubleOps =
|
2014-01-04 02:13:17 +08:00
|
|
|
"e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128"
|
|
|
|
"-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64";
|
2013-03-05 01:40:53 +08:00
|
|
|
|
|
|
|
static const char *DescriptionStringSI =
|
2014-01-04 02:13:17 +08:00
|
|
|
"e-p:32:32-p1:64:64-p2:64:64-p3:32:32-p4:32:32-p5:64:64"
|
|
|
|
"-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128"
|
|
|
|
"-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64";
|
2013-03-05 01:40:53 +08:00
|
|
|
|
2012-10-13 07:32:00 +08:00
|
|
|
class R600TargetInfo : public TargetInfo {
|
2013-03-05 01:40:53 +08:00
|
|
|
/// \brief The GPU profiles supported by the R600 target.
|
|
|
|
enum GPUKind {
|
|
|
|
GK_NONE,
|
|
|
|
GK_R600,
|
|
|
|
GK_R600_DOUBLE_OPS,
|
|
|
|
GK_R700,
|
|
|
|
GK_R700_DOUBLE_OPS,
|
|
|
|
GK_EVERGREEN,
|
|
|
|
GK_EVERGREEN_DOUBLE_OPS,
|
|
|
|
GK_NORTHERN_ISLANDS,
|
|
|
|
GK_CAYMAN,
|
2013-10-30 00:38:29 +08:00
|
|
|
GK_SOUTHERN_ISLANDS,
|
|
|
|
GK_SEA_ISLANDS
|
2013-03-05 01:40:53 +08:00
|
|
|
} GPU;
|
|
|
|
|
2012-10-13 07:32:00 +08:00
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
R600TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: TargetInfo(Triple), GPU(GK_R600) {
|
2013-03-05 01:40:53 +08:00
|
|
|
DescriptionString = DescriptionStringR600;
|
2012-10-13 07:32:00 +08:00
|
|
|
AddrSpaceMap = &R600AddrSpaceMap;
|
2013-09-13 20:04:22 +08:00
|
|
|
UseAddrSpaceMapMangling = true;
|
2012-10-13 07:32:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
virtual const char * getClobbers() const {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void getGCCRegNames(const char * const *&Names,
|
|
|
|
unsigned &numNames) const {
|
|
|
|
Names = NULL;
|
|
|
|
numNames = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
|
|
|
|
unsigned &NumAliases) const {
|
|
|
|
Aliases = NULL;
|
|
|
|
NumAliases = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual bool validateAsmConstraint(const char *&Name,
|
|
|
|
TargetInfo::ConstraintInfo &info) const {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void getTargetBuiltins(const Builtin::Info *&Records,
|
|
|
|
unsigned &NumRecords) const {
|
|
|
|
Records = NULL;
|
|
|
|
NumRecords = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
Builder.defineMacro("__R600__");
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual BuiltinVaListKind getBuiltinVaListKind() const {
|
|
|
|
return TargetInfo::CharPtrBuiltinVaList;
|
|
|
|
}
|
|
|
|
|
2013-03-05 01:40:53 +08:00
|
|
|
virtual bool setCPU(const std::string &Name) {
|
|
|
|
GPU = llvm::StringSwitch<GPUKind>(Name)
|
|
|
|
.Case("r600" , GK_R600)
|
|
|
|
.Case("rv610", GK_R600)
|
|
|
|
.Case("rv620", GK_R600)
|
|
|
|
.Case("rv630", GK_R600)
|
|
|
|
.Case("rv635", GK_R600)
|
|
|
|
.Case("rs780", GK_R600)
|
|
|
|
.Case("rs880", GK_R600)
|
|
|
|
.Case("rv670", GK_R600_DOUBLE_OPS)
|
|
|
|
.Case("rv710", GK_R700)
|
|
|
|
.Case("rv730", GK_R700)
|
|
|
|
.Case("rv740", GK_R700_DOUBLE_OPS)
|
|
|
|
.Case("rv770", GK_R700_DOUBLE_OPS)
|
|
|
|
.Case("palm", GK_EVERGREEN)
|
|
|
|
.Case("cedar", GK_EVERGREEN)
|
|
|
|
.Case("sumo", GK_EVERGREEN)
|
|
|
|
.Case("sumo2", GK_EVERGREEN)
|
|
|
|
.Case("redwood", GK_EVERGREEN)
|
|
|
|
.Case("juniper", GK_EVERGREEN)
|
|
|
|
.Case("hemlock", GK_EVERGREEN_DOUBLE_OPS)
|
|
|
|
.Case("cypress", GK_EVERGREEN_DOUBLE_OPS)
|
|
|
|
.Case("barts", GK_NORTHERN_ISLANDS)
|
|
|
|
.Case("turks", GK_NORTHERN_ISLANDS)
|
|
|
|
.Case("caicos", GK_NORTHERN_ISLANDS)
|
|
|
|
.Case("cayman", GK_CAYMAN)
|
|
|
|
.Case("aruba", GK_CAYMAN)
|
2013-04-02 04:56:49 +08:00
|
|
|
.Case("tahiti", GK_SOUTHERN_ISLANDS)
|
2013-03-05 01:40:53 +08:00
|
|
|
.Case("pitcairn", GK_SOUTHERN_ISLANDS)
|
|
|
|
.Case("verde", GK_SOUTHERN_ISLANDS)
|
|
|
|
.Case("oland", GK_SOUTHERN_ISLANDS)
|
2013-10-30 00:38:29 +08:00
|
|
|
.Case("bonaire", GK_SEA_ISLANDS)
|
|
|
|
.Case("kabini", GK_SEA_ISLANDS)
|
|
|
|
.Case("kaveri", GK_SEA_ISLANDS)
|
2013-11-15 07:45:53 +08:00
|
|
|
.Case("hawaii", GK_SEA_ISLANDS)
|
2013-03-05 01:40:53 +08:00
|
|
|
.Default(GK_NONE);
|
|
|
|
|
|
|
|
if (GPU == GK_NONE) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the correct data layout
|
|
|
|
switch (GPU) {
|
|
|
|
case GK_NONE:
|
|
|
|
case GK_R600:
|
|
|
|
case GK_R700:
|
|
|
|
case GK_EVERGREEN:
|
|
|
|
case GK_NORTHERN_ISLANDS:
|
|
|
|
DescriptionString = DescriptionStringR600;
|
|
|
|
break;
|
|
|
|
case GK_R600_DOUBLE_OPS:
|
|
|
|
case GK_R700_DOUBLE_OPS:
|
|
|
|
case GK_EVERGREEN_DOUBLE_OPS:
|
|
|
|
case GK_CAYMAN:
|
|
|
|
DescriptionString = DescriptionStringR600DoubleOps;
|
|
|
|
break;
|
|
|
|
case GK_SOUTHERN_ISLANDS:
|
2013-10-30 00:38:29 +08:00
|
|
|
case GK_SEA_ISLANDS:
|
2013-03-05 01:40:53 +08:00
|
|
|
DescriptionString = DescriptionStringSI;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2012-10-13 07:32:00 +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[] = {
|
2011-07-06 05:53:01 +08:00
|
|
|
#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
|
2010-12-01 01:35:24 +08:00
|
|
|
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
|
2011-07-06 05:53:01 +08:00
|
|
|
ALL_LANGUAGES },
|
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)",
|
2011-07-08 06:55:26 +08:00
|
|
|
"argp", "flags", "fpcr", "fpsr", "dirflag", "frame",
|
2008-08-20 10:34:37 +08:00
|
|
|
"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
|
|
|
|
"mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
|
|
|
|
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
|
2011-06-21 08:05:20 +08:00
|
|
|
"xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15",
|
2011-12-02 10:12:16 +08:00
|
|
|
"ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7",
|
|
|
|
"ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15",
|
2008-08-20 10:34:37 +08:00
|
|
|
};
|
|
|
|
|
2011-06-21 08:05:20 +08:00
|
|
|
const TargetInfo::AddlRegName AddlRegNames[] = {
|
|
|
|
{ { "al", "ah", "eax", "rax" }, 0 },
|
|
|
|
{ { "bl", "bh", "ebx", "rbx" }, 3 },
|
|
|
|
{ { "cl", "ch", "ecx", "rcx" }, 2 },
|
|
|
|
{ { "dl", "dh", "edx", "rdx" }, 1 },
|
|
|
|
{ { "esi", "rsi" }, 4 },
|
|
|
|
{ { "edi", "rdi" }, 5 },
|
|
|
|
{ { "esp", "rsp" }, 7 },
|
|
|
|
{ { "ebp", "rbp" }, 6 },
|
2008-08-20 10:34:37 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
// 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 {
|
2013-08-21 11:59:22 +08:00
|
|
|
NoSSE, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, AVX, AVX2, AVX512F
|
2009-03-03 06:40:39 +08:00
|
|
|
} SSELevel;
|
2011-07-09 07:31:17 +08:00
|
|
|
enum MMX3DNowEnum {
|
|
|
|
NoMMX3DNow, MMX, AMD3DNow, AMD3DNowAthlon
|
|
|
|
} MMX3DNowLevel;
|
2013-08-20 21:44:29 +08:00
|
|
|
enum XOPEnum {
|
|
|
|
NoXOP,
|
|
|
|
SSE4A,
|
|
|
|
FMA4,
|
|
|
|
XOP
|
|
|
|
} XOPLevel;
|
2010-01-27 11:47:49 +08:00
|
|
|
|
2010-04-03 07:50:19 +08:00
|
|
|
bool HasAES;
|
2012-05-31 13:18:48 +08:00
|
|
|
bool HasPCLMUL;
|
2011-12-25 13:06:45 +08:00
|
|
|
bool HasLZCNT;
|
2012-07-07 17:39:18 +08:00
|
|
|
bool HasRDRND;
|
2011-12-25 13:06:45 +08:00
|
|
|
bool HasBMI;
|
|
|
|
bool HasBMI2;
|
2011-12-30 00:10:46 +08:00
|
|
|
bool HasPOPCNT;
|
2012-11-10 13:17:46 +08:00
|
|
|
bool HasRTM;
|
2013-03-27 01:52:08 +08:00
|
|
|
bool HasPRFCHW;
|
2013-03-29 13:17:55 +08:00
|
|
|
bool HasRDSEED;
|
2013-09-25 03:00:58 +08:00
|
|
|
bool HasTBM;
|
2012-06-04 05:46:30 +08:00
|
|
|
bool HasFMA;
|
2012-10-11 08:59:55 +08:00
|
|
|
bool HasF16C;
|
2013-08-21 13:29:10 +08:00
|
|
|
bool HasAVX512CD, HasAVX512ER, HasAVX512PF;
|
2013-09-19 21:22:04 +08:00
|
|
|
bool HasSHA;
|
2013-10-06 04:14:27 +08:00
|
|
|
bool HasCX16;
|
2010-08-05 06:29:13 +08:00
|
|
|
|
2011-09-28 16:55:34 +08:00
|
|
|
/// \brief Enumeration of all of the X86 CPUs supported by Clang.
|
|
|
|
///
|
|
|
|
/// Each enumeration represents a particular CPU supported by Clang. These
|
|
|
|
/// loosely correspond to the options passed to '-march' or '-mtune' flags.
|
|
|
|
enum CPUKind {
|
|
|
|
CK_Generic,
|
|
|
|
|
|
|
|
/// \name i386
|
|
|
|
/// i386-generation processors.
|
|
|
|
//@{
|
|
|
|
CK_i386,
|
|
|
|
//@}
|
|
|
|
|
|
|
|
/// \name i486
|
|
|
|
/// i486-generation processors.
|
|
|
|
//@{
|
|
|
|
CK_i486,
|
|
|
|
CK_WinChipC6,
|
|
|
|
CK_WinChip2,
|
|
|
|
CK_C3,
|
|
|
|
//@}
|
|
|
|
|
|
|
|
/// \name i586
|
|
|
|
/// i586-generation processors, P5 microarchitecture based.
|
|
|
|
//@{
|
|
|
|
CK_i586,
|
|
|
|
CK_Pentium,
|
|
|
|
CK_PentiumMMX,
|
|
|
|
//@}
|
|
|
|
|
|
|
|
/// \name i686
|
|
|
|
/// i686-generation processors, P6 / Pentium M microarchitecture based.
|
|
|
|
//@{
|
|
|
|
CK_i686,
|
|
|
|
CK_PentiumPro,
|
|
|
|
CK_Pentium2,
|
|
|
|
CK_Pentium3,
|
|
|
|
CK_Pentium3M,
|
|
|
|
CK_PentiumM,
|
|
|
|
CK_C3_2,
|
|
|
|
|
|
|
|
/// This enumerator is a bit odd, as GCC no longer accepts -march=yonah.
|
|
|
|
/// Clang however has some logic to suport this.
|
|
|
|
// FIXME: Warn, deprecate, and potentially remove this.
|
|
|
|
CK_Yonah,
|
|
|
|
//@}
|
|
|
|
|
|
|
|
/// \name Netburst
|
2011-09-29 02:17:30 +08:00
|
|
|
/// Netburst microarchitecture based processors.
|
2011-09-28 16:55:34 +08:00
|
|
|
//@{
|
|
|
|
CK_Pentium4,
|
|
|
|
CK_Pentium4M,
|
|
|
|
CK_Prescott,
|
|
|
|
CK_Nocona,
|
|
|
|
//@}
|
|
|
|
|
|
|
|
/// \name Core
|
|
|
|
/// Core microarchitecture based processors.
|
|
|
|
//@{
|
|
|
|
CK_Core2,
|
|
|
|
|
|
|
|
/// This enumerator, like \see CK_Yonah, is a bit odd. It is another
|
|
|
|
/// codename which GCC no longer accepts as an option to -march, but Clang
|
|
|
|
/// has some logic for recognizing it.
|
|
|
|
// FIXME: Warn, deprecate, and potentially remove this.
|
|
|
|
CK_Penryn,
|
|
|
|
//@}
|
|
|
|
|
|
|
|
/// \name Atom
|
|
|
|
/// Atom processors
|
|
|
|
//@{
|
|
|
|
CK_Atom,
|
2013-09-14 03:27:17 +08:00
|
|
|
CK_Silvermont,
|
2011-09-28 16:55:34 +08:00
|
|
|
//@}
|
|
|
|
|
|
|
|
/// \name Nehalem
|
|
|
|
/// Nehalem microarchitecture based processors.
|
|
|
|
//@{
|
|
|
|
CK_Corei7,
|
|
|
|
CK_Corei7AVX,
|
2011-09-28 16:55:37 +08:00
|
|
|
CK_CoreAVXi,
|
2011-12-18 03:55:21 +08:00
|
|
|
CK_CoreAVX2,
|
2011-09-28 16:55:34 +08:00
|
|
|
//@}
|
|
|
|
|
2013-08-20 15:09:39 +08:00
|
|
|
/// \name Knights Landing
|
|
|
|
/// Knights Landing processor.
|
|
|
|
CK_KNL,
|
|
|
|
|
2011-09-28 16:55:34 +08:00
|
|
|
/// \name K6
|
|
|
|
/// K6 architecture processors.
|
|
|
|
//@{
|
|
|
|
CK_K6,
|
|
|
|
CK_K6_2,
|
|
|
|
CK_K6_3,
|
|
|
|
//@}
|
|
|
|
|
|
|
|
/// \name K7
|
|
|
|
/// K7 architecture processors.
|
|
|
|
//@{
|
|
|
|
CK_Athlon,
|
|
|
|
CK_AthlonThunderbird,
|
|
|
|
CK_Athlon4,
|
|
|
|
CK_AthlonXP,
|
|
|
|
CK_AthlonMP,
|
|
|
|
//@}
|
|
|
|
|
|
|
|
/// \name K8
|
|
|
|
/// K8 architecture processors.
|
|
|
|
//@{
|
|
|
|
CK_Athlon64,
|
|
|
|
CK_Athlon64SSE3,
|
|
|
|
CK_AthlonFX,
|
|
|
|
CK_K8,
|
2011-09-28 16:55:37 +08:00
|
|
|
CK_K8SSE3,
|
2011-09-28 16:55:34 +08:00
|
|
|
CK_Opteron,
|
|
|
|
CK_OpteronSSE3,
|
2011-10-30 15:48:46 +08:00
|
|
|
CK_AMDFAM10,
|
2012-01-10 19:50:18 +08:00
|
|
|
//@}
|
|
|
|
|
|
|
|
/// \name Bobcat
|
|
|
|
/// Bobcat architecture processors.
|
|
|
|
//@{
|
|
|
|
CK_BTVER1,
|
2013-05-03 18:47:15 +08:00
|
|
|
CK_BTVER2,
|
2012-01-10 19:50:18 +08:00
|
|
|
//@}
|
2011-09-28 16:55:34 +08:00
|
|
|
|
2012-01-10 19:50:18 +08:00
|
|
|
/// \name Bulldozer
|
|
|
|
/// Bulldozer architecture processors.
|
2011-12-02 02:23:59 +08:00
|
|
|
//@{
|
|
|
|
CK_BDVER1,
|
|
|
|
CK_BDVER2,
|
2013-11-04 18:29:51 +08:00
|
|
|
CK_BDVER3,
|
2012-01-10 19:50:18 +08:00
|
|
|
//@}
|
2011-12-02 02:23:59 +08:00
|
|
|
|
2011-09-28 16:55:34 +08:00
|
|
|
/// This specification is deprecated and will be removed in the future.
|
|
|
|
/// Users should prefer \see CK_K8.
|
|
|
|
// FIXME: Warn on this when the CPU is set to it.
|
|
|
|
CK_x86_64,
|
|
|
|
//@}
|
|
|
|
|
|
|
|
/// \name Geode
|
|
|
|
/// Geode processors.
|
|
|
|
//@{
|
|
|
|
CK_Geode
|
|
|
|
//@}
|
2011-09-28 16:55:37 +08:00
|
|
|
} CPU;
|
2011-09-28 16:55:34 +08:00
|
|
|
|
2013-08-22 05:59:03 +08:00
|
|
|
enum FPMathKind {
|
|
|
|
FP_Default,
|
|
|
|
FP_SSE,
|
|
|
|
FP_387
|
|
|
|
} FPMath;
|
|
|
|
|
2006-10-14 15:39:34 +08:00
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
X86TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: TargetInfo(Triple), SSELevel(NoSSE), MMX3DNowLevel(NoMMX3DNow),
|
2013-08-20 21:44:29 +08:00
|
|
|
XOPLevel(NoXOP), HasAES(false), HasPCLMUL(false), HasLZCNT(false),
|
|
|
|
HasRDRND(false), HasBMI(false), HasBMI2(false), HasPOPCNT(false),
|
2013-09-25 03:00:58 +08:00
|
|
|
HasRTM(false), HasPRFCHW(false), HasRDSEED(false), HasTBM(false),
|
|
|
|
HasFMA(false), HasF16C(false), HasAVX512CD(false), HasAVX512ER(false),
|
2013-10-06 04:14:27 +08:00
|
|
|
HasAVX512PF(false), HasSHA(false), HasCX16(false), CPU(CK_Generic),
|
|
|
|
FPMath(FP_Default) {
|
2011-12-22 11:51:45 +08:00
|
|
|
BigEndian = false;
|
2008-05-20 22:21:01 +08:00
|
|
|
LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
|
|
|
|
}
|
2011-12-28 23:47:06 +08:00
|
|
|
virtual unsigned getFloatEvalMethod() const {
|
|
|
|
// X87 evaluates with 80 bits "long double" precision.
|
|
|
|
return SSELevel == NoSSE ? 2 : 0;
|
|
|
|
}
|
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 {
|
2011-06-21 08:05:20 +08:00
|
|
|
Aliases = 0;
|
|
|
|
NumAliases = 0;
|
|
|
|
}
|
|
|
|
virtual void getGCCAddlRegNames(const AddlRegName *&Names,
|
2012-11-15 06:08:59 +08:00
|
|
|
unsigned &NumNames) const {
|
2011-06-21 08:05:20 +08:00
|
|
|
Names = AddlRegNames;
|
|
|
|
NumNames = llvm::array_lengthof(AddlRegNames);
|
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;
|
2011-06-08 07:45:05 +08:00
|
|
|
virtual std::string convertConstraint(const char *&Constraint) const;
|
2008-08-20 10:34:37 +08:00
|
|
|
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;
|
2013-09-17 12:12:55 +08:00
|
|
|
static void setSSELevel(llvm::StringMap<bool> &Features, X86SSEEnum Level,
|
|
|
|
bool Enabled);
|
|
|
|
static void setMMXLevel(llvm::StringMap<bool> &Features, MMX3DNowEnum Level,
|
|
|
|
bool Enabled);
|
|
|
|
static void setXOPLevel(llvm::StringMap<bool> &Features, XOPEnum Level,
|
|
|
|
bool Enabled);
|
2013-08-20 23:30:32 +08:00
|
|
|
virtual void setFeatureEnabled(llvm::StringMap<bool> &Features,
|
2013-09-17 12:51:29 +08:00
|
|
|
StringRef Name, bool Enabled) const {
|
|
|
|
setFeatureEnabledImpl(Features, Name, Enabled);
|
|
|
|
}
|
|
|
|
// This exists purely to cut down on the number of virtual calls in
|
|
|
|
// getDefaultFeatures which calls this repeatedly.
|
|
|
|
static void setFeatureEnabledImpl(llvm::StringMap<bool> &Features,
|
|
|
|
StringRef Name, bool Enabled);
|
2011-09-28 13:56:05 +08:00
|
|
|
virtual void getDefaultFeatures(llvm::StringMap<bool> &Features) const;
|
2012-01-30 14:38:25 +08:00
|
|
|
virtual bool hasFeature(StringRef Feature) const;
|
2013-10-17 05:26:26 +08:00
|
|
|
virtual bool handleTargetFeatures(std::vector<std::string> &Features,
|
2013-08-22 05:59:03 +08:00
|
|
|
DiagnosticsEngine &Diags);
|
2011-07-09 07:31:17 +08:00
|
|
|
virtual const char* getABI() const {
|
2012-10-11 23:52:22 +08:00
|
|
|
if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX)
|
2011-12-02 08:11:43 +08:00
|
|
|
return "avx";
|
2012-10-11 23:52:22 +08:00
|
|
|
else if (getTriple().getArch() == llvm::Triple::x86 &&
|
|
|
|
MMX3DNowLevel == NoMMX3DNow)
|
2011-12-02 08:11:43 +08:00
|
|
|
return "no-mmx";
|
|
|
|
return "";
|
2011-07-09 07:31:17 +08:00
|
|
|
}
|
2011-09-28 10:59:25 +08:00
|
|
|
virtual bool setCPU(const std::string &Name) {
|
2011-09-28 16:55:37 +08:00
|
|
|
CPU = llvm::StringSwitch<CPUKind>(Name)
|
|
|
|
.Case("i386", CK_i386)
|
|
|
|
.Case("i486", CK_i486)
|
|
|
|
.Case("winchip-c6", CK_WinChipC6)
|
|
|
|
.Case("winchip2", CK_WinChip2)
|
|
|
|
.Case("c3", CK_C3)
|
|
|
|
.Case("i586", CK_i586)
|
|
|
|
.Case("pentium", CK_Pentium)
|
|
|
|
.Case("pentium-mmx", CK_PentiumMMX)
|
|
|
|
.Case("i686", CK_i686)
|
|
|
|
.Case("pentiumpro", CK_PentiumPro)
|
|
|
|
.Case("pentium2", CK_Pentium2)
|
|
|
|
.Case("pentium3", CK_Pentium3)
|
|
|
|
.Case("pentium3m", CK_Pentium3M)
|
|
|
|
.Case("pentium-m", CK_PentiumM)
|
|
|
|
.Case("c3-2", CK_C3_2)
|
|
|
|
.Case("yonah", CK_Yonah)
|
|
|
|
.Case("pentium4", CK_Pentium4)
|
|
|
|
.Case("pentium4m", CK_Pentium4M)
|
|
|
|
.Case("prescott", CK_Prescott)
|
|
|
|
.Case("nocona", CK_Nocona)
|
|
|
|
.Case("core2", CK_Core2)
|
|
|
|
.Case("penryn", CK_Penryn)
|
|
|
|
.Case("atom", CK_Atom)
|
2013-09-14 03:27:17 +08:00
|
|
|
.Case("slm", CK_Silvermont)
|
2011-09-28 16:55:37 +08:00
|
|
|
.Case("corei7", CK_Corei7)
|
|
|
|
.Case("corei7-avx", CK_Corei7AVX)
|
|
|
|
.Case("core-avx-i", CK_CoreAVXi)
|
2011-12-18 03:55:21 +08:00
|
|
|
.Case("core-avx2", CK_CoreAVX2)
|
2013-08-20 15:09:39 +08:00
|
|
|
.Case("knl", CK_KNL)
|
2011-09-28 16:55:37 +08:00
|
|
|
.Case("k6", CK_K6)
|
|
|
|
.Case("k6-2", CK_K6_2)
|
|
|
|
.Case("k6-3", CK_K6_3)
|
|
|
|
.Case("athlon", CK_Athlon)
|
|
|
|
.Case("athlon-tbird", CK_AthlonThunderbird)
|
|
|
|
.Case("athlon-4", CK_Athlon4)
|
|
|
|
.Case("athlon-xp", CK_AthlonXP)
|
|
|
|
.Case("athlon-mp", CK_AthlonMP)
|
|
|
|
.Case("athlon64", CK_Athlon64)
|
|
|
|
.Case("athlon64-sse3", CK_Athlon64SSE3)
|
|
|
|
.Case("athlon-fx", CK_AthlonFX)
|
|
|
|
.Case("k8", CK_K8)
|
|
|
|
.Case("k8-sse3", CK_K8SSE3)
|
|
|
|
.Case("opteron", CK_Opteron)
|
|
|
|
.Case("opteron-sse3", CK_OpteronSSE3)
|
2011-10-30 15:48:46 +08:00
|
|
|
.Case("amdfam10", CK_AMDFAM10)
|
2012-01-10 19:50:18 +08:00
|
|
|
.Case("btver1", CK_BTVER1)
|
2013-05-03 18:47:15 +08:00
|
|
|
.Case("btver2", CK_BTVER2)
|
2011-12-02 02:23:59 +08:00
|
|
|
.Case("bdver1", CK_BDVER1)
|
|
|
|
.Case("bdver2", CK_BDVER2)
|
2013-11-04 18:29:51 +08:00
|
|
|
.Case("bdver3", CK_BDVER3)
|
2011-09-28 16:55:37 +08:00
|
|
|
.Case("x86-64", CK_x86_64)
|
|
|
|
.Case("geode", CK_Geode)
|
|
|
|
.Default(CK_Generic);
|
|
|
|
|
2011-09-28 17:45:08 +08:00
|
|
|
// Perform any per-CPU checks necessary to determine if this CPU is
|
|
|
|
// acceptable.
|
|
|
|
// FIXME: This results in terrible diagnostics. Clang just says the CPU is
|
|
|
|
// invalid without explaining *why*.
|
|
|
|
switch (CPU) {
|
|
|
|
case CK_Generic:
|
|
|
|
// No processor selected!
|
|
|
|
return false;
|
|
|
|
|
|
|
|
case CK_i386:
|
|
|
|
case CK_i486:
|
|
|
|
case CK_WinChipC6:
|
|
|
|
case CK_WinChip2:
|
|
|
|
case CK_C3:
|
|
|
|
case CK_i586:
|
|
|
|
case CK_Pentium:
|
|
|
|
case CK_PentiumMMX:
|
|
|
|
case CK_i686:
|
|
|
|
case CK_PentiumPro:
|
|
|
|
case CK_Pentium2:
|
|
|
|
case CK_Pentium3:
|
|
|
|
case CK_Pentium3M:
|
|
|
|
case CK_PentiumM:
|
|
|
|
case CK_Yonah:
|
|
|
|
case CK_C3_2:
|
|
|
|
case CK_Pentium4:
|
|
|
|
case CK_Pentium4M:
|
|
|
|
case CK_Prescott:
|
|
|
|
case CK_K6:
|
|
|
|
case CK_K6_2:
|
|
|
|
case CK_K6_3:
|
|
|
|
case CK_Athlon:
|
|
|
|
case CK_AthlonThunderbird:
|
|
|
|
case CK_Athlon4:
|
|
|
|
case CK_AthlonXP:
|
|
|
|
case CK_AthlonMP:
|
|
|
|
case CK_Geode:
|
|
|
|
// Only accept certain architectures when compiling in 32-bit mode.
|
2012-10-11 23:52:22 +08:00
|
|
|
if (getTriple().getArch() != llvm::Triple::x86)
|
2011-09-28 17:45:08 +08:00
|
|
|
return false;
|
|
|
|
|
|
|
|
// Fallthrough
|
|
|
|
case CK_Nocona:
|
|
|
|
case CK_Core2:
|
|
|
|
case CK_Penryn:
|
|
|
|
case CK_Atom:
|
2013-09-14 03:27:17 +08:00
|
|
|
case CK_Silvermont:
|
2011-09-28 17:45:08 +08:00
|
|
|
case CK_Corei7:
|
|
|
|
case CK_Corei7AVX:
|
|
|
|
case CK_CoreAVXi:
|
2011-12-18 03:55:21 +08:00
|
|
|
case CK_CoreAVX2:
|
2013-08-20 15:09:39 +08:00
|
|
|
case CK_KNL:
|
2011-09-28 17:45:08 +08:00
|
|
|
case CK_Athlon64:
|
|
|
|
case CK_Athlon64SSE3:
|
|
|
|
case CK_AthlonFX:
|
|
|
|
case CK_K8:
|
|
|
|
case CK_K8SSE3:
|
|
|
|
case CK_Opteron:
|
|
|
|
case CK_OpteronSSE3:
|
2011-10-30 15:48:46 +08:00
|
|
|
case CK_AMDFAM10:
|
2012-01-10 19:50:18 +08:00
|
|
|
case CK_BTVER1:
|
2013-05-03 18:47:15 +08:00
|
|
|
case CK_BTVER2:
|
2011-12-02 02:23:59 +08:00
|
|
|
case CK_BDVER1:
|
|
|
|
case CK_BDVER2:
|
2013-11-04 18:29:51 +08:00
|
|
|
case CK_BDVER3:
|
2011-09-28 17:45:08 +08:00
|
|
|
case CK_x86_64:
|
|
|
|
return true;
|
|
|
|
}
|
2011-09-28 18:49:06 +08:00
|
|
|
llvm_unreachable("Unhandled CPU kind");
|
2011-09-28 10:59:25 +08:00
|
|
|
}
|
2012-10-02 22:26:08 +08:00
|
|
|
|
2013-08-22 05:59:03 +08:00
|
|
|
virtual bool setFPMath(StringRef Name);
|
|
|
|
|
2012-10-02 22:26:08 +08:00
|
|
|
virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const {
|
|
|
|
// We accept all non-ARM calling conventions
|
|
|
|
return (CC == CC_X86ThisCall ||
|
|
|
|
CC == CC_X86FastCall ||
|
2013-02-23 08:06:18 +08:00
|
|
|
CC == CC_X86StdCall ||
|
|
|
|
CC == CC_C ||
|
2012-12-25 16:53:55 +08:00
|
|
|
CC == CC_X86Pascal ||
|
|
|
|
CC == CC_IntelOclBicc) ? CCCR_OK : CCCR_Warning;
|
2012-10-02 22:26:08 +08:00
|
|
|
}
|
|
|
|
|
2012-12-10 01:45:41 +08:00
|
|
|
virtual CallingConv getDefaultCallingConv(CallingConvMethodType MT) const {
|
|
|
|
return MT == CCMT_Member ? CC_X86ThisCall : CC_C;
|
2012-10-02 22:26:08 +08:00
|
|
|
}
|
2008-08-20 10:34:37 +08:00
|
|
|
};
|
2009-03-03 06:20:04 +08:00
|
|
|
|
2013-08-22 05:59:03 +08:00
|
|
|
bool X86TargetInfo::setFPMath(StringRef Name) {
|
|
|
|
if (Name == "387") {
|
|
|
|
FPMath = FP_387;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (Name == "sse") {
|
|
|
|
FPMath = FP_SSE;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-09-28 13:56:05 +08:00
|
|
|
void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const {
|
2009-05-06 11:16:41 +08:00
|
|
|
// FIXME: This *really* should not be here.
|
|
|
|
|
|
|
|
// X86_64 always has SSE2.
|
2012-10-11 23:52:22 +08:00
|
|
|
if (getTriple().getArch() == llvm::Triple::x86_64)
|
2013-09-17 12:51:29 +08:00
|
|
|
setFeatureEnabledImpl(Features, "sse2", true);
|
2009-05-06 11:16:41 +08:00
|
|
|
|
2011-09-28 16:55:37 +08:00
|
|
|
switch (CPU) {
|
|
|
|
case CK_Generic:
|
|
|
|
case CK_i386:
|
|
|
|
case CK_i486:
|
|
|
|
case CK_i586:
|
|
|
|
case CK_Pentium:
|
|
|
|
case CK_i686:
|
|
|
|
case CK_PentiumPro:
|
|
|
|
break;
|
|
|
|
case CK_PentiumMMX:
|
|
|
|
case CK_Pentium2:
|
2013-09-17 12:51:29 +08:00
|
|
|
setFeatureEnabledImpl(Features, "mmx", true);
|
2011-09-28 16:55:37 +08:00
|
|
|
break;
|
|
|
|
case CK_Pentium3:
|
|
|
|
case CK_Pentium3M:
|
2013-09-17 12:51:29 +08:00
|
|
|
setFeatureEnabledImpl(Features, "sse", true);
|
2011-09-28 16:55:37 +08:00
|
|
|
break;
|
|
|
|
case CK_PentiumM:
|
|
|
|
case CK_Pentium4:
|
|
|
|
case CK_Pentium4M:
|
|
|
|
case CK_x86_64:
|
2013-09-17 12:51:29 +08:00
|
|
|
setFeatureEnabledImpl(Features, "sse2", true);
|
2011-09-28 16:55:37 +08:00
|
|
|
break;
|
|
|
|
case CK_Yonah:
|
|
|
|
case CK_Prescott:
|
|
|
|
case CK_Nocona:
|
2013-09-17 12:51:29 +08:00
|
|
|
setFeatureEnabledImpl(Features, "sse3", true);
|
2013-10-06 04:14:27 +08:00
|
|
|
setFeatureEnabledImpl(Features, "cx16", true);
|
2011-09-28 16:55:37 +08:00
|
|
|
break;
|
|
|
|
case CK_Core2:
|
2013-09-17 12:51:29 +08:00
|
|
|
setFeatureEnabledImpl(Features, "ssse3", true);
|
2013-10-06 04:14:27 +08:00
|
|
|
setFeatureEnabledImpl(Features, "cx16", true);
|
2011-09-28 16:55:37 +08:00
|
|
|
break;
|
|
|
|
case CK_Penryn:
|
2013-09-17 12:51:29 +08:00
|
|
|
setFeatureEnabledImpl(Features, "sse4.1", true);
|
2013-10-06 04:14:27 +08:00
|
|
|
setFeatureEnabledImpl(Features, "cx16", true);
|
2011-09-28 16:55:37 +08:00
|
|
|
break;
|
|
|
|
case CK_Atom:
|
2013-09-17 12:51:29 +08:00
|
|
|
setFeatureEnabledImpl(Features, "ssse3", true);
|
2013-10-06 04:14:27 +08:00
|
|
|
setFeatureEnabledImpl(Features, "cx16", true);
|
2011-09-28 16:55:37 +08:00
|
|
|
break;
|
2013-09-14 03:27:17 +08:00
|
|
|
case CK_Silvermont:
|
2013-09-17 12:51:29 +08:00
|
|
|
setFeatureEnabledImpl(Features, "sse4.2", true);
|
|
|
|
setFeatureEnabledImpl(Features, "aes", true);
|
2013-10-06 04:14:27 +08:00
|
|
|
setFeatureEnabledImpl(Features, "cx16", true);
|
2013-09-17 12:51:29 +08:00
|
|
|
setFeatureEnabledImpl(Features, "pclmul", true);
|
2013-09-14 03:27:17 +08:00
|
|
|
break;
|
2011-09-28 16:55:37 +08:00
|
|
|
case CK_Corei7:
|
2013-09-17 12:51:29 +08:00
|
|
|
setFeatureEnabledImpl(Features, "sse4.2", true);
|
2013-10-06 04:14:27 +08:00
|
|
|
setFeatureEnabledImpl(Features, "cx16", true);
|
2011-09-28 16:55:37 +08:00
|
|
|
break;
|
|
|
|
case CK_Corei7AVX:
|
2013-09-17 12:51:29 +08:00
|
|
|
setFeatureEnabledImpl(Features, "avx", true);
|
|
|
|
setFeatureEnabledImpl(Features, "aes", true);
|
2013-10-06 04:14:27 +08:00
|
|
|
setFeatureEnabledImpl(Features, "cx16", true);
|
2013-09-17 12:51:29 +08:00
|
|
|
setFeatureEnabledImpl(Features, "pclmul", true);
|
2012-07-07 17:39:18 +08:00
|
|
|
break;
|
2011-09-28 16:55:37 +08:00
|
|
|
case CK_CoreAVXi:
|
2013-09-17 12:51:29 +08:00
|
|
|
setFeatureEnabledImpl(Features, "avx", true);
|
|
|
|
setFeatureEnabledImpl(Features, "aes", true);
|
|
|
|
setFeatureEnabledImpl(Features, "pclmul", true);
|
|
|
|
setFeatureEnabledImpl(Features, "rdrnd", true);
|
|
|
|
setFeatureEnabledImpl(Features, "f16c", true);
|
2011-09-28 16:55:37 +08:00
|
|
|
break;
|
2011-12-18 03:55:21 +08:00
|
|
|
case CK_CoreAVX2:
|
2013-09-17 12:51:29 +08:00
|
|
|
setFeatureEnabledImpl(Features, "avx2", true);
|
|
|
|
setFeatureEnabledImpl(Features, "aes", true);
|
|
|
|
setFeatureEnabledImpl(Features, "pclmul", true);
|
|
|
|
setFeatureEnabledImpl(Features, "lzcnt", true);
|
|
|
|
setFeatureEnabledImpl(Features, "rdrnd", true);
|
|
|
|
setFeatureEnabledImpl(Features, "f16c", true);
|
|
|
|
setFeatureEnabledImpl(Features, "bmi", true);
|
|
|
|
setFeatureEnabledImpl(Features, "bmi2", true);
|
|
|
|
setFeatureEnabledImpl(Features, "rtm", true);
|
|
|
|
setFeatureEnabledImpl(Features, "fma", true);
|
2013-10-06 04:14:27 +08:00
|
|
|
setFeatureEnabledImpl(Features, "cx16", true);
|
2011-12-18 03:55:21 +08:00
|
|
|
break;
|
2013-08-20 15:09:39 +08:00
|
|
|
case CK_KNL:
|
2013-09-17 12:51:29 +08:00
|
|
|
setFeatureEnabledImpl(Features, "avx512f", true);
|
|
|
|
setFeatureEnabledImpl(Features, "avx512cd", true);
|
|
|
|
setFeatureEnabledImpl(Features, "avx512er", true);
|
|
|
|
setFeatureEnabledImpl(Features, "avx512pf", true);
|
|
|
|
setFeatureEnabledImpl(Features, "aes", true);
|
|
|
|
setFeatureEnabledImpl(Features, "pclmul", true);
|
|
|
|
setFeatureEnabledImpl(Features, "lzcnt", true);
|
|
|
|
setFeatureEnabledImpl(Features, "rdrnd", true);
|
|
|
|
setFeatureEnabledImpl(Features, "f16c", true);
|
|
|
|
setFeatureEnabledImpl(Features, "bmi", true);
|
|
|
|
setFeatureEnabledImpl(Features, "bmi2", true);
|
|
|
|
setFeatureEnabledImpl(Features, "rtm", true);
|
|
|
|
setFeatureEnabledImpl(Features, "fma", true);
|
2013-08-20 15:09:39 +08:00
|
|
|
break;
|
2011-09-28 16:55:37 +08:00
|
|
|
case CK_K6:
|
|
|
|
case CK_WinChipC6:
|
2013-09-17 12:51:29 +08:00
|
|
|
setFeatureEnabledImpl(Features, "mmx", true);
|
2011-09-28 16:55:37 +08:00
|
|
|
break;
|
|
|
|
case CK_K6_2:
|
|
|
|
case CK_K6_3:
|
|
|
|
case CK_WinChip2:
|
|
|
|
case CK_C3:
|
2013-09-17 12:51:29 +08:00
|
|
|
setFeatureEnabledImpl(Features, "3dnow", true);
|
2011-09-28 16:55:37 +08:00
|
|
|
break;
|
2011-09-28 18:36:46 +08:00
|
|
|
case CK_Athlon:
|
|
|
|
case CK_AthlonThunderbird:
|
|
|
|
case CK_Geode:
|
2013-09-17 12:51:29 +08:00
|
|
|
setFeatureEnabledImpl(Features, "3dnowa", true);
|
2011-09-28 18:36:46 +08:00
|
|
|
break;
|
2011-09-28 16:55:37 +08:00
|
|
|
case CK_Athlon4:
|
|
|
|
case CK_AthlonXP:
|
|
|
|
case CK_AthlonMP:
|
2013-09-17 12:51:29 +08:00
|
|
|
setFeatureEnabledImpl(Features, "sse", true);
|
|
|
|
setFeatureEnabledImpl(Features, "3dnowa", true);
|
2011-09-28 16:55:37 +08:00
|
|
|
break;
|
|
|
|
case CK_K8:
|
|
|
|
case CK_Opteron:
|
|
|
|
case CK_Athlon64:
|
|
|
|
case CK_AthlonFX:
|
2013-09-17 12:51:29 +08:00
|
|
|
setFeatureEnabledImpl(Features, "sse2", true);
|
|
|
|
setFeatureEnabledImpl(Features, "3dnowa", true);
|
2011-09-28 16:55:37 +08:00
|
|
|
break;
|
|
|
|
case CK_K8SSE3:
|
|
|
|
case CK_OpteronSSE3:
|
|
|
|
case CK_Athlon64SSE3:
|
2013-09-17 12:51:29 +08:00
|
|
|
setFeatureEnabledImpl(Features, "sse3", true);
|
|
|
|
setFeatureEnabledImpl(Features, "3dnowa", true);
|
2011-10-30 21:47:56 +08:00
|
|
|
break;
|
2011-10-30 15:48:46 +08:00
|
|
|
case CK_AMDFAM10:
|
2013-09-17 12:51:29 +08:00
|
|
|
setFeatureEnabledImpl(Features, "sse3", true);
|
|
|
|
setFeatureEnabledImpl(Features, "sse4a", true);
|
|
|
|
setFeatureEnabledImpl(Features, "3dnowa", true);
|
|
|
|
setFeatureEnabledImpl(Features, "lzcnt", true);
|
|
|
|
setFeatureEnabledImpl(Features, "popcnt", true);
|
2011-09-28 16:55:37 +08:00
|
|
|
break;
|
2012-01-10 19:50:18 +08:00
|
|
|
case CK_BTVER1:
|
2013-09-17 12:51:29 +08:00
|
|
|
setFeatureEnabledImpl(Features, "ssse3", true);
|
|
|
|
setFeatureEnabledImpl(Features, "sse4a", true);
|
2013-10-06 04:14:27 +08:00
|
|
|
setFeatureEnabledImpl(Features, "cx16", true);
|
2013-09-17 12:51:29 +08:00
|
|
|
setFeatureEnabledImpl(Features, "lzcnt", true);
|
|
|
|
setFeatureEnabledImpl(Features, "popcnt", true);
|
2013-10-17 03:07:02 +08:00
|
|
|
setFeatureEnabledImpl(Features, "prfchw", true);
|
2012-05-30 13:54:54 +08:00
|
|
|
break;
|
2013-05-03 18:47:15 +08:00
|
|
|
case CK_BTVER2:
|
2013-09-17 12:51:29 +08:00
|
|
|
setFeatureEnabledImpl(Features, "avx", true);
|
|
|
|
setFeatureEnabledImpl(Features, "sse4a", true);
|
|
|
|
setFeatureEnabledImpl(Features, "lzcnt", true);
|
|
|
|
setFeatureEnabledImpl(Features, "aes", true);
|
|
|
|
setFeatureEnabledImpl(Features, "pclmul", true);
|
2013-10-17 03:07:02 +08:00
|
|
|
setFeatureEnabledImpl(Features, "prfchw", true);
|
2013-09-17 12:51:29 +08:00
|
|
|
setFeatureEnabledImpl(Features, "bmi", true);
|
|
|
|
setFeatureEnabledImpl(Features, "f16c", true);
|
2013-10-06 04:14:27 +08:00
|
|
|
setFeatureEnabledImpl(Features, "cx16", true);
|
2013-05-03 18:47:15 +08:00
|
|
|
break;
|
2011-12-02 02:23:59 +08:00
|
|
|
case CK_BDVER1:
|
2013-09-17 12:51:29 +08:00
|
|
|
setFeatureEnabledImpl(Features, "xop", true);
|
|
|
|
setFeatureEnabledImpl(Features, "lzcnt", true);
|
|
|
|
setFeatureEnabledImpl(Features, "aes", true);
|
|
|
|
setFeatureEnabledImpl(Features, "pclmul", true);
|
2013-10-17 03:07:02 +08:00
|
|
|
setFeatureEnabledImpl(Features, "prfchw", true);
|
2013-10-06 04:14:27 +08:00
|
|
|
setFeatureEnabledImpl(Features, "cx16", true);
|
2012-11-27 05:57:28 +08:00
|
|
|
break;
|
2011-12-02 02:23:59 +08:00
|
|
|
case CK_BDVER2:
|
2013-11-04 18:29:51 +08:00
|
|
|
case CK_BDVER3:
|
2013-09-17 12:51:29 +08:00
|
|
|
setFeatureEnabledImpl(Features, "xop", true);
|
|
|
|
setFeatureEnabledImpl(Features, "lzcnt", true);
|
|
|
|
setFeatureEnabledImpl(Features, "aes", true);
|
|
|
|
setFeatureEnabledImpl(Features, "pclmul", true);
|
2013-10-17 03:07:02 +08:00
|
|
|
setFeatureEnabledImpl(Features, "prfchw", true);
|
2013-09-17 12:51:29 +08:00
|
|
|
setFeatureEnabledImpl(Features, "bmi", true);
|
|
|
|
setFeatureEnabledImpl(Features, "fma", true);
|
|
|
|
setFeatureEnabledImpl(Features, "f16c", true);
|
2013-09-25 03:00:58 +08:00
|
|
|
setFeatureEnabledImpl(Features, "tbm", true);
|
2013-10-06 04:14:27 +08:00
|
|
|
setFeatureEnabledImpl(Features, "cx16", true);
|
2011-12-02 02:23:59 +08:00
|
|
|
break;
|
2011-09-28 16:55:37 +08:00
|
|
|
case CK_C3_2:
|
2013-09-17 12:51:29 +08:00
|
|
|
setFeatureEnabledImpl(Features, "sse", true);
|
2011-09-28 16:55:37 +08:00
|
|
|
break;
|
2011-07-09 07:31:17 +08:00
|
|
|
}
|
2009-05-06 11:16:41 +08:00
|
|
|
}
|
|
|
|
|
2013-08-20 21:44:29 +08:00
|
|
|
void X86TargetInfo::setSSELevel(llvm::StringMap<bool> &Features,
|
2013-09-17 12:12:55 +08:00
|
|
|
X86SSEEnum Level, bool Enabled) {
|
2013-08-20 21:44:29 +08:00
|
|
|
if (Enabled) {
|
|
|
|
switch (Level) {
|
2013-08-21 11:59:22 +08:00
|
|
|
case AVX512F:
|
|
|
|
Features["avx512f"] = true;
|
2013-08-20 21:44:29 +08:00
|
|
|
case AVX2:
|
|
|
|
Features["avx2"] = true;
|
|
|
|
case AVX:
|
|
|
|
Features["avx"] = true;
|
|
|
|
case SSE42:
|
2013-09-10 14:55:47 +08:00
|
|
|
Features["sse4.2"] = true;
|
2013-08-20 21:44:29 +08:00
|
|
|
case SSE41:
|
2013-08-24 04:21:37 +08:00
|
|
|
Features["sse4.1"] = true;
|
2013-08-20 21:44:29 +08:00
|
|
|
case SSSE3:
|
|
|
|
Features["ssse3"] = true;
|
|
|
|
case SSE3:
|
|
|
|
Features["sse3"] = true;
|
|
|
|
case SSE2:
|
|
|
|
Features["sse2"] = true;
|
|
|
|
case SSE1:
|
|
|
|
Features["sse"] = true;
|
|
|
|
case NoSSE:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (Level) {
|
|
|
|
case NoSSE:
|
|
|
|
case SSE1:
|
|
|
|
Features["sse"] = false;
|
|
|
|
case SSE2:
|
2013-09-19 21:22:04 +08:00
|
|
|
Features["sse2"] = Features["pclmul"] = Features["aes"] =
|
|
|
|
Features["sha"] = false;
|
2013-08-20 21:44:29 +08:00
|
|
|
case SSE3:
|
|
|
|
Features["sse3"] = false;
|
|
|
|
setXOPLevel(Features, NoXOP, false);
|
|
|
|
case SSSE3:
|
|
|
|
Features["ssse3"] = false;
|
|
|
|
case SSE41:
|
2013-08-24 04:21:37 +08:00
|
|
|
Features["sse4.1"] = false;
|
2013-08-20 21:44:29 +08:00
|
|
|
case SSE42:
|
2013-09-10 14:55:47 +08:00
|
|
|
Features["sse4.2"] = false;
|
2013-08-20 21:44:29 +08:00
|
|
|
case AVX:
|
2013-09-16 12:54:13 +08:00
|
|
|
Features["fma"] = Features["avx"] = Features["f16c"] = false;
|
2013-08-21 21:28:02 +08:00
|
|
|
setXOPLevel(Features, FMA4, false);
|
2013-08-20 21:44:29 +08:00
|
|
|
case AVX2:
|
|
|
|
Features["avx2"] = false;
|
2013-08-21 11:59:22 +08:00
|
|
|
case AVX512F:
|
2013-08-21 13:29:10 +08:00
|
|
|
Features["avx512f"] = Features["avx512cd"] = Features["avx512er"] =
|
|
|
|
Features["avx512pf"] = false;
|
2013-08-20 21:44:29 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void X86TargetInfo::setMMXLevel(llvm::StringMap<bool> &Features,
|
2013-09-17 12:12:55 +08:00
|
|
|
MMX3DNowEnum Level, bool Enabled) {
|
2013-08-20 21:44:29 +08:00
|
|
|
if (Enabled) {
|
|
|
|
switch (Level) {
|
|
|
|
case AMD3DNowAthlon:
|
|
|
|
Features["3dnowa"] = true;
|
|
|
|
case AMD3DNow:
|
|
|
|
Features["3dnow"] = true;
|
|
|
|
case MMX:
|
|
|
|
Features["mmx"] = true;
|
|
|
|
case NoMMX3DNow:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (Level) {
|
|
|
|
case NoMMX3DNow:
|
|
|
|
case MMX:
|
|
|
|
Features["mmx"] = false;
|
|
|
|
case AMD3DNow:
|
|
|
|
Features["3dnow"] = false;
|
|
|
|
case AMD3DNowAthlon:
|
|
|
|
Features["3dnowa"] = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void X86TargetInfo::setXOPLevel(llvm::StringMap<bool> &Features, XOPEnum Level,
|
2013-09-17 12:12:55 +08:00
|
|
|
bool Enabled) {
|
2013-08-20 21:44:29 +08:00
|
|
|
if (Enabled) {
|
|
|
|
switch (Level) {
|
|
|
|
case XOP:
|
|
|
|
Features["xop"] = true;
|
|
|
|
case FMA4:
|
|
|
|
Features["fma4"] = true;
|
|
|
|
setSSELevel(Features, AVX, true);
|
|
|
|
case SSE4A:
|
|
|
|
Features["sse4a"] = true;
|
|
|
|
setSSELevel(Features, SSE3, true);
|
|
|
|
case NoXOP:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (Level) {
|
|
|
|
case NoXOP:
|
|
|
|
case SSE4A:
|
|
|
|
Features["sse4a"] = false;
|
|
|
|
case FMA4:
|
|
|
|
Features["fma4"] = false;
|
|
|
|
case XOP:
|
|
|
|
Features["xop"] = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-17 12:51:29 +08:00
|
|
|
void X86TargetInfo::setFeatureEnabledImpl(llvm::StringMap<bool> &Features,
|
|
|
|
StringRef Name, bool Enabled) {
|
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.
|
2013-08-24 04:21:37 +08:00
|
|
|
if (Name == "sse4")
|
|
|
|
Name = "sse4.2";
|
2009-05-07 05:07:50 +08:00
|
|
|
|
2013-08-20 21:44:29 +08:00
|
|
|
Features[Name] = Enabled;
|
|
|
|
|
2013-09-19 09:13:07 +08:00
|
|
|
if (Name == "mmx") {
|
2013-08-20 21:44:29 +08:00
|
|
|
setMMXLevel(Features, MMX, Enabled);
|
2013-09-19 09:13:07 +08:00
|
|
|
} else if (Name == "sse") {
|
2013-08-20 21:44:29 +08:00
|
|
|
setSSELevel(Features, SSE1, Enabled);
|
2013-09-19 09:13:07 +08:00
|
|
|
} else if (Name == "sse2") {
|
2013-08-20 21:44:29 +08:00
|
|
|
setSSELevel(Features, SSE2, Enabled);
|
2013-09-19 09:13:07 +08:00
|
|
|
} else if (Name == "sse3") {
|
2013-08-20 21:44:29 +08:00
|
|
|
setSSELevel(Features, SSE3, Enabled);
|
2013-09-19 09:13:07 +08:00
|
|
|
} else if (Name == "ssse3") {
|
2013-08-20 21:44:29 +08:00
|
|
|
setSSELevel(Features, SSSE3, Enabled);
|
2013-09-19 09:13:07 +08:00
|
|
|
} else if (Name == "sse4.2") {
|
2013-08-20 21:44:29 +08:00
|
|
|
setSSELevel(Features, SSE42, Enabled);
|
2013-09-19 09:13:07 +08:00
|
|
|
} else if (Name == "sse4.1") {
|
2013-08-20 21:44:29 +08:00
|
|
|
setSSELevel(Features, SSE41, Enabled);
|
2013-09-19 09:13:07 +08:00
|
|
|
} else if (Name == "3dnow") {
|
2013-08-20 21:44:29 +08:00
|
|
|
setMMXLevel(Features, AMD3DNow, Enabled);
|
2013-09-19 09:13:07 +08:00
|
|
|
} else if (Name == "3dnowa") {
|
2013-08-20 21:44:29 +08:00
|
|
|
setMMXLevel(Features, AMD3DNowAthlon, Enabled);
|
2013-09-19 09:13:07 +08:00
|
|
|
} else if (Name == "aes") {
|
2013-08-20 21:44:29 +08:00
|
|
|
if (Enabled)
|
|
|
|
setSSELevel(Features, SSE2, Enabled);
|
|
|
|
} else if (Name == "pclmul") {
|
|
|
|
if (Enabled)
|
|
|
|
setSSELevel(Features, SSE2, Enabled);
|
2013-09-19 09:13:07 +08:00
|
|
|
} else if (Name == "avx") {
|
2013-08-20 21:44:29 +08:00
|
|
|
setSSELevel(Features, AVX, Enabled);
|
2013-09-19 09:13:07 +08:00
|
|
|
} else if (Name == "avx2") {
|
2013-08-20 21:44:29 +08:00
|
|
|
setSSELevel(Features, AVX2, Enabled);
|
2013-09-19 09:13:07 +08:00
|
|
|
} else if (Name == "avx512f") {
|
2013-08-21 11:59:22 +08:00
|
|
|
setSSELevel(Features, AVX512F, Enabled);
|
2013-09-19 09:13:07 +08:00
|
|
|
} else if (Name == "avx512cd" || Name == "avx512er" || Name == "avx512pf") {
|
2013-08-21 13:29:10 +08:00
|
|
|
if (Enabled)
|
|
|
|
setSSELevel(Features, AVX512F, Enabled);
|
|
|
|
} else if (Name == "fma") {
|
2013-08-20 21:44:29 +08:00
|
|
|
if (Enabled)
|
|
|
|
setSSELevel(Features, AVX, Enabled);
|
|
|
|
} else if (Name == "fma4") {
|
|
|
|
setXOPLevel(Features, FMA4, Enabled);
|
|
|
|
} else if (Name == "xop") {
|
|
|
|
setXOPLevel(Features, XOP, Enabled);
|
|
|
|
} else if (Name == "sse4a") {
|
|
|
|
setXOPLevel(Features, SSE4A, Enabled);
|
2013-09-16 12:54:13 +08:00
|
|
|
} else if (Name == "f16c") {
|
|
|
|
if (Enabled)
|
|
|
|
setSSELevel(Features, AVX, Enabled);
|
2013-09-19 21:22:04 +08:00
|
|
|
} else if (Name == "sha") {
|
|
|
|
if (Enabled)
|
|
|
|
setSSELevel(Features, SSE2, Enabled);
|
2009-05-07 05:07:50 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-17 05:26:26 +08:00
|
|
|
/// handleTargetFeatures - Perform initialization based on the user
|
2009-05-06 11:16:41 +08:00
|
|
|
/// configured set of features.
|
2013-10-17 05:26:26 +08:00
|
|
|
bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
|
2013-08-22 05:59:03 +08:00
|
|
|
DiagnosticsEngine &Diags) {
|
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;
|
|
|
|
|
2012-03-05 23:10:44 +08:00
|
|
|
StringRef Feature = StringRef(Features[i]).substr(1);
|
|
|
|
|
|
|
|
if (Feature == "aes") {
|
2010-04-03 07:50:19 +08:00
|
|
|
HasAES = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2012-05-31 13:18:48 +08:00
|
|
|
if (Feature == "pclmul") {
|
|
|
|
HasPCLMUL = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2012-03-05 23:10:44 +08:00
|
|
|
if (Feature == "lzcnt") {
|
2011-12-25 13:06:45 +08:00
|
|
|
HasLZCNT = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2013-08-24 04:21:37 +08:00
|
|
|
if (Feature == "rdrnd") {
|
2012-07-07 17:39:18 +08:00
|
|
|
HasRDRND = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2012-03-05 23:10:44 +08:00
|
|
|
if (Feature == "bmi") {
|
2011-12-25 13:06:45 +08:00
|
|
|
HasBMI = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2012-03-05 23:10:44 +08:00
|
|
|
if (Feature == "bmi2") {
|
2011-12-25 13:06:45 +08:00
|
|
|
HasBMI2 = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2012-03-05 23:10:44 +08:00
|
|
|
if (Feature == "popcnt") {
|
2011-12-30 00:10:46 +08:00
|
|
|
HasPOPCNT = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2012-11-10 13:17:46 +08:00
|
|
|
if (Feature == "rtm") {
|
|
|
|
HasRTM = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2013-03-27 01:52:08 +08:00
|
|
|
if (Feature == "prfchw") {
|
|
|
|
HasPRFCHW = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2013-03-29 13:17:55 +08:00
|
|
|
if (Feature == "rdseed") {
|
|
|
|
HasRDSEED = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2013-09-25 03:00:58 +08:00
|
|
|
if (Feature == "tbm") {
|
|
|
|
HasTBM = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2012-06-04 05:46:30 +08:00
|
|
|
if (Feature == "fma") {
|
|
|
|
HasFMA = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2012-10-11 08:59:55 +08:00
|
|
|
if (Feature == "f16c") {
|
|
|
|
HasF16C = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2013-08-21 13:29:10 +08:00
|
|
|
if (Feature == "avx512cd") {
|
|
|
|
HasAVX512CD = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Feature == "avx512er") {
|
|
|
|
HasAVX512ER = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Feature == "avx512pf") {
|
|
|
|
HasAVX512PF = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2013-09-19 21:22:04 +08:00
|
|
|
if (Feature == "sha") {
|
|
|
|
HasSHA = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2013-10-06 04:14:27 +08:00
|
|
|
if (Feature == "cx16") {
|
|
|
|
HasCX16 = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2009-11-11 17:38:56 +08:00
|
|
|
assert(Features[i][0] == '+' && "Invalid target feature!");
|
2012-03-05 23:10:44 +08:00
|
|
|
X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature)
|
2013-08-21 13:29:10 +08:00
|
|
|
.Case("avx512f", AVX512F)
|
2012-01-09 17:19:09 +08:00
|
|
|
.Case("avx2", AVX2)
|
|
|
|
.Case("avx", AVX)
|
2013-08-24 04:21:37 +08:00
|
|
|
.Case("sse4.2", SSE42)
|
|
|
|
.Case("sse4.1", SSE41)
|
2009-11-11 17:38:56 +08:00
|
|
|
.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)
|
2011-07-09 07:31:17 +08:00
|
|
|
.Default(NoSSE);
|
2009-11-11 17:38:56 +08:00
|
|
|
SSELevel = std::max(SSELevel, Level);
|
2010-10-21 11:16:25 +08:00
|
|
|
|
2011-07-09 07:31:17 +08:00
|
|
|
MMX3DNowEnum ThreeDNowLevel =
|
2012-03-05 23:10:44 +08:00
|
|
|
llvm::StringSwitch<MMX3DNowEnum>(Feature)
|
2010-01-27 11:47:49 +08:00
|
|
|
.Case("3dnowa", AMD3DNowAthlon)
|
|
|
|
.Case("3dnow", AMD3DNow)
|
2011-07-09 07:31:17 +08:00
|
|
|
.Case("mmx", MMX)
|
|
|
|
.Default(NoMMX3DNow);
|
|
|
|
MMX3DNowLevel = std::max(MMX3DNowLevel, ThreeDNowLevel);
|
2013-08-20 21:44:29 +08:00
|
|
|
|
|
|
|
XOPEnum XLevel = llvm::StringSwitch<XOPEnum>(Feature)
|
|
|
|
.Case("xop", XOP)
|
|
|
|
.Case("fma4", FMA4)
|
|
|
|
.Case("sse4a", SSE4A)
|
|
|
|
.Default(NoXOP);
|
|
|
|
XOPLevel = std::max(XOPLevel, XLevel);
|
2009-11-11 17:38:56 +08:00
|
|
|
}
|
2011-07-09 07:31:17 +08:00
|
|
|
|
2013-09-10 14:55:47 +08:00
|
|
|
// Enable popcnt if sse4.2 is enabled and popcnt is not explicitly disabled.
|
|
|
|
// Can't do this earlier because we need to be able to explicitly enable
|
|
|
|
// popcnt and still disable sse4.2.
|
|
|
|
if (!HasPOPCNT && SSELevel >= SSE42 &&
|
|
|
|
std::find(Features.begin(), Features.end(), "-popcnt") == Features.end()){
|
|
|
|
HasPOPCNT = true;
|
|
|
|
Features.push_back("+popcnt");
|
|
|
|
}
|
|
|
|
|
2013-10-17 03:07:02 +08:00
|
|
|
// Enable prfchw if 3DNow! is enabled and prfchw is not explicitly disabled.
|
|
|
|
if (!HasPRFCHW && MMX3DNowLevel >= AMD3DNow &&
|
|
|
|
std::find(Features.begin(), Features.end(), "-prfchw") == Features.end()){
|
|
|
|
HasPRFCHW = true;
|
|
|
|
Features.push_back("+prfchw");
|
|
|
|
}
|
|
|
|
|
2013-08-22 05:59:03 +08:00
|
|
|
// LLVM doesn't have a separate switch for fpmath, so only accept it if it
|
|
|
|
// matches the selected sse level.
|
|
|
|
if (FPMath == FP_SSE && SSELevel < SSE1) {
|
|
|
|
Diags.Report(diag::err_target_unsupported_fpmath) << "sse";
|
|
|
|
return false;
|
|
|
|
} else if (FPMath == FP_387 && SSELevel >= SSE1) {
|
|
|
|
Diags.Report(diag::err_target_unsupported_fpmath) << "387";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-07-09 07:31:17 +08:00
|
|
|
// Don't tell the backend if we're turning off mmx; it will end up disabling
|
|
|
|
// SSE, which we don't want.
|
2013-09-11 14:48:53 +08:00
|
|
|
// Additionally, if SSE is enabled and mmx is not explicitly disabled,
|
|
|
|
// then enable MMX.
|
2011-07-09 07:31:17 +08:00
|
|
|
std::vector<std::string>::iterator it;
|
|
|
|
it = std::find(Features.begin(), Features.end(), "-mmx");
|
|
|
|
if (it != Features.end())
|
|
|
|
Features.erase(it);
|
2013-09-11 14:48:53 +08:00
|
|
|
else if (SSELevel > NoSSE)
|
|
|
|
MMX3DNowLevel = std::max(MMX3DNowLevel, MMX);
|
2013-08-22 05:59:03 +08:00
|
|
|
return true;
|
2009-03-03 06:20:04 +08:00
|
|
|
}
|
2009-03-03 06:27:17 +08:00
|
|
|
|
2011-09-28 10:59:25 +08:00
|
|
|
/// X86TargetInfo::getTargetDefines - Return the set of the X86-specific macro
|
|
|
|
/// definitions for this particular 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.
|
2012-10-11 23:52:22 +08:00
|
|
|
if (getTriple().getArch() == llvm::Triple::x86_64) {
|
2010-01-10 01:55:51 +08:00
|
|
|
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
|
|
|
|
2009-03-03 06:27:17 +08:00
|
|
|
// Subtarget options.
|
2011-09-28 10:59:25 +08:00
|
|
|
// FIXME: We are hard-coding the tune parameters based on the CPU, but they
|
|
|
|
// truly should be based on -mtune options.
|
2011-09-28 16:55:37 +08:00
|
|
|
switch (CPU) {
|
|
|
|
case CK_Generic:
|
|
|
|
break;
|
|
|
|
case CK_i386:
|
2011-09-28 10:59:25 +08:00
|
|
|
// The rest are coming from the i386 define above.
|
|
|
|
Builder.defineMacro("__tune_i386__");
|
2011-09-28 16:55:37 +08:00
|
|
|
break;
|
|
|
|
case CK_i486:
|
|
|
|
case CK_WinChipC6:
|
|
|
|
case CK_WinChip2:
|
|
|
|
case CK_C3:
|
2012-01-10 19:50:09 +08:00
|
|
|
defineCPUMacros(Builder, "i486");
|
2011-09-28 16:55:37 +08:00
|
|
|
break;
|
2011-09-28 17:45:05 +08:00
|
|
|
case CK_PentiumMMX:
|
|
|
|
Builder.defineMacro("__pentium_mmx__");
|
|
|
|
Builder.defineMacro("__tune_pentium_mmx__");
|
|
|
|
// Fallthrough
|
2011-09-28 16:55:37 +08:00
|
|
|
case CK_i586:
|
|
|
|
case CK_Pentium:
|
2012-01-10 19:50:09 +08:00
|
|
|
defineCPUMacros(Builder, "i586");
|
|
|
|
defineCPUMacros(Builder, "pentium");
|
2011-09-28 16:55:37 +08:00
|
|
|
break;
|
|
|
|
case CK_Pentium3:
|
|
|
|
case CK_Pentium3M:
|
|
|
|
case CK_PentiumM:
|
2011-09-28 17:45:05 +08:00
|
|
|
Builder.defineMacro("__tune_pentium3__");
|
|
|
|
// Fallthrough
|
|
|
|
case CK_Pentium2:
|
2011-09-28 16:55:37 +08:00
|
|
|
case CK_C3_2:
|
2011-09-28 17:45:05 +08:00
|
|
|
Builder.defineMacro("__tune_pentium2__");
|
|
|
|
// Fallthrough
|
|
|
|
case CK_PentiumPro:
|
|
|
|
Builder.defineMacro("__tune_i686__");
|
|
|
|
Builder.defineMacro("__tune_pentiumpro__");
|
|
|
|
// Fallthrough
|
|
|
|
case CK_i686:
|
2011-09-28 10:59:25 +08:00
|
|
|
Builder.defineMacro("__i686");
|
|
|
|
Builder.defineMacro("__i686__");
|
|
|
|
// Strangely, __tune_i686__ isn't defined by GCC when CPU == i686.
|
|
|
|
Builder.defineMacro("__pentiumpro");
|
|
|
|
Builder.defineMacro("__pentiumpro__");
|
2011-09-28 16:55:37 +08:00
|
|
|
break;
|
|
|
|
case CK_Pentium4:
|
|
|
|
case CK_Pentium4M:
|
2012-01-10 19:50:09 +08:00
|
|
|
defineCPUMacros(Builder, "pentium4");
|
2011-09-28 16:55:37 +08:00
|
|
|
break;
|
|
|
|
case CK_Yonah:
|
|
|
|
case CK_Prescott:
|
|
|
|
case CK_Nocona:
|
2012-01-10 19:50:09 +08:00
|
|
|
defineCPUMacros(Builder, "nocona");
|
2011-09-28 16:55:37 +08:00
|
|
|
break;
|
|
|
|
case CK_Core2:
|
|
|
|
case CK_Penryn:
|
2012-01-10 19:50:09 +08:00
|
|
|
defineCPUMacros(Builder, "core2");
|
2011-09-28 16:55:37 +08:00
|
|
|
break;
|
|
|
|
case CK_Atom:
|
2012-01-10 19:50:09 +08:00
|
|
|
defineCPUMacros(Builder, "atom");
|
2011-09-28 16:55:37 +08:00
|
|
|
break;
|
2013-09-14 03:27:17 +08:00
|
|
|
case CK_Silvermont:
|
2013-08-30 22:05:34 +08:00
|
|
|
defineCPUMacros(Builder, "slm");
|
|
|
|
break;
|
2011-09-28 16:55:37 +08:00
|
|
|
case CK_Corei7:
|
|
|
|
case CK_Corei7AVX:
|
|
|
|
case CK_CoreAVXi:
|
2011-12-18 03:55:21 +08:00
|
|
|
case CK_CoreAVX2:
|
2012-01-10 19:50:09 +08:00
|
|
|
defineCPUMacros(Builder, "corei7");
|
2011-09-28 16:55:37 +08:00
|
|
|
break;
|
2013-08-20 15:09:39 +08:00
|
|
|
case CK_KNL:
|
|
|
|
defineCPUMacros(Builder, "knl");
|
|
|
|
break;
|
2011-09-28 16:55:37 +08:00
|
|
|
case CK_K6_2:
|
2011-09-28 17:45:05 +08:00
|
|
|
Builder.defineMacro("__k6_2__");
|
|
|
|
Builder.defineMacro("__tune_k6_2__");
|
|
|
|
// Fallthrough
|
2011-09-28 16:55:37 +08:00
|
|
|
case CK_K6_3:
|
2011-09-28 17:45:05 +08:00
|
|
|
if (CPU != CK_K6_2) { // In case of fallthrough
|
|
|
|
// FIXME: GCC may be enabling these in cases where some other k6
|
|
|
|
// architecture is specified but -m3dnow is explicitly provided. The
|
|
|
|
// exact semantics need to be determined and emulated here.
|
2011-09-28 10:59:25 +08:00
|
|
|
Builder.defineMacro("__k6_3__");
|
|
|
|
Builder.defineMacro("__tune_k6_3__");
|
|
|
|
}
|
2011-09-28 17:45:05 +08:00
|
|
|
// Fallthrough
|
|
|
|
case CK_K6:
|
2012-01-10 19:50:09 +08:00
|
|
|
defineCPUMacros(Builder, "k6");
|
2011-09-28 16:55:37 +08:00
|
|
|
break;
|
|
|
|
case CK_Athlon:
|
|
|
|
case CK_AthlonThunderbird:
|
|
|
|
case CK_Athlon4:
|
|
|
|
case CK_AthlonXP:
|
|
|
|
case CK_AthlonMP:
|
2012-01-10 19:50:09 +08:00
|
|
|
defineCPUMacros(Builder, "athlon");
|
2011-09-28 17:54:11 +08:00
|
|
|
if (SSELevel != NoSSE) {
|
2011-09-28 10:59:25 +08:00
|
|
|
Builder.defineMacro("__athlon_sse__");
|
2011-09-28 17:54:11 +08:00
|
|
|
Builder.defineMacro("__tune_athlon_sse__");
|
|
|
|
}
|
2011-09-28 16:55:37 +08:00
|
|
|
break;
|
|
|
|
case CK_K8:
|
|
|
|
case CK_K8SSE3:
|
|
|
|
case CK_x86_64:
|
|
|
|
case CK_Opteron:
|
|
|
|
case CK_OpteronSSE3:
|
|
|
|
case CK_Athlon64:
|
|
|
|
case CK_Athlon64SSE3:
|
|
|
|
case CK_AthlonFX:
|
2012-01-10 19:50:09 +08:00
|
|
|
defineCPUMacros(Builder, "k8");
|
2011-09-28 16:55:37 +08:00
|
|
|
break;
|
2011-10-30 15:48:46 +08:00
|
|
|
case CK_AMDFAM10:
|
2012-01-10 19:50:09 +08:00
|
|
|
defineCPUMacros(Builder, "amdfam10");
|
2011-10-30 15:48:46 +08:00
|
|
|
break;
|
2012-01-10 19:50:18 +08:00
|
|
|
case CK_BTVER1:
|
|
|
|
defineCPUMacros(Builder, "btver1");
|
|
|
|
break;
|
2013-05-03 18:47:15 +08:00
|
|
|
case CK_BTVER2:
|
|
|
|
defineCPUMacros(Builder, "btver2");
|
|
|
|
break;
|
2011-12-02 02:23:59 +08:00
|
|
|
case CK_BDVER1:
|
2012-01-10 19:50:09 +08:00
|
|
|
defineCPUMacros(Builder, "bdver1");
|
2011-12-02 02:23:59 +08:00
|
|
|
break;
|
|
|
|
case CK_BDVER2:
|
2012-01-10 19:50:09 +08:00
|
|
|
defineCPUMacros(Builder, "bdver2");
|
2011-12-02 02:23:59 +08:00
|
|
|
break;
|
2013-11-04 18:29:51 +08:00
|
|
|
case CK_BDVER3:
|
|
|
|
defineCPUMacros(Builder, "bdver3");
|
|
|
|
break;
|
2011-09-28 16:55:37 +08:00
|
|
|
case CK_Geode:
|
2012-01-10 19:50:09 +08:00
|
|
|
defineCPUMacros(Builder, "geode");
|
2011-09-28 16:55:37 +08:00
|
|
|
break;
|
2011-09-28 10:59:25 +08:00
|
|
|
}
|
2009-03-03 06:40:39 +08:00
|
|
|
|
2011-09-28 17:54:07 +08:00
|
|
|
// Target properties.
|
|
|
|
Builder.defineMacro("__LITTLE_ENDIAN__");
|
|
|
|
Builder.defineMacro("__REGISTER_PREFIX__", "");
|
|
|
|
|
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
|
|
|
|
2011-09-28 17:54:07 +08:00
|
|
|
if (HasAES)
|
|
|
|
Builder.defineMacro("__AES__");
|
|
|
|
|
2012-05-31 13:18:48 +08:00
|
|
|
if (HasPCLMUL)
|
|
|
|
Builder.defineMacro("__PCLMUL__");
|
|
|
|
|
2011-12-25 13:06:45 +08:00
|
|
|
if (HasLZCNT)
|
|
|
|
Builder.defineMacro("__LZCNT__");
|
|
|
|
|
2012-07-07 17:39:18 +08:00
|
|
|
if (HasRDRND)
|
|
|
|
Builder.defineMacro("__RDRND__");
|
|
|
|
|
2011-12-25 13:06:45 +08:00
|
|
|
if (HasBMI)
|
|
|
|
Builder.defineMacro("__BMI__");
|
|
|
|
|
|
|
|
if (HasBMI2)
|
|
|
|
Builder.defineMacro("__BMI2__");
|
|
|
|
|
2011-12-30 00:10:46 +08:00
|
|
|
if (HasPOPCNT)
|
|
|
|
Builder.defineMacro("__POPCNT__");
|
|
|
|
|
2012-11-10 13:17:46 +08:00
|
|
|
if (HasRTM)
|
|
|
|
Builder.defineMacro("__RTM__");
|
|
|
|
|
2013-03-27 01:52:08 +08:00
|
|
|
if (HasPRFCHW)
|
|
|
|
Builder.defineMacro("__PRFCHW__");
|
|
|
|
|
2013-03-29 13:17:55 +08:00
|
|
|
if (HasRDSEED)
|
|
|
|
Builder.defineMacro("__RDSEED__");
|
|
|
|
|
2013-09-25 03:00:58 +08:00
|
|
|
if (HasTBM)
|
|
|
|
Builder.defineMacro("__TBM__");
|
|
|
|
|
2013-08-20 21:44:29 +08:00
|
|
|
switch (XOPLevel) {
|
|
|
|
case XOP:
|
|
|
|
Builder.defineMacro("__XOP__");
|
|
|
|
case FMA4:
|
2011-12-30 15:33:42 +08:00
|
|
|
Builder.defineMacro("__FMA4__");
|
2013-08-20 21:44:29 +08:00
|
|
|
case SSE4A:
|
|
|
|
Builder.defineMacro("__SSE4A__");
|
|
|
|
case NoXOP:
|
|
|
|
break;
|
|
|
|
}
|
2011-12-30 15:33:42 +08:00
|
|
|
|
2012-06-04 05:46:30 +08:00
|
|
|
if (HasFMA)
|
|
|
|
Builder.defineMacro("__FMA__");
|
|
|
|
|
2012-10-11 08:59:55 +08:00
|
|
|
if (HasF16C)
|
|
|
|
Builder.defineMacro("__F16C__");
|
|
|
|
|
2013-08-21 13:29:10 +08:00
|
|
|
if (HasAVX512CD)
|
|
|
|
Builder.defineMacro("__AVX512CD__");
|
|
|
|
if (HasAVX512ER)
|
|
|
|
Builder.defineMacro("__AVX512ER__");
|
|
|
|
if (HasAVX512PF)
|
|
|
|
Builder.defineMacro("__AVX512PF__");
|
|
|
|
|
2013-09-19 21:22:04 +08:00
|
|
|
if (HasSHA)
|
|
|
|
Builder.defineMacro("__SHA__");
|
|
|
|
|
2013-10-06 04:14:27 +08:00
|
|
|
if (HasCX16)
|
|
|
|
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16");
|
|
|
|
|
2009-03-03 06:40:39 +08:00
|
|
|
// Each case falls through to the previous one here.
|
|
|
|
switch (SSELevel) {
|
2013-08-21 11:59:22 +08:00
|
|
|
case AVX512F:
|
2013-08-20 15:39:54 +08:00
|
|
|
Builder.defineMacro("__AVX512F__");
|
2012-01-09 17:19:09 +08:00
|
|
|
case AVX2:
|
|
|
|
Builder.defineMacro("__AVX2__");
|
|
|
|
case AVX:
|
|
|
|
Builder.defineMacro("__AVX__");
|
2009-03-03 06:40:39 +08:00
|
|
|
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.
|
2011-07-09 07:31:17 +08:00
|
|
|
case NoSSE:
|
2009-03-03 06:40:39 +08:00
|
|
|
break;
|
|
|
|
}
|
2010-10-18 15:10:59 +08:00
|
|
|
|
2012-10-11 23:52:22 +08:00
|
|
|
if (Opts.MicrosoftExt && getTriple().getArch() == llvm::Triple::x86) {
|
2010-10-21 13:21:48 +08:00
|
|
|
switch (SSELevel) {
|
2013-08-21 11:59:22 +08:00
|
|
|
case AVX512F:
|
2012-01-09 17:19:09 +08:00
|
|
|
case AVX2:
|
|
|
|
case AVX:
|
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:
|
2011-07-23 18:55:15 +08:00
|
|
|
Builder.defineMacro("_M_IX86_FP", Twine(2));
|
2010-10-21 13:21:48 +08:00
|
|
|
break;
|
|
|
|
case SSE1:
|
2011-07-23 18:55:15 +08:00
|
|
|
Builder.defineMacro("_M_IX86_FP", Twine(1));
|
2010-10-21 13:21:48 +08:00
|
|
|
break;
|
|
|
|
default:
|
2011-07-23 18:55:15 +08:00
|
|
|
Builder.defineMacro("_M_IX86_FP", Twine(0));
|
2010-10-21 13:21:48 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-01-27 11:47:49 +08:00
|
|
|
// Each case falls through to the previous one here.
|
2011-07-09 07:31:17 +08:00
|
|
|
switch (MMX3DNowLevel) {
|
2010-01-27 11:47:49 +08:00
|
|
|
case AMD3DNowAthlon:
|
|
|
|
Builder.defineMacro("__3dNOW_A__");
|
|
|
|
case AMD3DNow:
|
|
|
|
Builder.defineMacro("__3dNOW__");
|
2011-07-09 07:31:17 +08:00
|
|
|
case MMX:
|
|
|
|
Builder.defineMacro("__MMX__");
|
|
|
|
case NoMMX3DNow:
|
2010-01-27 11:47:49 +08:00
|
|
|
break;
|
|
|
|
}
|
2013-04-05 07:53:43 +08:00
|
|
|
|
|
|
|
if (CPU >= CK_i486) {
|
|
|
|
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
|
|
|
|
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
|
|
|
|
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
|
|
|
|
}
|
|
|
|
if (CPU >= CK_i586)
|
|
|
|
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
|
2009-03-03 06:27:17 +08:00
|
|
|
}
|
2009-05-03 21:42:53 +08:00
|
|
|
|
2012-01-30 14:38:25 +08:00
|
|
|
bool X86TargetInfo::hasFeature(StringRef Feature) const {
|
|
|
|
return llvm::StringSwitch<bool>(Feature)
|
|
|
|
.Case("aes", HasAES)
|
|
|
|
.Case("avx", SSELevel >= AVX)
|
|
|
|
.Case("avx2", SSELevel >= AVX2)
|
2013-08-21 11:59:22 +08:00
|
|
|
.Case("avx512f", SSELevel >= AVX512F)
|
2013-08-21 13:29:10 +08:00
|
|
|
.Case("avx512cd", HasAVX512CD)
|
|
|
|
.Case("avx512er", HasAVX512ER)
|
|
|
|
.Case("avx512pf", HasAVX512PF)
|
2012-01-30 14:38:25 +08:00
|
|
|
.Case("bmi", HasBMI)
|
|
|
|
.Case("bmi2", HasBMI2)
|
2013-10-06 04:14:27 +08:00
|
|
|
.Case("cx16", HasCX16)
|
|
|
|
.Case("f16c", HasF16C)
|
2012-06-04 05:46:30 +08:00
|
|
|
.Case("fma", HasFMA)
|
2013-08-20 21:44:29 +08:00
|
|
|
.Case("fma4", XOPLevel >= FMA4)
|
2013-09-25 03:00:58 +08:00
|
|
|
.Case("tbm", HasTBM)
|
2012-01-30 14:38:25 +08:00
|
|
|
.Case("lzcnt", HasLZCNT)
|
2012-07-07 17:39:18 +08:00
|
|
|
.Case("rdrnd", HasRDRND)
|
2012-01-30 14:38:25 +08:00
|
|
|
.Case("mm3dnow", MMX3DNowLevel >= AMD3DNow)
|
|
|
|
.Case("mm3dnowa", MMX3DNowLevel >= AMD3DNowAthlon)
|
|
|
|
.Case("mmx", MMX3DNowLevel >= MMX)
|
2012-05-31 13:18:48 +08:00
|
|
|
.Case("pclmul", HasPCLMUL)
|
2012-01-30 14:38:25 +08:00
|
|
|
.Case("popcnt", HasPOPCNT)
|
2012-11-10 13:17:46 +08:00
|
|
|
.Case("rtm", HasRTM)
|
2013-03-27 01:52:08 +08:00
|
|
|
.Case("prfchw", HasPRFCHW)
|
2013-03-29 13:17:55 +08:00
|
|
|
.Case("rdseed", HasRDSEED)
|
2013-09-19 21:22:04 +08:00
|
|
|
.Case("sha", HasSHA)
|
2012-01-30 14:38:25 +08:00
|
|
|
.Case("sse", SSELevel >= SSE1)
|
|
|
|
.Case("sse2", SSELevel >= SSE2)
|
|
|
|
.Case("sse3", SSELevel >= SSE3)
|
|
|
|
.Case("ssse3", SSELevel >= SSSE3)
|
2013-08-24 04:21:37 +08:00
|
|
|
.Case("sse4.1", SSELevel >= SSE41)
|
|
|
|
.Case("sse4.2", SSELevel >= SSE42)
|
2013-08-20 21:44:29 +08:00
|
|
|
.Case("sse4a", XOPLevel >= SSE4A)
|
2012-01-30 14:38:25 +08:00
|
|
|
.Case("x86", true)
|
2012-10-11 23:52:22 +08:00
|
|
|
.Case("x86_32", getTriple().getArch() == llvm::Triple::x86)
|
|
|
|
.Case("x86_64", getTriple().getArch() == llvm::Triple::x86_64)
|
2013-08-20 21:44:29 +08:00
|
|
|
.Case("xop", XOPLevel >= XOP)
|
2012-01-30 14:38:25 +08:00
|
|
|
.Default(false);
|
|
|
|
}
|
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
|
|
|
}
|
2008-08-20 10:34:37 +08:00
|
|
|
}
|
2008-02-27 02:33:46 +08:00
|
|
|
|
2010-10-30 07:12:32 +08:00
|
|
|
|
2008-08-20 10:34:37 +08:00
|
|
|
std::string
|
2011-06-08 07:45:05 +08:00
|
|
|
X86TargetInfo::convertConstraint(const char *&Constraint) const {
|
|
|
|
switch (*Constraint) {
|
2008-08-20 10:34:37 +08:00
|
|
|
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:
|
2011-06-08 07:45:05 +08:00
|
|
|
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:
|
2013-06-30 00:37:14 +08:00
|
|
|
X86_32TargetInfo(const llvm::Triple &Triple) : X86TargetInfo(Triple) {
|
2008-08-20 10:34:37 +08:00
|
|
|
DoubleAlign = LongLongAlign = 32;
|
|
|
|
LongDoubleWidth = 96;
|
|
|
|
LongDoubleAlign = 32;
|
2011-12-21 12:25:47 +08:00
|
|
|
SuitableAlign = 128;
|
2014-01-04 03:22:05 +08:00
|
|
|
DescriptionString = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128";
|
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));
|
2011-10-15 04:59:01 +08:00
|
|
|
|
|
|
|
// x86-32 has atomics up to 8 bytes
|
|
|
|
// FIXME: Check that we actually have cmpxchg8b before setting
|
|
|
|
// MaxAtomicInlineWidth. (cmpxchg8b is an i586 instruction.)
|
|
|
|
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
|
2008-08-20 10:34:37 +08:00
|
|
|
}
|
2012-06-16 11:34:49 +08:00
|
|
|
virtual BuiltinVaListKind getBuiltinVaListKind() const {
|
|
|
|
return TargetInfo::CharPtrBuiltinVaList;
|
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;
|
|
|
|
}
|
2012-11-12 14:42:51 +08:00
|
|
|
virtual bool validateInputSize(StringRef Constraint,
|
|
|
|
unsigned Size) const {
|
|
|
|
switch (Constraint[0]) {
|
|
|
|
default: break;
|
|
|
|
case 'a':
|
|
|
|
case 'b':
|
|
|
|
case 'c':
|
|
|
|
case 'd':
|
2012-11-13 02:52:32 +08:00
|
|
|
return Size <= 32;
|
2012-11-12 14:42:51 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
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
|
|
|
|
2012-01-07 02:32:26 +08:00
|
|
|
namespace {
|
|
|
|
class NetBSDI386TargetInfo : public NetBSDTargetInfo<X86_32TargetInfo> {
|
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
NetBSDI386TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: NetBSDTargetInfo<X86_32TargetInfo>(Triple) {}
|
2012-01-07 02:32:26 +08:00
|
|
|
|
|
|
|
virtual unsigned getFloatEvalMethod() const {
|
2013-11-11 22:00:37 +08:00
|
|
|
unsigned Major, Minor, Micro;
|
|
|
|
getTriple().getOSVersion(Major, Minor, Micro);
|
|
|
|
// New NetBSD uses the default rounding mode.
|
|
|
|
if (Major >= 7 || (Major == 6 && Minor == 99 && Micro >= 26) || Major == 0)
|
|
|
|
return X86_32TargetInfo::getFloatEvalMethod();
|
|
|
|
// NetBSD before 6.99.26 defaults to "double" rounding.
|
2012-01-07 02:32:26 +08:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
} // end anonymous namespace
|
|
|
|
|
2009-07-06 02:47:56 +08:00
|
|
|
namespace {
|
|
|
|
class OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> {
|
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
OpenBSDI386TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: OpenBSDTargetInfo<X86_32TargetInfo>(Triple) {
|
2009-07-06 02:47:56 +08:00
|
|
|
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
|
|
|
|
|
2012-08-09 07:57:20 +08:00
|
|
|
namespace {
|
|
|
|
class BitrigI386TargetInfo : public BitrigTargetInfo<X86_32TargetInfo> {
|
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
BitrigI386TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: BitrigTargetInfo<X86_32TargetInfo>(Triple) {
|
2012-08-09 07:57:20 +08:00
|
|
|
SizeType = UnsignedLong;
|
|
|
|
IntPtrType = SignedLong;
|
|
|
|
PtrDiffType = SignedLong;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
} // 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:
|
2013-06-30 00:37:14 +08:00
|
|
|
DarwinI386TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: DarwinTargetInfo<X86_32TargetInfo>(Triple) {
|
2008-05-20 22:21:01 +08:00
|
|
|
LongDoubleWidth = 128;
|
|
|
|
LongDoubleAlign = 128;
|
2011-12-17 06:34:14 +08:00
|
|
|
SuitableAlign = 128;
|
2012-07-14 07:57:43 +08:00
|
|
|
MaxVectorAlign = 256;
|
2009-03-30 04:31:09 +08:00
|
|
|
SizeType = UnsignedLong;
|
|
|
|
IntPtrType = SignedLong;
|
2014-01-04 03:22:05 +08:00
|
|
|
DescriptionString = "e-m:o-p:32:32-f64:32:64-f80:128-n8:16:32-S128";
|
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:
|
2013-06-30 00:37:14 +08:00
|
|
|
WindowsX86_32TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: 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;
|
2014-01-10 21:42:17 +08:00
|
|
|
DescriptionString = "e-m:w-p:32:32-i64:64-f80:32-n8:16:32-S32";
|
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:
|
2013-06-30 00:37:14 +08:00
|
|
|
VisualStudioWindowsX86_32TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: WindowsX86_32TargetInfo(Triple) {
|
2011-03-23 05:25:11 +08:00
|
|
|
LongDoubleWidth = LongDoubleAlign = 64;
|
2010-10-21 16:22:51 +08:00
|
|
|
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:
|
2013-06-30 00:37:14 +08:00
|
|
|
MinGWX86_32TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: WindowsX86_32TargetInfo(Triple) {}
|
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 {
|
|
|
|
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__");
|
2011-03-15 10:32:50 +08:00
|
|
|
|
|
|
|
// mingw32-gcc provides __declspec(a) as alias of __attribute__((a)).
|
|
|
|
// In contrast, clang-cc1 provides __declspec(a) with -fms-extensions.
|
2011-09-18 01:15:52 +08:00
|
|
|
if (Opts.MicrosoftExt)
|
2011-03-15 10:32:50 +08:00
|
|
|
// Provide "as-is" __declspec.
|
|
|
|
Builder.defineMacro("__declspec", "__declspec");
|
|
|
|
else
|
|
|
|
// Provide alias of __attribute__ like mingw32-gcc.
|
|
|
|
Builder.defineMacro("__declspec(a)", "__attribute__((a))");
|
2009-09-23 15:31:35 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
} // end anonymous namespace
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
// x86-32 Cygwin target
|
|
|
|
class CygwinX86_32TargetInfo : public X86_32TargetInfo {
|
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
CygwinX86_32TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: X86_32TargetInfo(Triple) {
|
2009-09-23 15:31:35 +08:00
|
|
|
TLSSupported = false;
|
|
|
|
WCharType = UnsignedShort;
|
|
|
|
DoubleAlign = LongLongAlign = 64;
|
2014-01-10 21:42:17 +08:00
|
|
|
DescriptionString = "e-m:w-p:32:32-i64:64-f80:32-n8:16:32-S32";
|
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);
|
2012-12-14 18:17:26 +08:00
|
|
|
Builder.defineMacro("_X86_");
|
2010-01-10 01:55:51 +08:00
|
|
|
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:
|
2013-06-30 00:37:14 +08:00
|
|
|
HaikuX86_32TargetInfo(const llvm::Triple &Triple) : X86_32TargetInfo(Triple) {
|
2010-04-12 03:29:39 +08:00
|
|
|
SizeType = UnsignedLong;
|
2010-04-23 01:48:00 +08:00
|
|
|
IntPtrType = SignedLong;
|
|
|
|
PtrDiffType = SignedLong;
|
2012-11-27 10:58:24 +08:00
|
|
|
ProcessIDType = SignedLong;
|
2010-11-10 00:41:02 +08:00
|
|
|
this->UserLabelPrefix = "";
|
2012-11-08 20:59:15 +08:00
|
|
|
this->TLSSupported = false;
|
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
|
|
|
|
|
2011-07-02 06:41:14 +08:00
|
|
|
// RTEMS Target
|
|
|
|
template<typename Target>
|
|
|
|
class RTEMSTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
|
|
|
virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
// RTEMS defines; list based off of gcc output
|
|
|
|
|
|
|
|
Builder.defineMacro("__rtems__");
|
|
|
|
Builder.defineMacro("__ELF__");
|
|
|
|
}
|
|
|
|
|
2013-06-30 00:37:14 +08:00
|
|
|
public:
|
|
|
|
RTEMSTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
|
|
|
|
this->UserLabelPrefix = "";
|
2011-07-02 06:41:14 +08:00
|
|
|
|
2013-06-30 00:37:14 +08:00
|
|
|
switch (Triple.getArch()) {
|
|
|
|
default:
|
|
|
|
case llvm::Triple::x86:
|
|
|
|
// this->MCountName = ".mcount";
|
|
|
|
break;
|
|
|
|
case llvm::Triple::mips:
|
|
|
|
case llvm::Triple::mipsel:
|
|
|
|
case llvm::Triple::ppc:
|
|
|
|
case llvm::Triple::ppc64:
|
2013-07-26 09:36:11 +08:00
|
|
|
case llvm::Triple::ppc64le:
|
2013-06-30 00:37:14 +08:00
|
|
|
// this->MCountName = "_mcount";
|
|
|
|
break;
|
|
|
|
case llvm::Triple::arm:
|
|
|
|
// this->MCountName = "__mcount";
|
|
|
|
break;
|
2011-07-02 06:41:14 +08:00
|
|
|
}
|
2013-06-30 00:37:14 +08:00
|
|
|
}
|
2011-07-02 06:41:14 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
// x86-32 RTEMS target
|
|
|
|
class RTEMSX86_32TargetInfo : public X86_32TargetInfo {
|
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
RTEMSX86_32TargetInfo(const llvm::Triple &Triple) : X86_32TargetInfo(Triple) {
|
2011-07-02 06:41:14 +08:00
|
|
|
SizeType = UnsignedLong;
|
|
|
|
IntPtrType = SignedLong;
|
|
|
|
PtrDiffType = SignedLong;
|
|
|
|
this->UserLabelPrefix = "";
|
|
|
|
}
|
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
X86_32TargetInfo::getTargetDefines(Opts, Builder);
|
|
|
|
Builder.defineMacro("__INTEL__");
|
|
|
|
Builder.defineMacro("__rtems__");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
} // end anonymous namespace
|
|
|
|
|
2008-08-20 10:34:37 +08:00
|
|
|
namespace {
|
|
|
|
// x86-64 generic target
|
|
|
|
class X86_64TargetInfo : public X86TargetInfo {
|
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
X86_64TargetInfo(const llvm::Triple &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;
|
2011-12-17 06:34:14 +08:00
|
|
|
SuitableAlign = 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
|
|
|
|
2014-01-04 03:22:05 +08:00
|
|
|
DescriptionString = "e-m:e-i64:64-f80:128-n8:16:32:64-S128";
|
2010-07-15 07:39:36 +08:00
|
|
|
|
|
|
|
// Use fpret only for long double.
|
|
|
|
RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble);
|
2011-10-15 04:59:01 +08:00
|
|
|
|
2011-11-01 00:27:11 +08:00
|
|
|
// Use fp2ret for _Complex long double.
|
|
|
|
ComplexLongDoubleUsesFP2Ret = true;
|
|
|
|
|
2011-10-15 04:59:01 +08:00
|
|
|
// x86-64 has atomics up to 16 bytes.
|
|
|
|
// FIXME: Once the backend is fixed, increase MaxAtomicInlineWidth to 128
|
|
|
|
// on CPUs with cmpxchg16b
|
|
|
|
MaxAtomicPromoteWidth = 128;
|
|
|
|
MaxAtomicInlineWidth = 64;
|
2007-01-29 13:24:35 +08:00
|
|
|
}
|
2012-06-16 11:34:49 +08:00
|
|
|
virtual BuiltinVaListKind getBuiltinVaListKind() const {
|
|
|
|
return TargetInfo::X86_64ABIBuiltinVaList;
|
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;
|
|
|
|
}
|
2012-10-02 22:26:08 +08:00
|
|
|
|
|
|
|
virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const {
|
2013-08-30 12:39:01 +08:00
|
|
|
return (CC == CC_C ||
|
|
|
|
CC == CC_IntelOclBicc ||
|
|
|
|
CC == CC_X86_64Win64) ? CCCR_OK : CCCR_Warning;
|
2012-10-02 22:26:08 +08:00
|
|
|
}
|
|
|
|
|
2012-12-10 01:45:41 +08:00
|
|
|
virtual CallingConv getDefaultCallingConv(CallingConvMethodType MT) const {
|
|
|
|
return CC_C;
|
2012-10-02 22:26:08 +08:00
|
|
|
}
|
|
|
|
|
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:
|
2013-06-30 00:37:14 +08:00
|
|
|
WindowsX86_64TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: 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;
|
2011-01-18 06:56:08 +08:00
|
|
|
this->UserLabelPrefix = "";
|
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
|
|
|
}
|
2012-06-16 11:34:49 +08:00
|
|
|
virtual BuiltinVaListKind getBuiltinVaListKind() const {
|
|
|
|
return TargetInfo::CharPtrBuiltinVaList;
|
2011-01-18 06:56:23 +08:00
|
|
|
}
|
2013-08-30 12:39:01 +08:00
|
|
|
virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const {
|
|
|
|
return (CC == CC_C ||
|
|
|
|
CC == CC_IntelOclBicc ||
|
|
|
|
CC == CC_X86_64SysV) ? CCCR_OK : CCCR_Warning;
|
|
|
|
}
|
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:
|
2013-06-30 00:37:14 +08:00
|
|
|
VisualStudioWindowsX86_64TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: WindowsX86_64TargetInfo(Triple) {
|
2011-03-23 05:25:11 +08:00
|
|
|
LongDoubleWidth = LongDoubleAlign = 64;
|
|
|
|
LongDoubleFormat = &llvm::APFloat::IEEEdouble;
|
2010-10-21 16:22:51 +08:00
|
|
|
}
|
|
|
|
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
|
|
|
}
|
|
|
|
};
|
|
|
|
} // end anonymous namespace
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
// x86-64 MinGW target
|
|
|
|
class MinGWX86_64TargetInfo : public WindowsX86_64TargetInfo {
|
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
MinGWX86_64TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: WindowsX86_64TargetInfo(Triple) {}
|
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 {
|
|
|
|
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__");
|
2011-03-08 20:06:46 +08:00
|
|
|
Builder.defineMacro("__MINGW32__");
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__MINGW64__");
|
2011-03-15 10:32:50 +08:00
|
|
|
|
|
|
|
// mingw32-gcc provides __declspec(a) as alias of __attribute__((a)).
|
|
|
|
// In contrast, clang-cc1 provides __declspec(a) with -fms-extensions.
|
2011-09-18 01:15:52 +08:00
|
|
|
if (Opts.MicrosoftExt)
|
2011-03-15 10:32:50 +08:00
|
|
|
// Provide "as-is" __declspec.
|
|
|
|
Builder.defineMacro("__declspec", "__declspec");
|
|
|
|
else
|
|
|
|
// Provide alias of __attribute__ like mingw32-gcc.
|
|
|
|
Builder.defineMacro("__declspec(a)", "__attribute__((a))");
|
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:
|
2013-06-30 00:37:14 +08:00
|
|
|
DarwinX86_64TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: DarwinTargetInfo<X86_64TargetInfo>(Triple) {
|
2009-07-01 11:36:11 +08:00
|
|
|
Int64Type = SignedLongLong;
|
2012-07-14 07:57:43 +08:00
|
|
|
MaxVectorAlign = 256;
|
2014-01-04 03:22:05 +08:00
|
|
|
DescriptionString = "e-m:o-i64:64-f80:128-n8:16:32:64-S128";
|
2009-07-01 11:36:11 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
} // end anonymous namespace
|
|
|
|
|
2009-07-06 06:31:18 +08:00
|
|
|
namespace {
|
|
|
|
class OpenBSDX86_64TargetInfo : public OpenBSDTargetInfo<X86_64TargetInfo> {
|
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
OpenBSDX86_64TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: OpenBSDTargetInfo<X86_64TargetInfo>(Triple) {
|
2009-07-06 06:31:18 +08:00
|
|
|
IntMaxType = SignedLongLong;
|
|
|
|
UIntMaxType = UnsignedLongLong;
|
|
|
|
Int64Type = SignedLongLong;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
} // end anonymous namespace
|
|
|
|
|
2012-08-09 07:57:20 +08:00
|
|
|
namespace {
|
|
|
|
class BitrigX86_64TargetInfo : public BitrigTargetInfo<X86_64TargetInfo> {
|
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
BitrigX86_64TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: BitrigTargetInfo<X86_64TargetInfo>(Triple) {
|
|
|
|
IntMaxType = SignedLongLong;
|
|
|
|
UIntMaxType = UnsignedLongLong;
|
|
|
|
Int64Type = SignedLongLong;
|
2012-08-09 07:57:20 +08:00
|
|
|
}
|
|
|
|
};
|
2013-01-31 20:13:10 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
class AArch64TargetInfo : public TargetInfo {
|
|
|
|
static const char * const GCCRegNames[];
|
|
|
|
static const TargetInfo::GCCRegAlias GCCRegAliases[];
|
2013-05-04 15:15:13 +08:00
|
|
|
|
2013-08-01 17:23:19 +08:00
|
|
|
enum FPUModeEnum {
|
|
|
|
FPUMode,
|
|
|
|
NeonMode
|
|
|
|
};
|
|
|
|
|
|
|
|
unsigned FPU;
|
2013-11-19 09:33:17 +08:00
|
|
|
unsigned Crypto;
|
2013-05-04 15:15:13 +08:00
|
|
|
static const Builtin::Info BuiltinInfo[];
|
2013-08-01 17:23:19 +08:00
|
|
|
|
2013-01-31 20:13:10 +08:00
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
AArch64TargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
|
2013-01-31 20:13:10 +08:00
|
|
|
BigEndian = false;
|
|
|
|
LongWidth = LongAlign = 64;
|
|
|
|
LongDoubleWidth = LongDoubleAlign = 128;
|
|
|
|
PointerWidth = PointerAlign = 64;
|
|
|
|
SuitableAlign = 128;
|
2014-01-04 03:22:05 +08:00
|
|
|
DescriptionString = "e-m:e-i64:64-i128:128-n32:64-S128";
|
2013-01-31 20:13:10 +08:00
|
|
|
|
|
|
|
WCharType = UnsignedInt;
|
|
|
|
LongDoubleFormat = &llvm::APFloat::IEEEquad;
|
|
|
|
|
2013-02-18 20:11:32 +08:00
|
|
|
// AArch64 backend supports 64-bit operations at the moment. In principle
|
|
|
|
// 128-bit is possible if register-pairs are used.
|
|
|
|
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
|
|
|
|
|
2013-01-31 20:13:10 +08:00
|
|
|
TheCXXABI.set(TargetCXXABI::GenericAArch64);
|
|
|
|
}
|
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
// GCC defines theses currently
|
|
|
|
Builder.defineMacro("__aarch64__");
|
|
|
|
Builder.defineMacro("__AARCH64EL__");
|
|
|
|
|
|
|
|
// ACLE predefines. Many can only have one possible value on v8 AArch64.
|
2013-11-19 09:33:17 +08:00
|
|
|
Builder.defineMacro("__ARM_ACLE", "200");
|
2013-04-05 22:08:55 +08:00
|
|
|
Builder.defineMacro("__ARM_ARCH", "8");
|
|
|
|
Builder.defineMacro("__ARM_ARCH_PROFILE", "'A'");
|
2013-01-31 20:13:10 +08:00
|
|
|
|
2013-11-19 09:33:17 +08:00
|
|
|
Builder.defineMacro("__ARM_64BIT_STATE");
|
|
|
|
Builder.defineMacro("__ARM_PCS_AAPCS64");
|
|
|
|
Builder.defineMacro("__ARM_ARCH_ISA_A64");
|
|
|
|
|
2013-04-05 22:08:55 +08:00
|
|
|
Builder.defineMacro("__ARM_FEATURE_UNALIGNED");
|
|
|
|
Builder.defineMacro("__ARM_FEATURE_CLZ");
|
|
|
|
Builder.defineMacro("__ARM_FEATURE_FMA");
|
2013-11-19 09:33:17 +08:00
|
|
|
Builder.defineMacro("__ARM_FEATURE_DIV");
|
2013-01-31 20:13:10 +08:00
|
|
|
|
2013-11-19 09:33:17 +08:00
|
|
|
Builder.defineMacro("__ARM_ALIGN_MAX_STACK_PWR", "4");
|
2013-01-31 20:13:10 +08:00
|
|
|
|
|
|
|
// 0xe implies support for half, single and double precision operations.
|
2013-04-05 22:08:55 +08:00
|
|
|
Builder.defineMacro("__ARM_FP", "0xe");
|
2013-01-31 20:13:10 +08:00
|
|
|
|
|
|
|
// PCS specifies this for SysV variants, which is all we support. Other ABIs
|
2013-04-05 22:08:55 +08:00
|
|
|
// may choose __ARM_FP16_FORMAT_ALTERNATIVE.
|
|
|
|
Builder.defineMacro("__ARM_FP16_FORMAT_IEEE");
|
2013-01-31 20:13:10 +08:00
|
|
|
|
|
|
|
if (Opts.FastMath || Opts.FiniteMathOnly)
|
2013-04-05 22:08:55 +08:00
|
|
|
Builder.defineMacro("__ARM_FP_FAST");
|
2013-01-31 20:13:10 +08:00
|
|
|
|
|
|
|
if ((Opts.C99 || Opts.C11) && !Opts.Freestanding)
|
2013-04-05 22:08:55 +08:00
|
|
|
Builder.defineMacro("__ARM_FP_FENV_ROUNDING");
|
2013-01-31 20:13:10 +08:00
|
|
|
|
2013-04-05 22:08:55 +08:00
|
|
|
Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
|
2013-01-31 20:13:10 +08:00
|
|
|
Opts.ShortWChar ? "2" : "4");
|
|
|
|
|
2013-04-05 22:08:55 +08:00
|
|
|
Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM",
|
2013-01-31 20:13:10 +08:00
|
|
|
Opts.ShortEnums ? "1" : "4");
|
|
|
|
|
|
|
|
if (BigEndian)
|
2013-08-01 17:23:19 +08:00
|
|
|
Builder.defineMacro("__AARCH_BIG_ENDIAN");
|
|
|
|
|
|
|
|
if (FPU == NeonMode) {
|
2013-11-19 09:33:17 +08:00
|
|
|
Builder.defineMacro("__ARM_NEON");
|
2013-08-01 17:23:19 +08:00
|
|
|
// 64-bit NEON supports half, single and double precision operations.
|
2013-11-19 09:33:17 +08:00
|
|
|
Builder.defineMacro("__ARM_NEON_FP", "7");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Crypto) {
|
|
|
|
Builder.defineMacro("__ARM_FEATURE_CRYPTO");
|
2013-08-01 17:23:19 +08:00
|
|
|
}
|
2013-01-31 20:13:10 +08:00
|
|
|
}
|
|
|
|
virtual void getTargetBuiltins(const Builtin::Info *&Records,
|
|
|
|
unsigned &NumRecords) const {
|
2013-05-04 15:15:13 +08:00
|
|
|
Records = BuiltinInfo;
|
|
|
|
NumRecords = clang::AArch64::LastTSBuiltin-Builtin::FirstTSBuiltin;
|
2013-01-31 20:13:10 +08:00
|
|
|
}
|
|
|
|
virtual bool hasFeature(StringRef Feature) const {
|
2013-08-01 17:23:19 +08:00
|
|
|
return Feature == "aarch64" || (Feature == "neon" && FPU == NeonMode);
|
2013-01-31 20:13:10 +08:00
|
|
|
}
|
2013-08-01 17:23:19 +08:00
|
|
|
|
2013-10-31 17:32:33 +08:00
|
|
|
virtual bool setCPU(const std::string &Name) {
|
|
|
|
return llvm::StringSwitch<bool>(Name)
|
|
|
|
.Case("generic", true)
|
|
|
|
.Cases("cortex-a53", "cortex-a57", true)
|
|
|
|
.Default(false);
|
|
|
|
}
|
|
|
|
|
2013-10-17 05:26:26 +08:00
|
|
|
virtual bool handleTargetFeatures(std::vector<std::string> &Features,
|
2013-08-22 05:59:03 +08:00
|
|
|
DiagnosticsEngine &Diags) {
|
2013-08-01 17:23:19 +08:00
|
|
|
FPU = FPUMode;
|
2013-11-19 09:33:17 +08:00
|
|
|
Crypto = 0;
|
2013-08-01 17:23:19 +08:00
|
|
|
for (unsigned i = 0, e = Features.size(); i != e; ++i) {
|
|
|
|
if (Features[i] == "+neon")
|
|
|
|
FPU = NeonMode;
|
2013-11-19 09:33:17 +08:00
|
|
|
if (Features[i] == "+crypto")
|
|
|
|
Crypto = 1;
|
2013-08-01 17:23:19 +08:00
|
|
|
}
|
2013-08-22 05:59:03 +08:00
|
|
|
return true;
|
2013-08-01 17:23:19 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
virtual void getGCCRegNames(const char *const *&Names,
|
2013-01-31 20:13:10 +08:00
|
|
|
unsigned &NumNames) const;
|
|
|
|
virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
|
|
|
|
unsigned &NumAliases) const;
|
|
|
|
|
|
|
|
virtual bool isCLZForZeroUndef() const { return false; }
|
|
|
|
|
|
|
|
virtual bool validateAsmConstraint(const char *&Name,
|
|
|
|
TargetInfo::ConstraintInfo &Info) const {
|
|
|
|
switch (*Name) {
|
|
|
|
default: return false;
|
|
|
|
case 'w': // An FP/SIMD vector register
|
|
|
|
Info.setAllowsRegister();
|
|
|
|
return true;
|
|
|
|
case 'I': // Constant that can be used with an ADD instruction
|
|
|
|
case 'J': // Constant that can be used with a SUB instruction
|
|
|
|
case 'K': // Constant that can be used with a 32-bit logical instruction
|
|
|
|
case 'L': // Constant that can be used with a 64-bit logical instruction
|
|
|
|
case 'M': // Constant that can be used as a 32-bit MOV immediate
|
|
|
|
case 'N': // Constant that can be used as a 64-bit MOV immediate
|
|
|
|
case 'Y': // Floating point constant zero
|
|
|
|
case 'Z': // Integer constant zero
|
|
|
|
return true;
|
|
|
|
case 'Q': // A memory reference with base register and no offset
|
|
|
|
Info.setAllowsMemory();
|
|
|
|
return true;
|
|
|
|
case 'S': // A symbolic address
|
|
|
|
Info.setAllowsRegister();
|
|
|
|
return true;
|
|
|
|
case 'U':
|
|
|
|
// Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes, whatever they may be
|
|
|
|
// Utf: A memory address suitable for ldp/stp in TF mode, whatever it may be
|
|
|
|
// Usa: An absolute symbolic address
|
|
|
|
// Ush: The high part (bits 32:12) of a pc-relative symbolic address
|
|
|
|
llvm_unreachable("FIXME: Unimplemented support for bizarre constraints");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual const char *getClobbers() const {
|
|
|
|
// There are no AArch64 clobbers shared by all asm statements.
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual BuiltinVaListKind getBuiltinVaListKind() const {
|
|
|
|
return TargetInfo::AArch64ABIBuiltinVaList;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const char * const AArch64TargetInfo::GCCRegNames[] = {
|
|
|
|
"w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7",
|
|
|
|
"w8", "w9", "w10", "w11", "w12", "w13", "w14", "w15",
|
|
|
|
"w16", "w17", "w18", "w19", "w20", "w21", "w22", "w23",
|
|
|
|
"w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp", "wzr",
|
|
|
|
|
|
|
|
"x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
|
|
|
|
"x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",
|
|
|
|
"x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23",
|
|
|
|
"x24", "x25", "x26", "x27", "x28", "x29", "x30", "sp", "xzr",
|
|
|
|
|
|
|
|
"b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7",
|
|
|
|
"b8", "b9", "b10", "b11", "b12", "b13", "b14", "b15",
|
|
|
|
"b16", "b17", "b18", "b19", "b20", "b21", "b22", "b23",
|
|
|
|
"b24", "b25", "b26", "b27", "b28", "b29", "b30", "b31",
|
|
|
|
|
|
|
|
"h0", "h1", "h2", "h3", "h4", "h5", "h6", "h7",
|
|
|
|
"h8", "h9", "h10", "h11", "h12", "h13", "h14", "h15",
|
|
|
|
"h16", "h17", "h18", "h19", "h20", "h21", "h22", "h23",
|
|
|
|
"h24", "h25", "h26", "h27", "h28", "h29", "h30", "h31",
|
|
|
|
|
|
|
|
"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
|
|
|
|
"s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15",
|
|
|
|
"s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23",
|
|
|
|
"s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
|
|
|
|
|
|
|
|
"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
|
|
|
|
"d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15",
|
|
|
|
"d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23",
|
|
|
|
"d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
|
|
|
|
|
|
|
|
"q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7",
|
|
|
|
"q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15",
|
|
|
|
"q16", "q17", "q18", "q19", "q20", "q21", "q22", "q23",
|
|
|
|
"q24", "q25", "q26", "q27", "q28", "q29", "q30", "q31"
|
|
|
|
};
|
|
|
|
|
|
|
|
void AArch64TargetInfo::getGCCRegNames(const char * const *&Names,
|
|
|
|
unsigned &NumNames) const {
|
|
|
|
Names = GCCRegNames;
|
|
|
|
NumNames = llvm::array_lengthof(GCCRegNames);
|
|
|
|
}
|
|
|
|
|
|
|
|
const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = {
|
|
|
|
{ { "x16" }, "ip0"},
|
|
|
|
{ { "x17" }, "ip1"},
|
|
|
|
{ { "x29" }, "fp" },
|
|
|
|
{ { "x30" }, "lr" }
|
|
|
|
};
|
|
|
|
|
|
|
|
void AArch64TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
|
|
|
|
unsigned &NumAliases) const {
|
|
|
|
Aliases = GCCRegAliases;
|
|
|
|
NumAliases = llvm::array_lengthof(GCCRegAliases);
|
|
|
|
|
|
|
|
}
|
2013-05-04 15:15:13 +08:00
|
|
|
|
|
|
|
const Builtin::Info AArch64TargetInfo::BuiltinInfo[] = {
|
|
|
|
#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
|
|
|
|
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
|
|
|
|
ALL_LANGUAGES },
|
|
|
|
#include "clang/Basic/BuiltinsAArch64.def"
|
|
|
|
};
|
|
|
|
|
2012-08-09 07:57:20 +08:00
|
|
|
} // 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 {
|
2012-09-30 07:52:52 +08:00
|
|
|
VFP2FPU = (1 << 0),
|
|
|
|
VFP3FPU = (1 << 1),
|
|
|
|
VFP4FPU = (1 << 2),
|
2013-10-25 02:32:51 +08:00
|
|
|
NeonFPU = (1 << 3),
|
|
|
|
FPARMV8 = (1 << 4)
|
2009-12-22 07:28:17 +08:00
|
|
|
};
|
|
|
|
|
2013-10-21 18:54:53 +08:00
|
|
|
// Possible HWDiv features.
|
|
|
|
enum HWDivMode {
|
|
|
|
HWDivThumb = (1 << 0),
|
|
|
|
HWDivARM = (1 << 1)
|
|
|
|
};
|
|
|
|
|
2009-12-22 07:28:17 +08:00
|
|
|
static bool FPUModeIsVFP(FPUMode Mode) {
|
2013-10-25 02:32:51 +08:00
|
|
|
return Mode & (VFP2FPU | VFP3FPU | VFP4FPU | NeonFPU | FPARMV8);
|
2009-12-22 07:28:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
2013-08-22 05:59:03 +08:00
|
|
|
enum {
|
|
|
|
FP_Default,
|
|
|
|
FP_VFP,
|
|
|
|
FP_Neon
|
|
|
|
} FPMath;
|
|
|
|
|
2013-10-25 02:32:51 +08:00
|
|
|
unsigned FPU : 5;
|
2009-12-22 07:28:17 +08:00
|
|
|
|
2012-10-10 14:56:20 +08:00
|
|
|
unsigned IsAAPCS : 1;
|
2009-12-19 12:15:38 +08:00
|
|
|
unsigned IsThumb : 1;
|
2013-10-21 18:54:53 +08:00
|
|
|
unsigned HWDiv : 2;
|
2009-12-19 12:15:38 +08:00
|
|
|
|
|
|
|
// Initialized via features.
|
|
|
|
unsigned SoftFloat : 1;
|
|
|
|
unsigned SoftFloatABI : 1;
|
2009-09-14 08:35:03 +08:00
|
|
|
|
2013-10-29 17:47:51 +08:00
|
|
|
unsigned CRC : 1;
|
|
|
|
|
2010-03-04 03:03:45 +08:00
|
|
|
static const Builtin::Info BuiltinInfo[];
|
|
|
|
|
2013-05-14 04:09:47 +08:00
|
|
|
static bool shouldUseInlineAtomic(const llvm::Triple &T) {
|
|
|
|
// On linux, binaries targeting old cpus call functions in libgcc to
|
|
|
|
// perform atomic operations. The implementation in libgcc then calls into
|
|
|
|
// the kernel which on armv6 and newer uses ldrex and strex. The net result
|
|
|
|
// is that if we assume the kernel is at least as recent as the hardware,
|
|
|
|
// it is safe to use atomic instructions on armv6 and newer.
|
2013-09-14 09:09:11 +08:00
|
|
|
if (!T.isOSLinux() &&
|
2013-06-18 04:00:15 +08:00
|
|
|
T.getOS() != llvm::Triple::FreeBSD &&
|
2013-12-03 00:12:05 +08:00
|
|
|
T.getOS() != llvm::Triple::NetBSD &&
|
2013-06-18 04:00:15 +08:00
|
|
|
T.getOS() != llvm::Triple::Bitrig)
|
2013-06-15 17:40:14 +08:00
|
|
|
return false;
|
2013-05-14 04:09:47 +08:00
|
|
|
StringRef ArchName = T.getArchName();
|
2013-05-14 08:44:24 +08:00
|
|
|
if (T.getArch() == llvm::Triple::arm) {
|
|
|
|
if (!ArchName.startswith("armv"))
|
|
|
|
return false;
|
|
|
|
StringRef VersionStr = ArchName.substr(4);
|
|
|
|
unsigned Version;
|
|
|
|
if (VersionStr.getAsInteger(10, Version))
|
|
|
|
return false;
|
|
|
|
return Version >= 6;
|
|
|
|
}
|
|
|
|
assert(T.getArch() == llvm::Triple::thumb);
|
|
|
|
if (!ArchName.startswith("thumbv"))
|
|
|
|
return false;
|
|
|
|
StringRef VersionStr = ArchName.substr(6);
|
|
|
|
unsigned Version;
|
|
|
|
if (VersionStr.getAsInteger(10, Version))
|
|
|
|
return false;
|
|
|
|
return Version >= 7;
|
2013-05-14 04:09:47 +08:00
|
|
|
}
|
|
|
|
|
2013-12-19 03:47:32 +08:00
|
|
|
void setABIAAPCS() {
|
2013-12-19 04:24:51 +08:00
|
|
|
IsAAPCS = true;
|
|
|
|
|
|
|
|
DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
|
2014-01-04 03:22:05 +08:00
|
|
|
const llvm::Triple &T = getTriple();
|
2013-12-19 03:47:32 +08:00
|
|
|
|
2013-12-19 04:24:51 +08:00
|
|
|
// size_t is unsigned long on Darwin and netbsd.
|
2014-01-04 03:22:05 +08:00
|
|
|
if (T.isOSDarwin() || T.getOS() == llvm::Triple::NetBSD)
|
2013-12-19 03:47:32 +08:00
|
|
|
SizeType = UnsignedLong;
|
2013-12-19 04:24:51 +08:00
|
|
|
else
|
|
|
|
SizeType = UnsignedInt;
|
|
|
|
|
2014-01-04 03:22:05 +08:00
|
|
|
if (T.getOS() == llvm::Triple::NetBSD) {
|
2013-12-19 04:24:51 +08:00
|
|
|
WCharType = SignedInt;
|
|
|
|
} else {
|
|
|
|
// AAPCS 7.1.1, ARM-Linux ABI 2.4: type of wchar_t is unsigned int.
|
|
|
|
WCharType = UnsignedInt;
|
|
|
|
}
|
|
|
|
|
|
|
|
UseBitFieldTypeAlignment = true;
|
|
|
|
|
|
|
|
ZeroLengthBitfieldBoundary = 0;
|
|
|
|
|
|
|
|
if (IsThumb) {
|
|
|
|
// Thumb1 add sp, #imm requires the immediate value be multiple of 4,
|
|
|
|
// so set preferred for small types to 32.
|
2014-01-04 03:22:05 +08:00
|
|
|
if (T.isOSBinFormatMachO())
|
|
|
|
DescriptionString = "e-m:o-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:64-"
|
|
|
|
"v128:64:128-a:0:32-n32-S64";
|
|
|
|
else
|
|
|
|
DescriptionString = "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:64-"
|
|
|
|
"v128:64:128-a:0:32-n32-S64";
|
|
|
|
|
2013-12-19 04:24:51 +08:00
|
|
|
} else {
|
2014-01-04 03:22:05 +08:00
|
|
|
if (T.isOSBinFormatMachO())
|
|
|
|
DescriptionString = "e-m:o-p:32:32-i64:64-v128:64:128-n32-S64";
|
|
|
|
else
|
|
|
|
DescriptionString = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64";
|
2013-12-19 04:24:51 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME: Enumerated types are variable width in straight AAPCS.
|
2013-12-19 03:47:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void setABIAPCS() {
|
2014-01-04 03:22:05 +08:00
|
|
|
const llvm::Triple &T = getTriple();
|
|
|
|
|
2013-12-19 04:24:51 +08:00
|
|
|
IsAAPCS = false;
|
|
|
|
|
2013-12-19 03:47:32 +08:00
|
|
|
DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32;
|
2013-12-19 04:24:51 +08:00
|
|
|
|
2013-12-19 03:47:32 +08:00
|
|
|
// size_t is unsigned int on FreeBSD.
|
2014-01-04 03:22:05 +08:00
|
|
|
if (T.getOS() == llvm::Triple::FreeBSD)
|
2013-12-19 04:24:51 +08:00
|
|
|
SizeType = UnsignedInt;
|
|
|
|
else
|
2013-12-19 03:47:32 +08:00
|
|
|
SizeType = UnsignedLong;
|
|
|
|
|
|
|
|
// Revert to using SignedInt on apcs-gnu to comply with existing behaviour.
|
|
|
|
WCharType = SignedInt;
|
|
|
|
|
|
|
|
// Do not respect the alignment of bit-field types when laying out
|
|
|
|
// structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
|
|
|
|
UseBitFieldTypeAlignment = false;
|
|
|
|
|
|
|
|
/// gcc forces the alignment to 4 bytes, regardless of the type of the
|
|
|
|
/// zero length bitfield. This corresponds to EMPTY_FIELD_BOUNDARY in
|
|
|
|
/// gcc.
|
|
|
|
ZeroLengthBitfieldBoundary = 32;
|
|
|
|
|
|
|
|
if (IsThumb) {
|
|
|
|
// Thumb1 add sp, #imm requires the immediate value be multiple of 4,
|
|
|
|
// so set preferred for small types to 32.
|
2014-01-04 03:22:05 +08:00
|
|
|
if (T.isOSBinFormatMachO())
|
|
|
|
DescriptionString = "e-m:o-p:32:32-i1:8:32-i8:8:32-i16:16:32-f64:32:64"
|
|
|
|
"-v64:32:64-v128:32:128-a:0:32-n32-S32";
|
|
|
|
else
|
|
|
|
DescriptionString = "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-f64:32:64"
|
|
|
|
"-v64:32:64-v128:32:128-a:0:32-n32-S32";
|
2013-12-19 03:47:32 +08:00
|
|
|
} else {
|
2014-01-04 03:22:05 +08:00
|
|
|
if (T.isOSBinFormatMachO())
|
|
|
|
DescriptionString =
|
|
|
|
"e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32";
|
|
|
|
else
|
|
|
|
DescriptionString =
|
|
|
|
"e-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32";
|
2013-12-19 03:47:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME: Override "preferred align" for double and long long.
|
|
|
|
}
|
|
|
|
|
2008-04-22 02:56:49 +08:00
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
ARMTargetInfo(const llvm::Triple &Triple)
|
2013-12-19 04:24:51 +08:00
|
|
|
: TargetInfo(Triple), CPU("arm1136j-s"), FPMath(FP_Default),
|
|
|
|
IsAAPCS(true) {
|
2011-12-22 11:51:45 +08:00
|
|
|
BigEndian = false;
|
2013-11-30 08:38:16 +08:00
|
|
|
switch (getTriple().getOS()) {
|
|
|
|
case llvm::Triple::NetBSD:
|
2013-12-03 00:09:34 +08:00
|
|
|
PtrDiffType = SignedLong;
|
2013-11-30 08:38:16 +08:00
|
|
|
break;
|
|
|
|
default:
|
2013-12-03 00:09:34 +08:00
|
|
|
PtrDiffType = SignedInt;
|
2013-11-30 08:38:16 +08:00
|
|
|
break;
|
|
|
|
}
|
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");
|
2013-12-19 04:24:51 +08:00
|
|
|
|
|
|
|
setABI("aapcs-linux");
|
2010-08-22 06:46:04 +08:00
|
|
|
|
|
|
|
// ARM targets default to using the ARM C++ ABI.
|
2013-01-26 06:30:49 +08:00
|
|
|
TheCXXABI.set(TargetCXXABI::GenericARM);
|
2011-10-15 04:59:01 +08:00
|
|
|
|
|
|
|
// ARM has atomics up to 8 bytes
|
|
|
|
MaxAtomicPromoteWidth = 64;
|
2013-05-14 04:09:47 +08:00
|
|
|
if (shouldUseInlineAtomic(getTriple()))
|
|
|
|
MaxAtomicInlineWidth = 64;
|
2012-03-12 17:14:10 +08:00
|
|
|
|
|
|
|
// Do force alignment of members that follow zero length bitfields. If
|
|
|
|
// the alignment of the zero-length bitfield is greater than the member
|
|
|
|
// that follows it, `bar', `bar' will be aligned as the type of the
|
|
|
|
// zero length bitfield.
|
|
|
|
UseZeroLengthBitfieldAlignment = true;
|
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") {
|
2013-12-19 03:47:32 +08:00
|
|
|
setABIAPCS();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") {
|
|
|
|
setABIAAPCS();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
2009-09-14 08:02:24 +08:00
|
|
|
}
|
2009-12-19 12:15:38 +08:00
|
|
|
|
2011-09-28 13:56:05 +08:00
|
|
|
void getDefaultFeatures(llvm::StringMap<bool> &Features) const {
|
2014-01-02 21:57:18 +08:00
|
|
|
if (IsAAPCS)
|
|
|
|
Features["aapcs"] = true;
|
|
|
|
else
|
|
|
|
Features["apcs"] = true;
|
|
|
|
|
2013-10-21 18:59:33 +08:00
|
|
|
StringRef ArchName = getTriple().getArchName();
|
2009-12-22 07:28:17 +08:00
|
|
|
if (CPU == "arm1136jf-s" || CPU == "arm1176jzf-s" || CPU == "mpcore")
|
|
|
|
Features["vfp2"] = true;
|
2013-09-14 01:02:45 +08:00
|
|
|
else if (CPU == "cortex-a8" || CPU == "cortex-a9" ||
|
|
|
|
CPU == "cortex-a9-mp") {
|
|
|
|
Features["vfp3"] = true;
|
2009-12-22 07:28:17 +08:00
|
|
|
Features["neon"] = true;
|
2013-10-21 18:59:33 +08:00
|
|
|
}
|
|
|
|
else if (CPU == "cortex-a5") {
|
|
|
|
Features["vfp4"] = true;
|
|
|
|
Features["neon"] = true;
|
2013-12-07 06:43:17 +08:00
|
|
|
} else if (CPU == "swift" || CPU == "cortex-a7" ||
|
|
|
|
CPU == "cortex-a12" || CPU == "cortex-a15" ||
|
|
|
|
CPU == "krait") {
|
2012-09-30 07:52:52 +08:00
|
|
|
Features["vfp4"] = true;
|
|
|
|
Features["neon"] = true;
|
2013-10-21 18:59:33 +08:00
|
|
|
Features["hwdiv"] = true;
|
|
|
|
Features["hwdiv-arm"] = true;
|
2013-10-25 02:32:51 +08:00
|
|
|
} else if (CPU == "cortex-a53" || CPU == "cortex-a57") {
|
|
|
|
Features["fp-armv8"] = true;
|
|
|
|
Features["neon"] = true;
|
|
|
|
Features["hwdiv"] = true;
|
|
|
|
Features["hwdiv-arm"] = true;
|
2013-10-29 17:47:51 +08:00
|
|
|
Features["crc"] = true;
|
2013-10-25 02:32:51 +08:00
|
|
|
} else if (CPU == "cortex-r5" || CPU == "cortex-m3" ||
|
2013-10-21 18:59:33 +08:00
|
|
|
CPU == "cortex-m4" ||
|
|
|
|
// Enable the hwdiv extension for all v8a AArch32 cores by
|
|
|
|
// default.
|
|
|
|
ArchName == "armv8a" || ArchName == "armv8" ||
|
|
|
|
ArchName == "thumbv8a" || ArchName == "thumbv8") {
|
|
|
|
Features["hwdiv"] = true;
|
|
|
|
Features["hwdiv-arm"] = true;
|
2012-09-30 07:52:52 +08:00
|
|
|
}
|
2009-12-22 07:28:17 +08:00
|
|
|
}
|
2010-10-21 11:16:25 +08:00
|
|
|
|
2013-10-17 05:26:26 +08:00
|
|
|
virtual bool handleTargetFeatures(std::vector<std::string> &Features,
|
2013-08-22 05:59:03 +08:00
|
|
|
DiagnosticsEngine &Diags) {
|
2012-09-30 07:52:52 +08:00
|
|
|
FPU = 0;
|
2013-10-29 17:47:51 +08:00
|
|
|
CRC = 0;
|
2009-12-19 12:15:38 +08:00
|
|
|
SoftFloat = SoftFloatABI = false;
|
2013-10-21 18:54:53 +08:00
|
|
|
HWDiv = 0;
|
2009-12-19 12:15:38 +08:00
|
|
|
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")
|
2012-09-30 07:52:52 +08:00
|
|
|
FPU |= VFP2FPU;
|
2009-12-22 07:28:17 +08:00
|
|
|
else if (Features[i] == "+vfp3")
|
2012-09-30 07:52:52 +08:00
|
|
|
FPU |= VFP3FPU;
|
|
|
|
else if (Features[i] == "+vfp4")
|
|
|
|
FPU |= VFP4FPU;
|
2013-10-25 02:32:51 +08:00
|
|
|
else if (Features[i] == "+fp-armv8")
|
|
|
|
FPU |= FPARMV8;
|
2009-12-22 07:28:17 +08:00
|
|
|
else if (Features[i] == "+neon")
|
2012-09-30 07:52:52 +08:00
|
|
|
FPU |= NeonFPU;
|
2013-10-21 18:54:53 +08:00
|
|
|
else if (Features[i] == "+hwdiv")
|
|
|
|
HWDiv |= HWDivThumb;
|
|
|
|
else if (Features[i] == "+hwdiv-arm")
|
|
|
|
HWDiv |= HWDivARM;
|
2013-10-29 17:47:51 +08:00
|
|
|
else if (Features[i] == "+crc")
|
|
|
|
CRC = 1;
|
2009-12-19 12:15:38 +08:00
|
|
|
}
|
|
|
|
|
2013-08-22 05:59:03 +08:00
|
|
|
if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
|
|
|
|
Diags.Report(diag::err_target_unsupported_fpmath) << "neon";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (FPMath == FP_Neon)
|
|
|
|
Features.push_back("+neonfp");
|
|
|
|
else if (FPMath == FP_VFP)
|
|
|
|
Features.push_back("-neonfp");
|
|
|
|
|
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);
|
2013-08-22 05:59:03 +08:00
|
|
|
return true;
|
2009-12-19 12:15:38 +08:00
|
|
|
}
|
|
|
|
|
2012-01-30 14:38:25 +08:00
|
|
|
virtual bool hasFeature(StringRef Feature) const {
|
|
|
|
return llvm::StringSwitch<bool>(Feature)
|
|
|
|
.Case("arm", true)
|
|
|
|
.Case("softfloat", SoftFloat)
|
|
|
|
.Case("thumb", IsThumb)
|
2013-09-17 02:07:35 +08:00
|
|
|
.Case("neon", (FPU & NeonFPU) && !SoftFloat)
|
2013-10-21 18:54:53 +08:00
|
|
|
.Case("hwdiv", HWDiv & HWDivThumb)
|
|
|
|
.Case("hwdiv-arm", HWDiv & HWDivARM)
|
2012-01-30 14:38:25 +08:00
|
|
|
.Default(false);
|
|
|
|
}
|
2012-09-08 16:08:27 +08:00
|
|
|
// FIXME: Should we actually have some table instead of these switches?
|
2011-07-23 18:55:15 +08:00
|
|
|
static const char *getCPUDefineSuffix(StringRef Name) {
|
2009-12-19 02:42:37 +08:00
|
|
|
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")
|
2013-03-05 06:37:46 +08:00
|
|
|
.Cases("cortex-a5", "cortex-a7", "cortex-a8", "7A")
|
2013-12-07 06:43:17 +08:00
|
|
|
.Cases("cortex-a9", "cortex-a12", "cortex-a15", "krait", "7A")
|
2013-09-14 01:02:54 +08:00
|
|
|
.Cases("cortex-r4", "cortex-r5", "7R")
|
2012-09-30 07:52:50 +08:00
|
|
|
.Case("cortex-a9-mp", "7F")
|
|
|
|
.Case("swift", "7S")
|
2012-09-08 16:08:27 +08:00
|
|
|
.Cases("cortex-m3", "cortex-m4", "7M")
|
2011-03-22 05:55:25 +08:00
|
|
|
.Case("cortex-m0", "6M")
|
2013-10-25 02:32:36 +08:00
|
|
|
.Cases("cortex-a53", "cortex-a57", "8A")
|
2009-12-19 02:42:37 +08:00
|
|
|
.Default(0);
|
|
|
|
}
|
2012-09-08 16:08:27 +08:00
|
|
|
static const char *getCPUProfile(StringRef Name) {
|
|
|
|
return llvm::StringSwitch<const char*>(Name)
|
2013-09-14 01:02:54 +08:00
|
|
|
.Cases("cortex-a5", "cortex-a7", "cortex-a8", "A")
|
2013-12-07 06:43:17 +08:00
|
|
|
.Cases("cortex-a9", "cortex-a12", "cortex-a15", "krait", "A")
|
2013-10-25 02:32:36 +08:00
|
|
|
.Cases("cortex-a53", "cortex-a57", "A")
|
2012-09-08 16:08:27 +08:00
|
|
|
.Cases("cortex-m3", "cortex-m4", "cortex-m0", "M")
|
2013-09-14 01:02:54 +08:00
|
|
|
.Cases("cortex-r4", "cortex-r5", "R")
|
2012-09-08 16:22:13 +08:00
|
|
|
.Default("");
|
2012-09-08 16:08:27 +08:00
|
|
|
}
|
2009-12-19 02:42:37 +08:00
|
|
|
virtual bool setCPU(const std::string &Name) {
|
|
|
|
if (!getCPUDefineSuffix(Name))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
CPU = Name;
|
|
|
|
return true;
|
|
|
|
}
|
2013-08-22 05:59:03 +08:00
|
|
|
virtual bool setFPMath(StringRef Name);
|
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
|
|
|
|
2011-07-23 18:55:15 +08:00
|
|
|
StringRef CPUArch = getCPUDefineSuffix(CPU);
|
2013-10-25 02:32:44 +08:00
|
|
|
unsigned int CPUArchVer;
|
|
|
|
if(CPUArch.substr(0, 1).getAsInteger<unsigned int>(10, CPUArchVer)) {
|
|
|
|
llvm_unreachable("Invalid char for architecture version number");
|
|
|
|
}
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__ARM_ARCH_" + CPUArch + "__");
|
2012-09-08 16:08:27 +08:00
|
|
|
Builder.defineMacro("__ARM_ARCH", CPUArch.substr(0, 1));
|
|
|
|
StringRef CPUProfile = getCPUProfile(CPU);
|
|
|
|
if (!CPUProfile.empty())
|
|
|
|
Builder.defineMacro("__ARM_ARCH_PROFILE", CPUProfile);
|
|
|
|
|
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.
|
2013-10-25 02:32:44 +08:00
|
|
|
if (5 <= CPUArchVer && CPUArchVer <= 7)
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__THUMB_INTERWORK__");
|
2009-12-19 02:42:37 +08:00
|
|
|
|
2012-10-25 21:33:01 +08:00
|
|
|
if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
|
2013-11-12 03:11:22 +08:00
|
|
|
// Embedded targets on Darwin follow AAPCS, but not EABI.
|
|
|
|
if (!getTriple().isOSDarwin())
|
2012-10-23 02:51:13 +08:00
|
|
|
Builder.defineMacro("__ARM_EABI__");
|
2012-09-08 16:08:27 +08:00
|
|
|
Builder.defineMacro("__ARM_PCS", "1");
|
|
|
|
|
2012-10-25 21:33:01 +08:00
|
|
|
if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp")
|
2012-09-08 16:08:27 +08:00
|
|
|
Builder.defineMacro("__ARM_PCS_VFP", "1");
|
|
|
|
}
|
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
|
|
|
|
|
|
|
if (IsThumb) {
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__THUMBEL__");
|
|
|
|
Builder.defineMacro("__thumb__");
|
2013-10-25 02:32:44 +08:00
|
|
|
if (CPUArch == "6T2" || CPUArchVer == 7)
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__thumb2__");
|
2009-09-18 00:21:10 +08:00
|
|
|
}
|
2013-10-21 18:54:53 +08:00
|
|
|
if (((HWDiv & HWDivThumb) && IsThumb) || ((HWDiv & HWDivARM) && !IsThumb))
|
|
|
|
Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
|
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
|
|
|
|
2012-09-30 07:52:52 +08:00
|
|
|
if (FPUModeIsVFP((FPUMode) FPU)) {
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__VFP_FP__");
|
2012-09-30 07:52:52 +08:00
|
|
|
if (FPU & VFP2FPU)
|
|
|
|
Builder.defineMacro("__ARM_VFPV2__");
|
|
|
|
if (FPU & VFP3FPU)
|
|
|
|
Builder.defineMacro("__ARM_VFPV3__");
|
|
|
|
if (FPU & VFP4FPU)
|
|
|
|
Builder.defineMacro("__ARM_VFPV4__");
|
|
|
|
}
|
|
|
|
|
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.
|
2013-11-21 20:36:34 +08:00
|
|
|
if ((FPU & NeonFPU) && !SoftFloat && CPUArchVer >= 7) {
|
|
|
|
Builder.defineMacro("__ARM_NEON");
|
2010-01-10 01:55:51 +08:00
|
|
|
Builder.defineMacro("__ARM_NEON__");
|
2013-11-21 20:36:34 +08:00
|
|
|
}
|
2013-09-18 18:07:09 +08:00
|
|
|
|
2013-10-29 17:47:51 +08:00
|
|
|
if (CRC)
|
2013-09-18 18:07:09 +08:00
|
|
|
Builder.defineMacro("__ARM_FEATURE_CRC32");
|
2013-10-01 06:51:32 +08:00
|
|
|
|
2013-10-25 02:32:44 +08:00
|
|
|
if (CPUArchVer >= 6 && CPUArch != "6M") {
|
2013-10-01 06:51:32 +08:00
|
|
|
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
|
|
|
|
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
|
|
|
|
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
|
|
|
|
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
|
|
|
|
}
|
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
|
|
|
}
|
2012-01-27 06:14:27 +08:00
|
|
|
virtual bool isCLZForZeroUndef() const { return false; }
|
2012-06-16 11:34:49 +08:00
|
|
|
virtual BuiltinVaListKind getBuiltinVaListKind() const {
|
2012-10-10 14:56:20 +08:00
|
|
|
return IsAAPCS ? AAPCSABIBuiltinVaList : TargetInfo::VoidPtrBuiltinVaList;
|
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 {
|
2009-03-01 01:11:49 +08:00
|
|
|
switch (*Name) {
|
2012-08-17 07:50:41 +08:00
|
|
|
default: break;
|
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;
|
2011-07-30 05:20:35 +08:00
|
|
|
case 'Q': // A memory address that is a single base register.
|
|
|
|
Info.setAllowsMemory();
|
|
|
|
return true;
|
2011-06-08 07:45:05 +08:00
|
|
|
case 'U': // a memory reference...
|
|
|
|
switch (Name[1]) {
|
|
|
|
case 'q': // ...ARMV4 ldrsb
|
|
|
|
case 'v': // ...VFP load/store (reg+constant offset)
|
|
|
|
case 'y': // ...iWMMXt load/store
|
2011-06-17 09:40:49 +08:00
|
|
|
case 't': // address valid for load/store opaque types wider
|
2012-11-15 06:08:59 +08:00
|
|
|
// than 128-bits
|
2011-06-17 09:40:49 +08:00
|
|
|
case 'n': // valid address for Neon doubleword vector load/store
|
|
|
|
case 'm': // valid address for Neon element and structure load/store
|
|
|
|
case 's': // valid address for non-offset loads/stores of quad-word
|
2012-11-15 06:08:59 +08:00
|
|
|
// values in four ARM registers
|
2011-06-08 07:45:05 +08:00
|
|
|
Info.setAllowsMemory();
|
|
|
|
Name++;
|
|
|
|
return true;
|
|
|
|
}
|
2008-04-22 13:03:19 +08:00
|
|
|
}
|
2008-04-22 02:56:49 +08:00
|
|
|
return false;
|
|
|
|
}
|
2011-06-17 03:13:15 +08:00
|
|
|
virtual std::string convertConstraint(const char *&Constraint) const {
|
2011-06-08 07:45:05 +08:00
|
|
|
std::string R;
|
|
|
|
switch (*Constraint) {
|
|
|
|
case 'U': // Two-character constraint; add "^" hint for later parsing.
|
2011-06-09 00:06:31 +08:00
|
|
|
R = std::string("^") + std::string(Constraint, 2);
|
2011-06-08 07:45:05 +08:00
|
|
|
Constraint++;
|
|
|
|
break;
|
2011-06-17 08:40:18 +08:00
|
|
|
case 'p': // 'p' should be translated to 'r' by default.
|
|
|
|
R = std::string("r");
|
|
|
|
break;
|
2011-06-08 07:45:05 +08:00
|
|
|
default:
|
|
|
|
return std::string(1, *Constraint);
|
|
|
|
}
|
|
|
|
return R;
|
|
|
|
}
|
2012-10-26 07:28:48 +08:00
|
|
|
virtual bool validateConstraintModifier(StringRef Constraint,
|
|
|
|
const char Modifier,
|
|
|
|
unsigned Size) const {
|
2012-12-01 07:18:12 +08:00
|
|
|
bool isOutput = (Constraint[0] == '=');
|
2012-12-01 07:46:56 +08:00
|
|
|
bool isInOut = (Constraint[0] == '+');
|
2012-12-01 07:18:12 +08:00
|
|
|
|
2012-10-26 07:28:48 +08:00
|
|
|
// Strip off constraint modifiers.
|
|
|
|
while (Constraint[0] == '=' ||
|
|
|
|
Constraint[0] == '+' ||
|
|
|
|
Constraint[0] == '&')
|
|
|
|
Constraint = Constraint.substr(1);
|
|
|
|
|
|
|
|
switch (Constraint[0]) {
|
|
|
|
default: break;
|
|
|
|
case 'r': {
|
|
|
|
switch (Modifier) {
|
|
|
|
default:
|
2013-12-08 23:24:55 +08:00
|
|
|
return (isInOut || isOutput || Size <= 64);
|
2012-10-26 07:28:48 +08:00
|
|
|
case 'q':
|
|
|
|
// A register of size 32 cannot fit a vector type.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2008-04-22 02:56:49 +08:00
|
|
|
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 "";
|
|
|
|
}
|
2012-10-02 22:26:08 +08:00
|
|
|
|
|
|
|
virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const {
|
|
|
|
return (CC == CC_AAPCS || CC == CC_AAPCS_VFP) ? CCCR_OK : CCCR_Warning;
|
|
|
|
}
|
2013-02-23 12:24:36 +08:00
|
|
|
|
|
|
|
virtual int getEHDataRegisterNumber(unsigned RegNo) const {
|
|
|
|
if (RegNo == 0) return 0;
|
|
|
|
if (RegNo == 1) return 1;
|
|
|
|
return -1;
|
|
|
|
}
|
2008-04-22 02:56:49 +08:00
|
|
|
};
|
2009-09-17 15:03:19 +08:00
|
|
|
|
2013-08-22 05:59:03 +08:00
|
|
|
bool ARMTargetInfo::setFPMath(StringRef Name) {
|
|
|
|
if (Name == "neon") {
|
|
|
|
FPMath = FP_Neon;
|
|
|
|
return true;
|
|
|
|
} else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" ||
|
|
|
|
Name == "vfp4") {
|
|
|
|
FPMath = FP_VFP;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
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[] = {
|
2011-07-06 05:53:01 +08:00
|
|
|
#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
|
2010-12-01 01:35:24 +08:00
|
|
|
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
|
2011-07-06 05:53:01 +08:00
|
|
|
ALL_LANGUAGES },
|
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 {
|
Implement a new 'availability' attribute, that allows one to specify
which versions of an OS provide a certain facility. For example,
void foo()
__attribute__((availability(macosx,introduced=10.2,deprecated=10.4,obsoleted=10.6)));
says that the function "foo" was introduced in 10.2, deprecated in
10.4, and completely obsoleted in 10.6. This attribute ties in with
the deployment targets (e.g., -mmacosx-version-min=10.1 specifies that
we want to deploy back to Mac OS X 10.1). There are several concrete
behaviors that this attribute enables, as illustrated with the
function foo() above:
- If we choose a deployment target >= Mac OS X 10.4, uses of "foo"
will result in a deprecation warning, as if we had placed
attribute((deprecated)) on it (but with a better diagnostic)
- If we choose a deployment target >= Mac OS X 10.6, uses of "foo"
will result in an "unavailable" warning (in C)/error (in C++), as
if we had placed attribute((unavailable)) on it
- If we choose a deployment target prior to 10.2, foo() is
weak-imported (if it is a kind of entity that can be weak
imported), as if we had placed the weak_import attribute on it.
Naturally, there can be multiple availability attributes on a
declaration, for different platforms; only the current platform
matters when checking availability attributes.
The only platforms this attribute currently works for are "ios" and
"macosx", since we already have -mxxxx-version-min flags for them and we
have experience there with macro tricks translating down to the
deprecated/unavailable/weak_import attributes. The end goal is to open
this up to other platforms, and even extension to other "platforms"
that are really libraries (say, through a #pragma clang
define_system), but that hasn't yet been designed and we may want to
shake out more issues with this narrower problem first.
Addresses <rdar://problem/6690412>.
As a drive-by bug-fix, if an entity is both deprecated and
unavailable, we only emit the "unavailable" diagnostic.
llvm-svn: 128127
2011-03-23 08:50:03 +08:00
|
|
|
getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
|
2008-08-20 15:44:10 +08:00
|
|
|
}
|
|
|
|
|
2009-03-24 00:09:04 +08:00
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
DarwinARMTargetInfo(const llvm::Triple &Triple)
|
|
|
|
: DarwinTargetInfo<ARMTargetInfo>(Triple) {
|
2010-05-27 15:00:26 +08:00
|
|
|
HasAlignMac68kSupport = true;
|
2011-10-15 04:59:01 +08:00
|
|
|
// iOS always has 64-bit atomic instructions.
|
|
|
|
// FIXME: This should be based off of the target features in ARMTargetInfo.
|
|
|
|
MaxAtomicInlineWidth = 64;
|
2013-01-26 06:30:49 +08:00
|
|
|
|
|
|
|
// Darwin on iOS uses a variant of the ARM C++ ABI.
|
|
|
|
TheCXXABI.set(TargetCXXABI::iOS);
|
2010-05-27 15:00:26 +08:00
|
|
|
}
|
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
|
|
|
|
2011-12-13 05:14:55 +08:00
|
|
|
|
|
|
|
namespace {
|
|
|
|
// Hexagon abstract base class
|
|
|
|
class HexagonTargetInfo : public TargetInfo {
|
|
|
|
static const Builtin::Info BuiltinInfo[];
|
|
|
|
static const char * const GCCRegNames[];
|
|
|
|
static const TargetInfo::GCCRegAlias GCCRegAliases[];
|
|
|
|
std::string CPU;
|
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
HexagonTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
|
2011-12-22 11:51:45 +08:00
|
|
|
BigEndian = false;
|
2014-01-04 03:22:05 +08:00
|
|
|
DescriptionString = "e-m:e-p:32:32-i1:32-i64:64-a:0-n32";
|
2011-12-13 05:14:55 +08:00
|
|
|
|
|
|
|
// {} in inline assembly are packet specifiers, not assembly variant
|
|
|
|
// specifiers.
|
|
|
|
NoAsmVariants = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void getTargetBuiltins(const Builtin::Info *&Records,
|
|
|
|
unsigned &NumRecords) const {
|
|
|
|
Records = BuiltinInfo;
|
|
|
|
NumRecords = clang::Hexagon::LastTSBuiltin-Builtin::FirstTSBuiltin;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual bool validateAsmConstraint(const char *&Name,
|
|
|
|
TargetInfo::ConstraintInfo &Info) const {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const;
|
|
|
|
|
2012-01-30 14:38:25 +08:00
|
|
|
virtual bool hasFeature(StringRef Feature) const {
|
|
|
|
return Feature == "hexagon";
|
|
|
|
}
|
|
|
|
|
2012-06-16 11:34:49 +08:00
|
|
|
virtual BuiltinVaListKind getBuiltinVaListKind() const {
|
|
|
|
return TargetInfo::CharPtrBuiltinVaList;
|
2011-12-13 05:14:55 +08:00
|
|
|
}
|
|
|
|
virtual void getGCCRegNames(const char * const *&Names,
|
|
|
|
unsigned &NumNames) const;
|
|
|
|
virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
|
|
|
|
unsigned &NumAliases) const;
|
|
|
|
virtual const char *getClobbers() const {
|
|
|
|
return "";
|
|
|
|
}
|
2012-01-14 04:37:10 +08:00
|
|
|
|
|
|
|
static const char *getHexagonCPUSuffix(StringRef Name) {
|
|
|
|
return llvm::StringSwitch<const char*>(Name)
|
|
|
|
.Case("hexagonv4", "4")
|
2012-05-11 04:19:54 +08:00
|
|
|
.Case("hexagonv5", "5")
|
2012-01-14 04:37:10 +08:00
|
|
|
.Default(0);
|
|
|
|
}
|
|
|
|
|
2011-12-13 05:14:55 +08:00
|
|
|
virtual bool setCPU(const std::string &Name) {
|
2012-01-14 04:37:10 +08:00
|
|
|
if (!getHexagonCPUSuffix(Name))
|
|
|
|
return false;
|
|
|
|
|
2011-12-13 05:14:55 +08:00
|
|
|
CPU = Name;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
Builder.defineMacro("qdsp6");
|
|
|
|
Builder.defineMacro("__qdsp6", "1");
|
|
|
|
Builder.defineMacro("__qdsp6__", "1");
|
|
|
|
|
|
|
|
Builder.defineMacro("hexagon");
|
|
|
|
Builder.defineMacro("__hexagon", "1");
|
|
|
|
Builder.defineMacro("__hexagon__", "1");
|
|
|
|
|
|
|
|
if(CPU == "hexagonv1") {
|
|
|
|
Builder.defineMacro("__HEXAGON_V1__");
|
|
|
|
Builder.defineMacro("__HEXAGON_ARCH__", "1");
|
|
|
|
if(Opts.HexagonQdsp6Compat) {
|
|
|
|
Builder.defineMacro("__QDSP6_V1__");
|
|
|
|
Builder.defineMacro("__QDSP6_ARCH__", "1");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(CPU == "hexagonv2") {
|
|
|
|
Builder.defineMacro("__HEXAGON_V2__");
|
|
|
|
Builder.defineMacro("__HEXAGON_ARCH__", "2");
|
|
|
|
if(Opts.HexagonQdsp6Compat) {
|
|
|
|
Builder.defineMacro("__QDSP6_V2__");
|
|
|
|
Builder.defineMacro("__QDSP6_ARCH__", "2");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(CPU == "hexagonv3") {
|
|
|
|
Builder.defineMacro("__HEXAGON_V3__");
|
|
|
|
Builder.defineMacro("__HEXAGON_ARCH__", "3");
|
|
|
|
if(Opts.HexagonQdsp6Compat) {
|
|
|
|
Builder.defineMacro("__QDSP6_V3__");
|
|
|
|
Builder.defineMacro("__QDSP6_ARCH__", "3");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(CPU == "hexagonv4") {
|
|
|
|
Builder.defineMacro("__HEXAGON_V4__");
|
|
|
|
Builder.defineMacro("__HEXAGON_ARCH__", "4");
|
|
|
|
if(Opts.HexagonQdsp6Compat) {
|
|
|
|
Builder.defineMacro("__QDSP6_V4__");
|
|
|
|
Builder.defineMacro("__QDSP6_ARCH__", "4");
|
|
|
|
}
|
|
|
|
}
|
2012-05-11 04:19:54 +08:00
|
|
|
else if(CPU == "hexagonv5") {
|
|
|
|
Builder.defineMacro("__HEXAGON_V5__");
|
|
|
|
Builder.defineMacro("__HEXAGON_ARCH__", "5");
|
|
|
|
if(Opts.HexagonQdsp6Compat) {
|
|
|
|
Builder.defineMacro("__QDSP6_V5__");
|
|
|
|
Builder.defineMacro("__QDSP6_ARCH__", "5");
|
|
|
|
}
|
|
|
|
}
|
2011-12-13 05:14:55 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
const char * const HexagonTargetInfo::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",
|
|
|
|
"p0", "p1", "p2", "p3",
|
|
|
|
"sa0", "lc0", "sa1", "lc1", "m0", "m1", "usr", "ugp"
|
|
|
|
};
|
|
|
|
|
|
|
|
void HexagonTargetInfo::getGCCRegNames(const char * const *&Names,
|
|
|
|
unsigned &NumNames) const {
|
|
|
|
Names = GCCRegNames;
|
|
|
|
NumNames = llvm::array_lengthof(GCCRegNames);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = {
|
|
|
|
{ { "sp" }, "r29" },
|
|
|
|
{ { "fp" }, "r30" },
|
|
|
|
{ { "lr" }, "r31" },
|
|
|
|
};
|
|
|
|
|
|
|
|
void HexagonTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
|
|
|
|
unsigned &NumAliases) const {
|
|
|
|
Aliases = GCCRegAliases;
|
|
|
|
NumAliases = llvm::array_lengthof(GCCRegAliases);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const Builtin::Info HexagonTargetInfo::BuiltinInfo[] = {
|
|
|
|
#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
|
|
|
|
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
|
|
|
|
ALL_LANGUAGES },
|
|
|
|
#include "clang/Basic/BuiltinsHexagon.def"
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-22 00:29:08 +08:00
|
|
|
namespace {
|
2013-04-16 23:17:49 +08:00
|
|
|
// Shared base class for SPARC v8 (32-bit) and SPARC v9 (64-bit).
|
|
|
|
class SparcTargetInfo : 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:
|
2013-06-30 00:37:14 +08:00
|
|
|
SparcTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {}
|
2013-04-16 23:17:49 +08:00
|
|
|
|
2013-10-17 05:26:26 +08:00
|
|
|
virtual bool handleTargetFeatures(std::vector<std::string> &Features,
|
2013-08-22 05:59:03 +08:00
|
|
|
DiagnosticsEngine &Diags) {
|
2010-11-10 01:21:19 +08:00
|
|
|
SoftFloat = false;
|
|
|
|
for (unsigned i = 0, e = Features.size(); i != e; ++i)
|
|
|
|
if (Features[i] == "+soft-float")
|
|
|
|
SoftFloat = true;
|
2013-08-22 05:59:03 +08:00
|
|
|
return true;
|
2010-11-10 01:21:19 +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 {
|
|
|
|
DefineStd(Builder, "sparc", Opts);
|
|
|
|
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
|
|
|
}
|
2012-01-30 14:38:25 +08:00
|
|
|
|
|
|
|
virtual bool hasFeature(StringRef Feature) const {
|
|
|
|
return llvm::StringSwitch<bool>(Feature)
|
|
|
|
.Case("softfloat", SoftFloat)
|
|
|
|
.Case("sparc", true)
|
|
|
|
.Default(false);
|
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
2012-06-16 11:34:49 +08:00
|
|
|
virtual BuiltinVaListKind getBuiltinVaListKind() const {
|
|
|
|
return TargetInfo::VoidPtrBuiltinVaList;
|
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
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2013-04-16 23:17:49 +08:00
|
|
|
const char * const SparcTargetInfo::GCCRegNames[] = {
|
2009-01-27 09:58:38 +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"
|
|
|
|
};
|
|
|
|
|
2013-04-16 23:17:49 +08:00
|
|
|
void SparcTargetInfo::getGCCRegNames(const char * const *&Names,
|
|
|
|
unsigned &NumNames) const {
|
2009-01-27 09:58:38 +08:00
|
|
|
Names = GCCRegNames;
|
|
|
|
NumNames = llvm::array_lengthof(GCCRegNames);
|
|
|
|
}
|
|
|
|
|
2013-04-16 23:17:49 +08:00
|
|
|
const TargetInfo::GCCRegAlias SparcTargetInfo::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
|
|
|
};
|
|
|
|
|
2013-04-16 23:17:49 +08:00
|
|
|
void SparcTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
|
|
|
|
unsigned &NumAliases) const {
|
2009-01-27 09:58:38 +08:00
|
|
|
Aliases = GCCRegAliases;
|
|
|
|
NumAliases = llvm::array_lengthof(GCCRegAliases);
|
|
|
|
}
|
2013-04-16 23:17:49 +08:00
|
|
|
|
|
|
|
// SPARC v8 is the 32-bit mode selected by Triple::sparc.
|
|
|
|
class SparcV8TargetInfo : public SparcTargetInfo {
|
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
SparcV8TargetInfo(const llvm::Triple &Triple) : SparcTargetInfo(Triple) {
|
2014-01-04 03:22:05 +08:00
|
|
|
DescriptionString = "E-m:e-p:32:32-i64:64-f128:64-n32-S64";
|
2013-04-16 23:17:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
SparcTargetInfo::getTargetDefines(Opts, Builder);
|
|
|
|
Builder.defineMacro("__sparcv8");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// SPARC v9 is the 64-bit mode selected by Triple::sparcv9.
|
|
|
|
class SparcV9TargetInfo : public SparcTargetInfo {
|
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
SparcV9TargetInfo(const llvm::Triple &Triple) : SparcTargetInfo(Triple) {
|
2013-04-16 23:17:49 +08:00
|
|
|
// FIXME: Support Sparc quad-precision long double?
|
2014-01-04 03:22:05 +08:00
|
|
|
DescriptionString = "E-m:e-i64:64-n32:64-S128";
|
2013-05-15 11:22:33 +08:00
|
|
|
// This is an LP64 platform.
|
|
|
|
LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
|
2013-05-20 01:53:37 +08:00
|
|
|
|
|
|
|
// OpenBSD uses long long for int64_t and intmax_t.
|
|
|
|
if (getTriple().getOS() == llvm::Triple::OpenBSD) {
|
|
|
|
IntMaxType = SignedLongLong;
|
|
|
|
UIntMaxType = UnsignedLongLong;
|
|
|
|
} else {
|
|
|
|
IntMaxType = SignedLong;
|
|
|
|
UIntMaxType = UnsignedLong;
|
|
|
|
}
|
|
|
|
Int64Type = IntMaxType;
|
2013-04-16 23:17:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
SparcTargetInfo::getTargetDefines(Opts, Builder);
|
|
|
|
Builder.defineMacro("__sparcv9");
|
2013-04-24 12:36:38 +08:00
|
|
|
Builder.defineMacro("__arch64__");
|
|
|
|
// Solaris and its derivative AuroraUX don't need these variants, but the
|
|
|
|
// BSDs do.
|
|
|
|
if (getTriple().getOS() != llvm::Triple::Solaris &&
|
|
|
|
getTriple().getOS() != llvm::Triple::AuroraUX) {
|
|
|
|
Builder.defineMacro("__sparc64__");
|
|
|
|
Builder.defineMacro("__sparc_v9__");
|
|
|
|
Builder.defineMacro("__sparcv9__");
|
|
|
|
}
|
2013-04-16 23:17:49 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
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:
|
2013-06-30 00:37:14 +08:00
|
|
|
AuroraUXSparcV8TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: AuroraUXTargetInfo<SparcV8TargetInfo>(Triple) {
|
2009-10-18 21:33:59 +08:00
|
|
|
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:
|
2013-06-30 00:37:14 +08:00
|
|
|
SolarisSparcV8TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: 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
|
|
|
|
2013-05-07 00:26:41 +08:00
|
|
|
namespace {
|
|
|
|
class SystemZTargetInfo : public TargetInfo {
|
|
|
|
static const char *const GCCRegNames[];
|
|
|
|
|
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
SystemZTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
|
2013-05-07 00:26:41 +08:00
|
|
|
TLSSupported = true;
|
|
|
|
IntWidth = IntAlign = 32;
|
|
|
|
LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64;
|
|
|
|
PointerWidth = PointerAlign = 64;
|
|
|
|
LongDoubleWidth = 128;
|
|
|
|
LongDoubleAlign = 64;
|
|
|
|
LongDoubleFormat = &llvm::APFloat::IEEEquad;
|
|
|
|
MinGlobalAlign = 16;
|
2014-01-04 03:22:05 +08:00
|
|
|
DescriptionString = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64";
|
2013-05-07 00:26:41 +08:00
|
|
|
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
|
|
|
|
}
|
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
Builder.defineMacro("__s390__");
|
|
|
|
Builder.defineMacro("__s390x__");
|
|
|
|
Builder.defineMacro("__zarch__");
|
|
|
|
Builder.defineMacro("__LONG_DOUBLE_128__");
|
|
|
|
}
|
|
|
|
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;
|
|
|
|
virtual const char *getClobbers() const {
|
|
|
|
// FIXME: Is this really right?
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
virtual BuiltinVaListKind getBuiltinVaListKind() const {
|
|
|
|
return TargetInfo::SystemZBuiltinVaList;
|
|
|
|
}
|
2013-07-20 00:51:51 +08:00
|
|
|
virtual bool setCPU(const std::string &Name) {
|
|
|
|
bool CPUKnown = llvm::StringSwitch<bool>(Name)
|
|
|
|
.Case("z10", true)
|
|
|
|
.Case("z196", true)
|
|
|
|
.Case("zEC12", true)
|
|
|
|
.Default(false);
|
|
|
|
|
|
|
|
// No need to store the CPU yet. There aren't any CPU-specific
|
|
|
|
// macros to define.
|
|
|
|
return CPUKnown;
|
|
|
|
}
|
2013-05-07 00:26:41 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
const char *const SystemZTargetInfo::GCCRegNames[] = {
|
|
|
|
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
|
|
|
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
|
|
|
|
"f0", "f2", "f4", "f6", "f1", "f3", "f5", "f7",
|
|
|
|
"f8", "f10", "f12", "f14", "f9", "f11", "f13", "f15"
|
|
|
|
};
|
|
|
|
|
|
|
|
void SystemZTargetInfo::getGCCRegNames(const char *const *&Names,
|
|
|
|
unsigned &NumNames) const {
|
|
|
|
Names = GCCRegNames;
|
|
|
|
NumNames = llvm::array_lengthof(GCCRegNames);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SystemZTargetInfo::
|
|
|
|
validateAsmConstraint(const char *&Name,
|
|
|
|
TargetInfo::ConstraintInfo &Info) const {
|
|
|
|
switch (*Name) {
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
|
|
|
|
case 'a': // Address register
|
|
|
|
case 'd': // Data register (equivalent to 'r')
|
|
|
|
case 'f': // Floating-point register
|
|
|
|
Info.setAllowsRegister();
|
|
|
|
return true;
|
|
|
|
|
|
|
|
case 'I': // Unsigned 8-bit constant
|
|
|
|
case 'J': // Unsigned 12-bit constant
|
|
|
|
case 'K': // Signed 16-bit constant
|
|
|
|
case 'L': // Signed 20-bit displacement (on all targets we support)
|
|
|
|
case 'M': // 0x7fffffff
|
|
|
|
return true;
|
|
|
|
|
|
|
|
case 'Q': // Memory with base and unsigned 12-bit displacement
|
|
|
|
case 'R': // Likewise, plus an index
|
|
|
|
case 'S': // Memory with base and signed 20-bit displacement
|
|
|
|
case 'T': // Likewise, plus an index
|
|
|
|
Info.setAllowsMemory();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-05-03 21:43:08 +08:00
|
|
|
namespace {
|
|
|
|
class MSP430TargetInfo : public TargetInfo {
|
|
|
|
static const char * const GCCRegNames[];
|
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
MSP430TargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
|
2011-12-22 11:51:45 +08:00
|
|
|
BigEndian = false;
|
2009-05-03 21:43:08 +08:00
|
|
|
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;
|
2011-12-17 06:34:14 +08:00
|
|
|
SuitableAlign = 16;
|
2009-05-03 21:43:08 +08:00
|
|
|
SizeType = UnsignedInt;
|
2013-07-02 03:42:40 +08:00
|
|
|
IntMaxType = SignedLongLong;
|
|
|
|
UIntMaxType = UnsignedLongLong;
|
|
|
|
IntPtrType = SignedInt;
|
2009-05-03 21:43:08 +08:00
|
|
|
PtrDiffType = SignedInt;
|
2009-11-21 08:49:54 +08:00
|
|
|
SigAtomicType = SignedLong;
|
2014-01-04 03:22:05 +08:00
|
|
|
DescriptionString = "e-m:e-p: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;
|
|
|
|
}
|
2012-01-30 14:38:25 +08:00
|
|
|
virtual bool hasFeature(StringRef Feature) const {
|
|
|
|
return Feature == "msp430";
|
|
|
|
}
|
2009-05-03 21:43:08 +08:00
|
|
|
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 "";
|
|
|
|
}
|
2012-06-16 11:34:49 +08:00
|
|
|
virtual BuiltinVaListKind getBuiltinVaListKind() const {
|
2009-05-03 21:43:08 +08:00
|
|
|
// FIXME: implement
|
2012-06-16 11:34:49 +08:00
|
|
|
return TargetInfo::CharPtrBuiltinVaList;
|
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-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
|
|
|
|
|
2011-10-08 03:51:42 +08:00
|
|
|
static const unsigned TCEOpenCLAddrSpaceMap[] = {
|
|
|
|
3, // opencl_global
|
|
|
|
4, // opencl_local
|
2012-05-21 05:08:35 +08:00
|
|
|
5, // opencl_constant
|
|
|
|
0, // cuda_device
|
|
|
|
0, // cuda_constant
|
|
|
|
0 // cuda_shared
|
2011-10-08 03:51:42 +08:00
|
|
|
};
|
|
|
|
|
2009-08-20 04:47:07 +08:00
|
|
|
class TCETargetInfo : public TargetInfo{
|
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
TCETargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
|
2009-08-20 04:47:07 +08:00
|
|
|
TLSSupported = false;
|
|
|
|
IntWidth = 32;
|
|
|
|
LongWidth = LongLongWidth = 32;
|
|
|
|
PointerWidth = 32;
|
|
|
|
IntAlign = 32;
|
|
|
|
LongAlign = LongLongAlign = 32;
|
|
|
|
PointerAlign = 32;
|
2011-12-17 06:34:14 +08:00
|
|
|
SuitableAlign = 32;
|
2009-08-20 04:47:07 +08:00
|
|
|
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;
|
2014-01-04 02:13:17 +08:00
|
|
|
DescriptionString = "E-p:32:32-i8:8:32-i16:16:32-i64:32"
|
|
|
|
"-f64:32-v64:32-v128:32-a:0:32-n32";
|
2011-10-08 03:51:42 +08:00
|
|
|
AddrSpaceMap = &TCEOpenCLAddrSpaceMap;
|
2013-09-13 20:04:22 +08:00
|
|
|
UseAddrSpaceMapMangling = true;
|
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
|
|
|
}
|
2012-01-30 14:38:25 +08:00
|
|
|
virtual bool hasFeature(StringRef Feature) const {
|
|
|
|
return Feature == "tce";
|
|
|
|
}
|
|
|
|
|
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 "";
|
|
|
|
}
|
2012-06-16 11:34:49 +08:00
|
|
|
virtual BuiltinVaListKind getBuiltinVaListKind() const {
|
|
|
|
return TargetInfo::VoidPtrBuiltinVaList;
|
2009-08-20 04:47:07 +08:00
|
|
|
}
|
|
|
|
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 {
|
2011-09-21 03:00:23 +08:00
|
|
|
class MipsTargetInfoBase : public TargetInfo {
|
2013-10-30 02:30:33 +08:00
|
|
|
virtual void setDescriptionString() = 0;
|
|
|
|
|
2012-06-29 02:23:16 +08:00
|
|
|
static const Builtin::Info BuiltinInfo[];
|
2011-09-21 03:00:23 +08:00
|
|
|
std::string CPU;
|
2012-07-06 00:06:06 +08:00
|
|
|
bool IsMips16;
|
2013-04-14 22:07:51 +08:00
|
|
|
bool IsMicromips;
|
2013-09-24 17:09:16 +08:00
|
|
|
bool IsNan2008;
|
2013-04-14 22:07:30 +08:00
|
|
|
bool IsSingleFloat;
|
2012-07-05 23:32:46 +08:00
|
|
|
enum MipsFloatABI {
|
2013-04-14 22:07:30 +08:00
|
|
|
HardFloat, SoftFloat
|
2012-07-05 23:32:46 +08:00
|
|
|
} FloatABI;
|
2012-07-06 04:16:22 +08:00
|
|
|
enum DspRevEnum {
|
|
|
|
NoDSP, DSP1, DSP2
|
|
|
|
} DspRev;
|
2013-08-13 01:20:29 +08:00
|
|
|
bool HasMSA;
|
2012-03-24 07:07:09 +08:00
|
|
|
|
2011-09-21 03:00:23 +08:00
|
|
|
protected:
|
2013-10-30 03:00:35 +08:00
|
|
|
bool HasFP64;
|
2011-09-21 03:00:23 +08:00
|
|
|
std::string ABI;
|
2012-03-24 07:07:09 +08:00
|
|
|
|
2009-11-15 18:22:07 +08:00
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
MipsTargetInfoBase(const llvm::Triple &Triple, const std::string &ABIStr,
|
|
|
|
const std::string &CPUStr)
|
|
|
|
: TargetInfo(Triple), CPU(CPUStr), IsMips16(false), IsMicromips(false),
|
2013-09-24 17:09:16 +08:00
|
|
|
IsNan2008(false), IsSingleFloat(false), FloatABI(HardFloat),
|
2013-10-18 21:13:53 +08:00
|
|
|
DspRev(NoDSP), HasMSA(false), HasFP64(false), ABI(ABIStr) {}
|
2012-03-24 07:07:09 +08:00
|
|
|
|
2010-03-02 10:41:08 +08:00
|
|
|
virtual const char *getABI() const { return ABI.c_str(); }
|
2011-09-21 03:00:23 +08:00
|
|
|
virtual bool setABI(const std::string &Name) = 0;
|
2010-03-02 10:41:08 +08:00
|
|
|
virtual bool setCPU(const std::string &Name) {
|
|
|
|
CPU = Name;
|
|
|
|
return true;
|
|
|
|
}
|
2011-09-28 13:56:05 +08:00
|
|
|
void getDefaultFeatures(llvm::StringMap<bool> &Features) const {
|
2010-03-02 10:41:08 +08:00
|
|
|
Features[ABI] = true;
|
|
|
|
Features[CPU] = true;
|
|
|
|
}
|
2012-03-24 07:07:09 +08:00
|
|
|
|
2012-08-30 03:59:32 +08:00
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const {
|
2012-08-30 03:14:58 +08:00
|
|
|
DefineStd(Builder, "mips", Opts);
|
|
|
|
Builder.defineMacro("_mips");
|
|
|
|
Builder.defineMacro("__REGISTER_PREFIX__", "");
|
|
|
|
|
2012-07-05 23:32:46 +08:00
|
|
|
switch (FloatABI) {
|
|
|
|
case HardFloat:
|
|
|
|
Builder.defineMacro("__mips_hard_float", Twine(1));
|
|
|
|
break;
|
|
|
|
case SoftFloat:
|
|
|
|
Builder.defineMacro("__mips_soft_float", Twine(1));
|
|
|
|
break;
|
2012-06-05 21:06:56 +08:00
|
|
|
}
|
2012-04-06 03:28:31 +08:00
|
|
|
|
2013-04-14 22:07:30 +08:00
|
|
|
if (IsSingleFloat)
|
|
|
|
Builder.defineMacro("__mips_single_float", Twine(1));
|
|
|
|
|
2013-10-18 21:13:53 +08:00
|
|
|
Builder.defineMacro("__mips_fpr", HasFP64 ? Twine(64) : Twine(32));
|
|
|
|
Builder.defineMacro("_MIPS_FPSET",
|
|
|
|
Twine(32 / (HasFP64 || IsSingleFloat ? 1 : 2)));
|
|
|
|
|
2012-07-06 00:06:06 +08:00
|
|
|
if (IsMips16)
|
|
|
|
Builder.defineMacro("__mips16", Twine(1));
|
|
|
|
|
2013-04-14 22:07:51 +08:00
|
|
|
if (IsMicromips)
|
|
|
|
Builder.defineMacro("__mips_micromips", Twine(1));
|
|
|
|
|
2013-09-24 17:09:16 +08:00
|
|
|
if (IsNan2008)
|
|
|
|
Builder.defineMacro("__mips_nan2008", Twine(1));
|
|
|
|
|
2012-07-06 04:16:22 +08:00
|
|
|
switch (DspRev) {
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
case DSP1:
|
|
|
|
Builder.defineMacro("__mips_dsp_rev", Twine(1));
|
|
|
|
Builder.defineMacro("__mips_dsp", Twine(1));
|
|
|
|
break;
|
|
|
|
case DSP2:
|
|
|
|
Builder.defineMacro("__mips_dsp_rev", Twine(2));
|
|
|
|
Builder.defineMacro("__mips_dspr2", Twine(1));
|
|
|
|
Builder.defineMacro("__mips_dsp", Twine(1));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2013-08-13 01:20:29 +08:00
|
|
|
if (HasMSA)
|
|
|
|
Builder.defineMacro("__mips_msa", Twine(1));
|
|
|
|
|
2012-04-06 03:28:31 +08:00
|
|
|
Builder.defineMacro("_MIPS_SZPTR", Twine(getPointerWidth(0)));
|
|
|
|
Builder.defineMacro("_MIPS_SZINT", Twine(getIntWidth()));
|
|
|
|
Builder.defineMacro("_MIPS_SZLONG", Twine(getLongWidth()));
|
2012-08-29 23:17:29 +08:00
|
|
|
|
|
|
|
Builder.defineMacro("_MIPS_ARCH", "\"" + CPU + "\"");
|
|
|
|
Builder.defineMacro("_MIPS_ARCH_" + StringRef(CPU).upper());
|
2012-03-24 07:07:09 +08:00
|
|
|
}
|
|
|
|
|
2009-11-15 18:22:07 +08:00
|
|
|
virtual void getTargetBuiltins(const Builtin::Info *&Records,
|
|
|
|
unsigned &NumRecords) const {
|
2012-06-29 02:23:16 +08:00
|
|
|
Records = BuiltinInfo;
|
|
|
|
NumRecords = clang::Mips::LastTSBuiltin - Builtin::FirstTSBuiltin;
|
2009-11-15 18:22:07 +08:00
|
|
|
}
|
2012-01-30 14:38:25 +08:00
|
|
|
virtual bool hasFeature(StringRef Feature) const {
|
2013-10-30 03:00:35 +08:00
|
|
|
return llvm::StringSwitch<bool>(Feature)
|
|
|
|
.Case("mips", true)
|
|
|
|
.Case("fp64", HasFP64)
|
|
|
|
.Default(false);
|
2012-01-30 14:38:25 +08:00
|
|
|
}
|
2012-06-16 11:34:49 +08:00
|
|
|
virtual BuiltinVaListKind getBuiltinVaListKind() const {
|
|
|
|
return TargetInfo::VoidPtrBuiltinVaList;
|
2009-11-15 18:22:07 +08:00
|
|
|
}
|
|
|
|
virtual void getGCCRegNames(const char * const *&Names,
|
2011-09-21 03:00:23 +08:00
|
|
|
unsigned &NumNames) const {
|
2013-11-12 20:56:01 +08:00
|
|
|
static const char *const GCCRegNames[] = {
|
2012-03-28 03:56:11 +08:00
|
|
|
// CPU register names
|
|
|
|
// Must match second column of GCCRegAliases
|
2011-09-21 03:00:23 +08:00
|
|
|
"$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
|
|
|
|
"$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
|
|
|
|
"$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
|
2012-03-28 03:56:11 +08:00
|
|
|
"$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31",
|
|
|
|
// Floating point register names
|
2011-09-21 03:00:23 +08:00
|
|
|
"$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",
|
2012-03-28 03:56:11 +08:00
|
|
|
// Hi/lo and condition register names
|
2011-09-21 03:00:23 +08:00
|
|
|
"hi", "lo", "", "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
|
2013-11-12 20:56:01 +08:00
|
|
|
"$fcc5","$fcc6","$fcc7",
|
|
|
|
// MSA register names
|
|
|
|
"$w0", "$w1", "$w2", "$w3", "$w4", "$w5", "$w6", "$w7",
|
|
|
|
"$w8", "$w9", "$w10", "$w11", "$w12", "$w13", "$w14", "$w15",
|
|
|
|
"$w16", "$w17", "$w18", "$w19", "$w20", "$w21", "$w22", "$w23",
|
|
|
|
"$w24", "$w25", "$w26", "$w27", "$w28", "$w29", "$w30", "$w31",
|
|
|
|
// MSA control register names
|
|
|
|
"$msair", "$msacsr", "$msaaccess", "$msasave", "$msamodify",
|
|
|
|
"$msarequest", "$msamap", "$msaunmap"
|
2011-09-21 03:00:23 +08:00
|
|
|
};
|
|
|
|
Names = GCCRegNames;
|
|
|
|
NumNames = llvm::array_lengthof(GCCRegNames);
|
|
|
|
}
|
2009-11-15 18:22:07 +08:00
|
|
|
virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
|
2011-09-21 03:00:23 +08:00
|
|
|
unsigned &NumAliases) const = 0;
|
2009-11-15 18:22:07 +08:00
|
|
|
virtual bool validateAsmConstraint(const char *&Name,
|
|
|
|
TargetInfo::ConstraintInfo &Info) const {
|
|
|
|
switch (*Name) {
|
|
|
|
default:
|
2011-11-03 04:52:01 +08:00
|
|
|
return false;
|
|
|
|
|
2009-11-15 18:22:07 +08:00
|
|
|
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.
|
2012-04-03 09:16:32 +08:00
|
|
|
case 'c': // $25 for indirect jumps
|
|
|
|
case 'l': // lo register
|
|
|
|
case 'x': // hilo register pair
|
2009-11-15 18:22:07 +08:00
|
|
|
Info.setAllowsRegister();
|
|
|
|
return true;
|
2013-03-06 03:10:54 +08:00
|
|
|
case 'R': // An address that can be used in a non-macro load or store
|
2013-03-05 05:36:11 +08:00
|
|
|
Info.setAllowsMemory();
|
|
|
|
return true;
|
2009-11-15 18:22:07 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual const char *getClobbers() const {
|
|
|
|
// FIXME: Implement!
|
|
|
|
return "";
|
|
|
|
}
|
2012-03-24 07:07:09 +08:00
|
|
|
|
2013-10-17 05:26:26 +08:00
|
|
|
virtual bool handleTargetFeatures(std::vector<std::string> &Features,
|
2013-08-22 05:59:03 +08:00
|
|
|
DiagnosticsEngine &Diags) {
|
2012-07-06 00:06:06 +08:00
|
|
|
IsMips16 = false;
|
2013-04-14 22:07:51 +08:00
|
|
|
IsMicromips = false;
|
2013-09-24 17:09:16 +08:00
|
|
|
IsNan2008 = false;
|
2013-04-14 22:07:30 +08:00
|
|
|
IsSingleFloat = false;
|
2012-07-05 23:32:46 +08:00
|
|
|
FloatABI = HardFloat;
|
2012-07-06 04:16:22 +08:00
|
|
|
DspRev = NoDSP;
|
2013-10-18 21:13:53 +08:00
|
|
|
HasFP64 = ABI == "n32" || ABI == "n64" || ABI == "64";
|
2012-03-24 07:07:09 +08:00
|
|
|
|
|
|
|
for (std::vector<std::string>::iterator it = Features.begin(),
|
|
|
|
ie = Features.end(); it != ie; ++it) {
|
2012-07-05 23:32:46 +08:00
|
|
|
if (*it == "+single-float")
|
2013-04-14 22:07:30 +08:00
|
|
|
IsSingleFloat = true;
|
2012-07-05 23:32:46 +08:00
|
|
|
else if (*it == "+soft-float")
|
|
|
|
FloatABI = SoftFloat;
|
2012-07-06 00:06:06 +08:00
|
|
|
else if (*it == "+mips16")
|
|
|
|
IsMips16 = true;
|
2013-04-14 22:07:51 +08:00
|
|
|
else if (*it == "+micromips")
|
|
|
|
IsMicromips = true;
|
2012-07-06 04:16:22 +08:00
|
|
|
else if (*it == "+dsp")
|
|
|
|
DspRev = std::max(DspRev, DSP1);
|
|
|
|
else if (*it == "+dspr2")
|
|
|
|
DspRev = std::max(DspRev, DSP2);
|
2013-08-13 01:20:29 +08:00
|
|
|
else if (*it == "+msa")
|
|
|
|
HasMSA = true;
|
2013-10-18 21:13:53 +08:00
|
|
|
else if (*it == "+fp64")
|
|
|
|
HasFP64 = true;
|
|
|
|
else if (*it == "-fp64")
|
|
|
|
HasFP64 = false;
|
2013-09-24 17:09:16 +08:00
|
|
|
else if (*it == "+nan2008")
|
|
|
|
IsNan2008 = true;
|
2012-03-24 07:07:09 +08:00
|
|
|
}
|
2012-07-05 23:32:46 +08:00
|
|
|
|
2013-09-24 17:09:16 +08:00
|
|
|
// Remove front-end specific options.
|
2012-07-05 23:32:46 +08:00
|
|
|
std::vector<std::string>::iterator it =
|
|
|
|
std::find(Features.begin(), Features.end(), "+soft-float");
|
|
|
|
if (it != Features.end())
|
|
|
|
Features.erase(it);
|
2013-09-24 17:09:16 +08:00
|
|
|
it = std::find(Features.begin(), Features.end(), "+nan2008");
|
|
|
|
if (it != Features.end())
|
|
|
|
Features.erase(it);
|
2013-08-22 05:59:03 +08:00
|
|
|
|
2013-10-30 02:30:33 +08:00
|
|
|
setDescriptionString();
|
|
|
|
|
2013-08-22 05:59:03 +08:00
|
|
|
return true;
|
2012-03-24 07:07:09 +08:00
|
|
|
}
|
2013-02-23 12:24:36 +08:00
|
|
|
|
|
|
|
virtual int getEHDataRegisterNumber(unsigned RegNo) const {
|
|
|
|
if (RegNo == 0) return 4;
|
|
|
|
if (RegNo == 1) return 5;
|
|
|
|
return -1;
|
|
|
|
}
|
2009-11-15 18:22:07 +08:00
|
|
|
};
|
|
|
|
|
2012-06-29 02:23:16 +08:00
|
|
|
const Builtin::Info MipsTargetInfoBase::BuiltinInfo[] = {
|
|
|
|
#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
|
|
|
|
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
|
|
|
|
ALL_LANGUAGES },
|
|
|
|
#include "clang/Basic/BuiltinsMips.def"
|
|
|
|
};
|
|
|
|
|
2011-09-21 03:00:23 +08:00
|
|
|
class Mips32TargetInfoBase : public MipsTargetInfoBase {
|
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
Mips32TargetInfoBase(const llvm::Triple &Triple)
|
|
|
|
: MipsTargetInfoBase(Triple, "o32", "mips32") {
|
2011-11-05 09:48:34 +08:00
|
|
|
SizeType = UnsignedInt;
|
|
|
|
PtrDiffType = SignedInt;
|
2013-01-19 05:58:11 +08:00
|
|
|
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32;
|
2011-11-05 09:48:34 +08:00
|
|
|
}
|
2011-09-21 03:00:23 +08:00
|
|
|
virtual bool setABI(const std::string &Name) {
|
|
|
|
if ((Name == "o32") || (Name == "eabi")) {
|
|
|
|
ABI = Name;
|
|
|
|
return true;
|
2013-02-27 22:55:49 +08:00
|
|
|
} else if (Name == "32") {
|
|
|
|
ABI = "o32";
|
|
|
|
return true;
|
2011-09-21 03:00:23 +08:00
|
|
|
} else
|
|
|
|
return false;
|
|
|
|
}
|
2012-08-30 03:59:32 +08:00
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
MipsTargetInfoBase::getTargetDefines(Opts, Builder);
|
2012-03-24 07:07:09 +08:00
|
|
|
|
2011-09-21 03:00:23 +08:00
|
|
|
if (ABI == "o32") {
|
|
|
|
Builder.defineMacro("__mips_o32");
|
|
|
|
Builder.defineMacro("_ABIO32", "1");
|
|
|
|
Builder.defineMacro("_MIPS_SIM", "_ABIO32");
|
|
|
|
}
|
|
|
|
else if (ABI == "eabi")
|
|
|
|
Builder.defineMacro("__mips_eabi");
|
|
|
|
else
|
2011-09-23 13:06:16 +08:00
|
|
|
llvm_unreachable("Invalid ABI for Mips32.");
|
2011-09-21 03:00:23 +08:00
|
|
|
}
|
|
|
|
virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
|
|
|
|
unsigned &NumAliases) const {
|
|
|
|
static const TargetInfo::GCCRegAlias 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" },
|
2012-03-28 03:56:11 +08:00
|
|
|
{ { "sp","$sp" }, "$29" },
|
|
|
|
{ { "fp","$fp" }, "$30" },
|
2011-09-21 03:00:23 +08:00
|
|
|
{ { "ra" }, "$31" }
|
|
|
|
};
|
|
|
|
Aliases = GCCRegAliases;
|
|
|
|
NumAliases = llvm::array_lengthof(GCCRegAliases);
|
|
|
|
}
|
2009-11-15 18:22:07 +08:00
|
|
|
};
|
|
|
|
|
2011-09-21 03:00:23 +08:00
|
|
|
class Mips32EBTargetInfo : public Mips32TargetInfoBase {
|
2013-10-30 02:30:33 +08:00
|
|
|
virtual void setDescriptionString() {
|
2014-01-04 03:22:05 +08:00
|
|
|
DescriptionString = "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64";
|
2013-10-30 02:30:33 +08:00
|
|
|
}
|
|
|
|
|
2011-09-21 03:00:23 +08:00
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
Mips32EBTargetInfo(const llvm::Triple &Triple)
|
|
|
|
: Mips32TargetInfoBase(Triple) {
|
2011-09-21 03:00:23 +08:00
|
|
|
}
|
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
DefineStd(Builder, "MIPSEB", Opts);
|
|
|
|
Builder.defineMacro("_MIPSEB");
|
2012-08-30 03:59:32 +08:00
|
|
|
Mips32TargetInfoBase::getTargetDefines(Opts, Builder);
|
2011-09-21 03:00:23 +08:00
|
|
|
}
|
2009-11-15 18:22:07 +08:00
|
|
|
};
|
|
|
|
|
2011-09-21 03:00:23 +08:00
|
|
|
class Mips32ELTargetInfo : public Mips32TargetInfoBase {
|
2013-10-30 02:30:33 +08:00
|
|
|
virtual void setDescriptionString() {
|
2014-01-04 03:22:05 +08:00
|
|
|
DescriptionString = "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64";
|
2013-10-30 02:30:33 +08:00
|
|
|
}
|
|
|
|
|
2009-11-15 18:22:07 +08:00
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
Mips32ELTargetInfo(const llvm::Triple &Triple)
|
|
|
|
: Mips32TargetInfoBase(Triple) {
|
2011-12-22 11:51:45 +08:00
|
|
|
BigEndian = false;
|
2009-11-15 18:22:07 +08:00
|
|
|
}
|
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
2011-09-21 03:00:23 +08:00
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
DefineStd(Builder, "MIPSEL", Opts);
|
|
|
|
Builder.defineMacro("_MIPSEL");
|
2012-08-30 03:59:32 +08:00
|
|
|
Mips32TargetInfoBase::getTargetDefines(Opts, Builder);
|
2011-09-21 03:00:23 +08:00
|
|
|
}
|
2009-11-15 18:22:07 +08:00
|
|
|
};
|
2011-09-21 03:21:49 +08:00
|
|
|
|
|
|
|
class Mips64TargetInfoBase : public MipsTargetInfoBase {
|
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
Mips64TargetInfoBase(const llvm::Triple &Triple)
|
|
|
|
: MipsTargetInfoBase(Triple, "n64", "mips64") {
|
2011-10-22 08:07:27 +08:00
|
|
|
LongWidth = LongAlign = 64;
|
|
|
|
PointerWidth = PointerAlign = 64;
|
|
|
|
LongDoubleWidth = LongDoubleAlign = 128;
|
|
|
|
LongDoubleFormat = &llvm::APFloat::IEEEquad;
|
2012-12-08 17:06:08 +08:00
|
|
|
if (getTriple().getOS() == llvm::Triple::FreeBSD) {
|
|
|
|
LongDoubleWidth = LongDoubleAlign = 64;
|
|
|
|
LongDoubleFormat = &llvm::APFloat::IEEEdouble;
|
|
|
|
}
|
2011-12-17 06:34:14 +08:00
|
|
|
SuitableAlign = 128;
|
2013-01-19 05:58:11 +08:00
|
|
|
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
|
2011-10-22 08:07:27 +08:00
|
|
|
}
|
2011-09-21 03:21:49 +08:00
|
|
|
virtual bool setABI(const std::string &Name) {
|
2011-10-22 08:07:27 +08:00
|
|
|
if (Name == "n32") {
|
|
|
|
LongWidth = LongAlign = 32;
|
|
|
|
PointerWidth = PointerAlign = 32;
|
2013-02-27 22:55:49 +08:00
|
|
|
ABI = Name;
|
|
|
|
return true;
|
|
|
|
} else if (Name == "n64") {
|
|
|
|
ABI = Name;
|
|
|
|
return true;
|
|
|
|
} else if (Name == "64") {
|
|
|
|
ABI = "n64";
|
|
|
|
return true;
|
|
|
|
} else
|
|
|
|
return false;
|
2011-09-21 03:21:49 +08:00
|
|
|
}
|
2012-08-30 03:59:32 +08:00
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
MipsTargetInfoBase::getTargetDefines(Opts, Builder);
|
2012-03-24 07:07:09 +08:00
|
|
|
|
2012-08-30 04:50:11 +08:00
|
|
|
Builder.defineMacro("__mips64");
|
|
|
|
Builder.defineMacro("__mips64__");
|
|
|
|
|
2011-09-21 03:21:49 +08:00
|
|
|
if (ABI == "n32") {
|
|
|
|
Builder.defineMacro("__mips_n32");
|
|
|
|
Builder.defineMacro("_ABIN32", "2");
|
|
|
|
Builder.defineMacro("_MIPS_SIM", "_ABIN32");
|
|
|
|
}
|
|
|
|
else if (ABI == "n64") {
|
|
|
|
Builder.defineMacro("__mips_n64");
|
|
|
|
Builder.defineMacro("_ABI64", "3");
|
|
|
|
Builder.defineMacro("_MIPS_SIM", "_ABI64");
|
|
|
|
}
|
|
|
|
else
|
2011-09-23 13:06:16 +08:00
|
|
|
llvm_unreachable("Invalid ABI for Mips64.");
|
2011-09-21 03:21:49 +08:00
|
|
|
}
|
|
|
|
virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
|
|
|
|
unsigned &NumAliases) const {
|
|
|
|
static const TargetInfo::GCCRegAlias GCCRegAliases[] = {
|
|
|
|
{ { "at" }, "$1" },
|
|
|
|
{ { "v0" }, "$2" },
|
|
|
|
{ { "v1" }, "$3" },
|
|
|
|
{ { "a0" }, "$4" },
|
|
|
|
{ { "a1" }, "$5" },
|
|
|
|
{ { "a2" }, "$6" },
|
|
|
|
{ { "a3" }, "$7" },
|
|
|
|
{ { "a4" }, "$8" },
|
|
|
|
{ { "a5" }, "$9" },
|
|
|
|
{ { "a6" }, "$10" },
|
|
|
|
{ { "a7" }, "$11" },
|
|
|
|
{ { "t0" }, "$12" },
|
|
|
|
{ { "t1" }, "$13" },
|
|
|
|
{ { "t2" }, "$14" },
|
|
|
|
{ { "t3" }, "$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" },
|
2012-03-28 03:56:11 +08:00
|
|
|
{ { "sp","$sp" }, "$29" },
|
|
|
|
{ { "fp","$fp" }, "$30" },
|
2011-09-21 03:21:49 +08:00
|
|
|
{ { "ra" }, "$31" }
|
|
|
|
};
|
|
|
|
Aliases = GCCRegAliases;
|
|
|
|
NumAliases = llvm::array_lengthof(GCCRegAliases);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class Mips64EBTargetInfo : public Mips64TargetInfoBase {
|
2013-10-30 02:30:33 +08:00
|
|
|
virtual void setDescriptionString() {
|
|
|
|
if (ABI == "n32")
|
2014-01-04 03:22:05 +08:00
|
|
|
DescriptionString = "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32:64-S128";
|
2013-10-30 02:30:33 +08:00
|
|
|
else
|
2014-01-04 03:22:05 +08:00
|
|
|
DescriptionString = "E-m:m-i8:8:32-i16:16:32-i64:64-n32:64-S128";
|
2013-10-30 02:30:33 +08:00
|
|
|
|
2011-09-21 03:21:49 +08:00
|
|
|
}
|
2013-10-30 02:30:33 +08:00
|
|
|
|
2011-09-21 03:21:49 +08:00
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
Mips64EBTargetInfo(const llvm::Triple &Triple)
|
2013-10-30 02:30:33 +08:00
|
|
|
: Mips64TargetInfoBase(Triple) {}
|
2011-09-21 03:21:49 +08:00
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
DefineStd(Builder, "MIPSEB", Opts);
|
|
|
|
Builder.defineMacro("_MIPSEB");
|
2012-08-30 03:59:32 +08:00
|
|
|
Mips64TargetInfoBase::getTargetDefines(Opts, Builder);
|
2011-09-21 03:21:49 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class Mips64ELTargetInfo : public Mips64TargetInfoBase {
|
2013-10-30 02:30:33 +08:00
|
|
|
virtual void setDescriptionString() {
|
|
|
|
if (ABI == "n32")
|
2014-01-04 03:22:05 +08:00
|
|
|
DescriptionString = "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32:64-S128";
|
2013-10-30 02:30:33 +08:00
|
|
|
else
|
2014-01-04 03:22:05 +08:00
|
|
|
DescriptionString = "e-m:m-i8:8:32-i16:16:32-i64:64-n32:64-S128";
|
2011-09-21 03:21:49 +08:00
|
|
|
}
|
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
Mips64ELTargetInfo(const llvm::Triple &Triple)
|
|
|
|
: Mips64TargetInfoBase(Triple) {
|
2011-12-22 11:51:45 +08:00
|
|
|
// Default ABI is n64.
|
|
|
|
BigEndian = false;
|
2011-09-21 03:21:49 +08:00
|
|
|
}
|
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
DefineStd(Builder, "MIPSEL", Opts);
|
|
|
|
Builder.defineMacro("_MIPSEL");
|
2012-08-30 03:59:32 +08:00
|
|
|
Mips64TargetInfoBase::getTargetDefines(Opts, Builder);
|
2011-09-21 03:21:49 +08:00
|
|
|
}
|
|
|
|
};
|
2009-11-15 18:22:07 +08:00
|
|
|
} // end anonymous namespace.
|
|
|
|
|
2011-08-25 04:22:22 +08:00
|
|
|
namespace {
|
|
|
|
class PNaClTargetInfo : public TargetInfo {
|
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
PNaClTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
|
2011-12-22 11:51:45 +08:00
|
|
|
BigEndian = false;
|
2011-08-25 04:22:22 +08:00
|
|
|
this->UserLabelPrefix = "";
|
|
|
|
this->LongAlign = 32;
|
|
|
|
this->LongWidth = 32;
|
|
|
|
this->PointerAlign = 32;
|
|
|
|
this->PointerWidth = 32;
|
|
|
|
this->IntMaxType = TargetInfo::SignedLongLong;
|
|
|
|
this->UIntMaxType = TargetInfo::UnsignedLongLong;
|
|
|
|
this->Int64Type = TargetInfo::SignedLongLong;
|
2011-08-30 06:39:12 +08:00
|
|
|
this->DoubleAlign = 64;
|
2011-09-20 22:56:54 +08:00
|
|
|
this->LongDoubleWidth = 64;
|
2011-08-30 06:39:12 +08:00
|
|
|
this->LongDoubleAlign = 64;
|
2011-09-20 22:56:54 +08:00
|
|
|
this->SizeType = TargetInfo::UnsignedInt;
|
|
|
|
this->PtrDiffType = TargetInfo::SignedInt;
|
|
|
|
this->IntPtrType = TargetInfo::SignedInt;
|
2013-04-09 05:31:01 +08:00
|
|
|
this->RegParmMax = 0; // Disallow regparm
|
2011-08-25 04:22:22 +08:00
|
|
|
}
|
|
|
|
|
2011-09-28 13:56:05 +08:00
|
|
|
void getDefaultFeatures(llvm::StringMap<bool> &Features) const {
|
2011-08-25 04:22:22 +08:00
|
|
|
}
|
|
|
|
virtual void getArchDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
Builder.defineMacro("__le32__");
|
|
|
|
Builder.defineMacro("__pnacl__");
|
|
|
|
}
|
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const {
|
2012-03-29 08:05:59 +08:00
|
|
|
Builder.defineMacro("__LITTLE_ENDIAN__");
|
2011-08-25 04:22:22 +08:00
|
|
|
getArchDefines(Opts, Builder);
|
|
|
|
}
|
2012-01-30 14:38:25 +08:00
|
|
|
virtual bool hasFeature(StringRef Feature) const {
|
|
|
|
return Feature == "pnacl";
|
|
|
|
}
|
2011-08-25 04:22:22 +08:00
|
|
|
virtual void getTargetBuiltins(const Builtin::Info *&Records,
|
|
|
|
unsigned &NumRecords) const {
|
|
|
|
}
|
2012-06-16 11:34:49 +08:00
|
|
|
virtual BuiltinVaListKind getBuiltinVaListKind() const {
|
|
|
|
return TargetInfo::PNaClABIBuiltinVaList;
|
2011-08-25 04:22:22 +08:00
|
|
|
}
|
|
|
|
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 {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual const char *getClobbers() const {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
void PNaClTargetInfo::getGCCRegNames(const char * const *&Names,
|
|
|
|
unsigned &NumNames) const {
|
|
|
|
Names = NULL;
|
|
|
|
NumNames = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PNaClTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
|
|
|
|
unsigned &NumAliases) const {
|
|
|
|
Aliases = NULL;
|
|
|
|
NumAliases = 0;
|
|
|
|
}
|
|
|
|
} // end anonymous namespace.
|
|
|
|
|
2012-12-12 05:38:14 +08:00
|
|
|
namespace {
|
|
|
|
static const unsigned SPIRAddrSpaceMap[] = {
|
|
|
|
1, // opencl_global
|
|
|
|
3, // opencl_local
|
|
|
|
2, // opencl_constant
|
|
|
|
0, // cuda_device
|
|
|
|
0, // cuda_constant
|
|
|
|
0 // cuda_shared
|
|
|
|
};
|
|
|
|
class SPIRTargetInfo : public TargetInfo {
|
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
SPIRTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
|
2012-12-12 05:38:14 +08:00
|
|
|
assert(getTriple().getOS() == llvm::Triple::UnknownOS &&
|
|
|
|
"SPIR target must use unknown OS");
|
|
|
|
assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
|
|
|
|
"SPIR target must use unknown environment type");
|
|
|
|
BigEndian = false;
|
|
|
|
TLSSupported = false;
|
|
|
|
LongWidth = LongAlign = 64;
|
|
|
|
AddrSpaceMap = &SPIRAddrSpaceMap;
|
2013-09-13 20:04:22 +08:00
|
|
|
UseAddrSpaceMapMangling = true;
|
2012-12-12 05:38:14 +08:00
|
|
|
// Define available target features
|
|
|
|
// These must be defined in sorted order!
|
|
|
|
NoAsmVariants = true;
|
|
|
|
}
|
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
DefineStd(Builder, "SPIR", Opts);
|
|
|
|
}
|
|
|
|
virtual bool hasFeature(StringRef Feature) const {
|
|
|
|
return Feature == "spir";
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void getTargetBuiltins(const Builtin::Info *&Records,
|
|
|
|
unsigned &NumRecords) const {}
|
|
|
|
virtual const char *getClobbers() const {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
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 {}
|
|
|
|
virtual BuiltinVaListKind getBuiltinVaListKind() const {
|
|
|
|
return TargetInfo::VoidPtrBuiltinVaList;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class SPIR32TargetInfo : public SPIRTargetInfo {
|
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
SPIR32TargetInfo(const llvm::Triple &Triple) : SPIRTargetInfo(Triple) {
|
2012-12-12 05:38:14 +08:00
|
|
|
PointerWidth = PointerAlign = 32;
|
|
|
|
SizeType = TargetInfo::UnsignedInt;
|
|
|
|
PtrDiffType = IntPtrType = TargetInfo::SignedInt;
|
|
|
|
DescriptionString
|
2014-01-04 02:13:17 +08:00
|
|
|
= "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-"
|
|
|
|
"v96:128-v192:256-v256:256-v512:512-v1024:1024";
|
2013-03-07 21:06:10 +08:00
|
|
|
}
|
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
DefineStd(Builder, "SPIR32", Opts);
|
|
|
|
}
|
2012-12-12 05:38:14 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
class SPIR64TargetInfo : public SPIRTargetInfo {
|
|
|
|
public:
|
2013-06-30 00:37:14 +08:00
|
|
|
SPIR64TargetInfo(const llvm::Triple &Triple) : SPIRTargetInfo(Triple) {
|
2012-12-12 05:38:14 +08:00
|
|
|
PointerWidth = PointerAlign = 64;
|
|
|
|
SizeType = TargetInfo::UnsignedLong;
|
|
|
|
PtrDiffType = IntPtrType = TargetInfo::SignedLong;
|
2014-01-04 02:13:17 +08:00
|
|
|
DescriptionString = "e-i64:64-v16:16-v24:32-v32:32-v48:64-"
|
|
|
|
"v96:128-v192:256-v256:256-v512:512-v1024:1024";
|
2013-03-07 21:06:10 +08:00
|
|
|
}
|
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
DefineStd(Builder, "SPIR64", Opts);
|
|
|
|
}
|
2012-12-12 05:38:14 +08:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2013-08-13 17:43:10 +08:00
|
|
|
namespace {
|
|
|
|
class XCoreTargetInfo : public TargetInfo {
|
|
|
|
static const Builtin::Info BuiltinInfo[];
|
|
|
|
public:
|
|
|
|
XCoreTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
|
|
|
|
BigEndian = false;
|
|
|
|
NoAsmVariants = true;
|
|
|
|
LongLongAlign = 32;
|
|
|
|
SuitableAlign = 32;
|
|
|
|
DoubleAlign = LongDoubleAlign = 32;
|
2013-11-12 18:09:30 +08:00
|
|
|
SizeType = UnsignedInt;
|
|
|
|
PtrDiffType = SignedInt;
|
|
|
|
IntPtrType = SignedInt;
|
|
|
|
WCharType = UnsignedChar;
|
|
|
|
WIntType = UnsignedInt;
|
2013-08-13 17:43:10 +08:00
|
|
|
UseZeroLengthBitfieldAlignment = true;
|
2014-01-04 03:22:05 +08:00
|
|
|
DescriptionString = "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:32"
|
2013-12-17 22:34:42 +08:00
|
|
|
"-f64:32-a:0:32-n32";
|
2013-08-13 17:43:10 +08:00
|
|
|
}
|
|
|
|
virtual void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
Builder.defineMacro("__XS1B__");
|
|
|
|
}
|
|
|
|
virtual void getTargetBuiltins(const Builtin::Info *&Records,
|
|
|
|
unsigned &NumRecords) const {
|
|
|
|
Records = BuiltinInfo;
|
|
|
|
NumRecords = clang::XCore::LastTSBuiltin-Builtin::FirstTSBuiltin;
|
|
|
|
}
|
|
|
|
virtual BuiltinVaListKind getBuiltinVaListKind() const {
|
|
|
|
return TargetInfo::VoidPtrBuiltinVaList;
|
|
|
|
}
|
|
|
|
virtual const char *getClobbers() const {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
virtual void getGCCRegNames(const char * const *&Names,
|
|
|
|
unsigned &NumNames) const {
|
|
|
|
static const char * const GCCRegNames[] = {
|
|
|
|
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
|
|
|
"r8", "r9", "r10", "r11", "cp", "dp", "sp", "lr"
|
|
|
|
};
|
|
|
|
Names = GCCRegNames;
|
|
|
|
NumNames = llvm::array_lengthof(GCCRegNames);
|
|
|
|
}
|
|
|
|
virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
|
|
|
|
unsigned &NumAliases) const {
|
|
|
|
Aliases = NULL;
|
|
|
|
NumAliases = 0;
|
|
|
|
}
|
|
|
|
virtual bool validateAsmConstraint(const char *&Name,
|
|
|
|
TargetInfo::ConstraintInfo &Info) const {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const Builtin::Info XCoreTargetInfo::BuiltinInfo[] = {
|
|
|
|
#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
|
|
|
|
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
|
|
|
|
ALL_LANGUAGES },
|
|
|
|
#include "clang/Basic/BuiltinsXCore.def"
|
|
|
|
};
|
|
|
|
} // end anonymous namespace.
|
|
|
|
|
2011-08-25 04:22:22 +08:00
|
|
|
|
2006-10-14 15:39:34 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Driver code
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2013-06-30 00:37:14 +08:00
|
|
|
static TargetInfo *AllocateTarget(const llvm::Triple &Triple) {
|
2009-08-18 13:47:58 +08:00
|
|
|
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
|
|
|
|
2013-08-13 17:43:10 +08:00
|
|
|
case llvm::Triple::xcore:
|
|
|
|
return new XCoreTargetInfo(Triple);
|
|
|
|
|
2011-12-13 05:14:55 +08:00
|
|
|
case llvm::Triple::hexagon:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new HexagonTargetInfo(Triple);
|
2011-12-13 05:14:55 +08:00
|
|
|
|
2013-01-31 20:13:10 +08:00
|
|
|
case llvm::Triple::aarch64:
|
|
|
|
switch (os) {
|
|
|
|
case llvm::Triple::Linux:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new LinuxTargetInfo<AArch64TargetInfo>(Triple);
|
2014-01-14 02:25:15 +08:00
|
|
|
case llvm::Triple::NetBSD:
|
|
|
|
return new NetBSDTargetInfo<AArch64TargetInfo>(Triple);
|
2013-01-31 20:13:10 +08:00
|
|
|
default:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new AArch64TargetInfo(Triple);
|
2013-01-31 20:13:10 +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:
|
2011-04-20 05:43:27 +08:00
|
|
|
if (Triple.isOSDarwin())
|
2013-06-30 00:37:14 +08:00
|
|
|
return new DarwinARMTargetInfo(Triple);
|
2011-04-20 05:43:27 +08:00
|
|
|
|
2009-08-18 13:47:58 +08:00
|
|
|
switch (os) {
|
2010-06-10 08:46:51 +08:00
|
|
|
case llvm::Triple::Linux:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new LinuxTargetInfo<ARMTargetInfo>(Triple);
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::FreeBSD:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new FreeBSDTargetInfo<ARMTargetInfo>(Triple);
|
2011-07-05 05:59:44 +08:00
|
|
|
case llvm::Triple::NetBSD:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new NetBSDTargetInfo<ARMTargetInfo>(Triple);
|
2012-08-02 21:45:48 +08:00
|
|
|
case llvm::Triple::OpenBSD:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new OpenBSDTargetInfo<ARMTargetInfo>(Triple);
|
2012-08-09 07:57:20 +08:00
|
|
|
case llvm::Triple::Bitrig:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new BitrigTargetInfo<ARMTargetInfo>(Triple);
|
2011-07-02 06:41:14 +08:00
|
|
|
case llvm::Triple::RTEMS:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new RTEMSTargetInfo<ARMTargetInfo>(Triple);
|
2012-12-05 02:38:10 +08:00
|
|
|
case llvm::Triple::NaCl:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new NaClTargetInfo<ARMTargetInfo>(Triple);
|
2009-08-18 13:47:58 +08:00
|
|
|
default:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new ARMTargetInfo(Triple);
|
2009-08-18 13:47:58 +08:00
|
|
|
}
|
2008-04-22 02:56:49 +08:00
|
|
|
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::msp430:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new MSP430TargetInfo(Triple);
|
2008-05-20 22:21:01 +08:00
|
|
|
|
2009-11-15 18:22:07 +08:00
|
|
|
case llvm::Triple::mips:
|
2011-07-06 02:05:54 +08:00
|
|
|
switch (os) {
|
|
|
|
case llvm::Triple::Linux:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new LinuxTargetInfo<Mips32EBTargetInfo>(Triple);
|
2011-07-06 02:05:54 +08:00
|
|
|
case llvm::Triple::RTEMS:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new RTEMSTargetInfo<Mips32EBTargetInfo>(Triple);
|
2011-07-06 02:05:54 +08:00
|
|
|
case llvm::Triple::FreeBSD:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new FreeBSDTargetInfo<Mips32EBTargetInfo>(Triple);
|
2011-07-06 02:05:54 +08:00
|
|
|
case llvm::Triple::NetBSD:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new NetBSDTargetInfo<Mips32EBTargetInfo>(Triple);
|
2011-07-06 02:05:54 +08:00
|
|
|
default:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new Mips32EBTargetInfo(Triple);
|
2011-07-06 02:05:54 +08:00
|
|
|
}
|
2009-11-15 18:22:07 +08:00
|
|
|
|
|
|
|
case llvm::Triple::mipsel:
|
2011-07-06 02:24:04 +08:00
|
|
|
switch (os) {
|
|
|
|
case llvm::Triple::Linux:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new LinuxTargetInfo<Mips32ELTargetInfo>(Triple);
|
2011-07-06 02:24:04 +08:00
|
|
|
case llvm::Triple::RTEMS:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new RTEMSTargetInfo<Mips32ELTargetInfo>(Triple);
|
2011-07-06 02:24:04 +08:00
|
|
|
case llvm::Triple::FreeBSD:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new FreeBSDTargetInfo<Mips32ELTargetInfo>(Triple);
|
2011-07-06 02:24:04 +08:00
|
|
|
case llvm::Triple::NetBSD:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new NetBSDTargetInfo<Mips32ELTargetInfo>(Triple);
|
2013-09-21 09:27:01 +08:00
|
|
|
case llvm::Triple::NaCl:
|
|
|
|
return new NaClTargetInfo<Mips32ELTargetInfo>(Triple);
|
2011-07-06 02:24:04 +08:00
|
|
|
default:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new Mips32ELTargetInfo(Triple);
|
2011-07-06 02:24:04 +08:00
|
|
|
}
|
2009-11-15 18:22:07 +08:00
|
|
|
|
2011-09-21 03:21:49 +08:00
|
|
|
case llvm::Triple::mips64:
|
|
|
|
switch (os) {
|
|
|
|
case llvm::Triple::Linux:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new LinuxTargetInfo<Mips64EBTargetInfo>(Triple);
|
2011-09-21 03:21:49 +08:00
|
|
|
case llvm::Triple::RTEMS:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new RTEMSTargetInfo<Mips64EBTargetInfo>(Triple);
|
2011-09-21 03:21:49 +08:00
|
|
|
case llvm::Triple::FreeBSD:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new FreeBSDTargetInfo<Mips64EBTargetInfo>(Triple);
|
2011-09-21 03:21:49 +08:00
|
|
|
case llvm::Triple::NetBSD:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new NetBSDTargetInfo<Mips64EBTargetInfo>(Triple);
|
2012-08-02 21:45:48 +08:00
|
|
|
case llvm::Triple::OpenBSD:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new OpenBSDTargetInfo<Mips64EBTargetInfo>(Triple);
|
2011-09-21 03:21:49 +08:00
|
|
|
default:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new Mips64EBTargetInfo(Triple);
|
2011-09-21 03:21:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
case llvm::Triple::mips64el:
|
|
|
|
switch (os) {
|
|
|
|
case llvm::Triple::Linux:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new LinuxTargetInfo<Mips64ELTargetInfo>(Triple);
|
2011-09-21 03:21:49 +08:00
|
|
|
case llvm::Triple::RTEMS:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new RTEMSTargetInfo<Mips64ELTargetInfo>(Triple);
|
2011-09-21 03:21:49 +08:00
|
|
|
case llvm::Triple::FreeBSD:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new FreeBSDTargetInfo<Mips64ELTargetInfo>(Triple);
|
2011-09-21 03:21:49 +08:00
|
|
|
case llvm::Triple::NetBSD:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new NetBSDTargetInfo<Mips64ELTargetInfo>(Triple);
|
2012-08-02 21:45:48 +08:00
|
|
|
case llvm::Triple::OpenBSD:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new OpenBSDTargetInfo<Mips64ELTargetInfo>(Triple);
|
2011-09-21 03:21:49 +08:00
|
|
|
default:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new Mips64ELTargetInfo(Triple);
|
2011-09-21 03:21:49 +08:00
|
|
|
}
|
|
|
|
|
2011-08-25 04:22:22 +08:00
|
|
|
case llvm::Triple::le32:
|
|
|
|
switch (os) {
|
2012-12-05 02:38:10 +08:00
|
|
|
case llvm::Triple::NaCl:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new NaClTargetInfo<PNaClTargetInfo>(Triple);
|
2011-08-25 04:22:22 +08:00
|
|
|
default:
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::ppc:
|
2011-04-20 05:43:27 +08:00
|
|
|
if (Triple.isOSDarwin())
|
2013-06-30 00:37:14 +08:00
|
|
|
return new DarwinPPC32TargetInfo(Triple);
|
2011-07-05 05:59:44 +08:00
|
|
|
switch (os) {
|
2011-10-12 17:30:58 +08:00
|
|
|
case llvm::Triple::Linux:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new LinuxTargetInfo<PPC32TargetInfo>(Triple);
|
2011-07-05 05:59:44 +08:00
|
|
|
case llvm::Triple::FreeBSD:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new FreeBSDTargetInfo<PPC32TargetInfo>(Triple);
|
2011-07-05 05:59:44 +08:00
|
|
|
case llvm::Triple::NetBSD:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new NetBSDTargetInfo<PPC32TargetInfo>(Triple);
|
2012-08-02 21:45:48 +08:00
|
|
|
case llvm::Triple::OpenBSD:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new OpenBSDTargetInfo<PPC32TargetInfo>(Triple);
|
2011-07-05 05:59:44 +08:00
|
|
|
case llvm::Triple::RTEMS:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new RTEMSTargetInfo<PPC32TargetInfo>(Triple);
|
2011-07-05 05:59:44 +08:00
|
|
|
default:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new PPC32TargetInfo(Triple);
|
2011-07-05 05:59:44 +08:00
|
|
|
}
|
2009-05-03 21:43:08 +08:00
|
|
|
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::ppc64:
|
2011-04-20 05:43:27 +08:00
|
|
|
if (Triple.isOSDarwin())
|
2013-06-30 00:37:14 +08:00
|
|
|
return new DarwinPPC64TargetInfo(Triple);
|
2011-07-05 05:59:44 +08:00
|
|
|
switch (os) {
|
2011-10-12 17:30:58 +08:00
|
|
|
case llvm::Triple::Linux:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new LinuxTargetInfo<PPC64TargetInfo>(Triple);
|
2011-07-05 05:59:44 +08:00
|
|
|
case llvm::Triple::Lv2:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new PS3PPUTargetInfo<PPC64TargetInfo>(Triple);
|
2011-07-05 05:59:44 +08:00
|
|
|
case llvm::Triple::FreeBSD:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new FreeBSDTargetInfo<PPC64TargetInfo>(Triple);
|
2011-07-05 05:59:44 +08:00
|
|
|
case llvm::Triple::NetBSD:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new NetBSDTargetInfo<PPC64TargetInfo>(Triple);
|
2011-07-05 05:59:44 +08:00
|
|
|
default:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new PPC64TargetInfo(Triple);
|
2011-07-05 05:59:44 +08:00
|
|
|
}
|
2009-07-17 04:09:57 +08:00
|
|
|
|
2013-07-26 09:36:11 +08:00
|
|
|
case llvm::Triple::ppc64le:
|
|
|
|
switch (os) {
|
|
|
|
case llvm::Triple::Linux:
|
|
|
|
return new LinuxTargetInfo<PPC64TargetInfo>(Triple);
|
|
|
|
default:
|
|
|
|
return new PPC64TargetInfo(Triple);
|
|
|
|
}
|
|
|
|
|
2012-05-21 07:28:41 +08:00
|
|
|
case llvm::Triple::nvptx:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new NVPTX32TargetInfo(Triple);
|
2012-05-21 07:28:41 +08:00
|
|
|
case llvm::Triple::nvptx64:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new NVPTX64TargetInfo(Triple);
|
2012-05-21 07:28:41 +08:00
|
|
|
|
2012-10-13 07:32:00 +08:00
|
|
|
case llvm::Triple::r600:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new R600TargetInfo(Triple);
|
2012-10-13 07:32:00 +08:00
|
|
|
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::sparc:
|
2011-07-05 05:59:44 +08:00
|
|
|
switch (os) {
|
2011-10-12 17:30:58 +08:00
|
|
|
case llvm::Triple::Linux:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new LinuxTargetInfo<SparcV8TargetInfo>(Triple);
|
2011-07-05 05:59:44 +08:00
|
|
|
case llvm::Triple::AuroraUX:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new AuroraUXSparcV8TargetInfo(Triple);
|
2011-07-05 05:59:44 +08:00
|
|
|
case llvm::Triple::Solaris:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new SolarisSparcV8TargetInfo(Triple);
|
2011-07-05 05:59:44 +08:00
|
|
|
case llvm::Triple::NetBSD:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new NetBSDTargetInfo<SparcV8TargetInfo>(Triple);
|
2012-08-02 21:45:48 +08:00
|
|
|
case llvm::Triple::OpenBSD:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new OpenBSDTargetInfo<SparcV8TargetInfo>(Triple);
|
2011-07-05 05:59:44 +08:00
|
|
|
case llvm::Triple::RTEMS:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new RTEMSTargetInfo<SparcV8TargetInfo>(Triple);
|
2011-07-05 05:59:44 +08:00
|
|
|
default:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new SparcV8TargetInfo(Triple);
|
2011-07-05 05:59:44 +08:00
|
|
|
}
|
2009-08-18 04:08:44 +08:00
|
|
|
|
2013-04-16 23:17:49 +08:00
|
|
|
case llvm::Triple::sparcv9:
|
|
|
|
switch (os) {
|
|
|
|
case llvm::Triple::Linux:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new LinuxTargetInfo<SparcV9TargetInfo>(Triple);
|
2013-04-16 23:17:49 +08:00
|
|
|
case llvm::Triple::AuroraUX:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new AuroraUXTargetInfo<SparcV9TargetInfo>(Triple);
|
2013-04-16 23:17:49 +08:00
|
|
|
case llvm::Triple::Solaris:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new SolarisTargetInfo<SparcV9TargetInfo>(Triple);
|
2013-04-16 23:17:49 +08:00
|
|
|
case llvm::Triple::NetBSD:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new NetBSDTargetInfo<SparcV9TargetInfo>(Triple);
|
2013-04-16 23:17:49 +08:00
|
|
|
case llvm::Triple::OpenBSD:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new OpenBSDTargetInfo<SparcV9TargetInfo>(Triple);
|
2013-04-16 23:17:49 +08:00
|
|
|
case llvm::Triple::FreeBSD:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new FreeBSDTargetInfo<SparcV9TargetInfo>(Triple);
|
2013-04-16 23:17:49 +08:00
|
|
|
default:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new SparcV9TargetInfo(Triple);
|
2013-04-16 23:17:49 +08:00
|
|
|
}
|
|
|
|
|
2013-05-07 00:26:41 +08:00
|
|
|
case llvm::Triple::systemz:
|
|
|
|
switch (os) {
|
|
|
|
case llvm::Triple::Linux:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new LinuxTargetInfo<SystemZTargetInfo>(Triple);
|
2013-05-07 00:26:41 +08:00
|
|
|
default:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new SystemZTargetInfo(Triple);
|
2013-05-07 00:26:41 +08:00
|
|
|
}
|
|
|
|
|
2009-08-20 04:47:07 +08:00
|
|
|
case llvm::Triple::tce:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new TCETargetInfo(Triple);
|
2009-08-20 04:47:07 +08:00
|
|
|
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::x86:
|
2011-04-20 05:43:27 +08:00
|
|
|
if (Triple.isOSDarwin())
|
2013-06-30 00:37:14 +08:00
|
|
|
return new DarwinI386TargetInfo(Triple);
|
2011-04-20 05:43:27 +08:00
|
|
|
|
2009-08-18 13:47:58 +08:00
|
|
|
switch (os) {
|
2009-10-18 21:33:59 +08:00
|
|
|
case llvm::Triple::AuroraUX:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new AuroraUXTargetInfo<X86_32TargetInfo>(Triple);
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::Linux:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new LinuxTargetInfo<X86_32TargetInfo>(Triple);
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::DragonFly:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(Triple);
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::NetBSD:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new NetBSDI386TargetInfo(Triple);
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::OpenBSD:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new OpenBSDI386TargetInfo(Triple);
|
2012-08-09 07:57:20 +08:00
|
|
|
case llvm::Triple::Bitrig:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new BitrigI386TargetInfo(Triple);
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::FreeBSD:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new FreeBSDTargetInfo<X86_32TargetInfo>(Triple);
|
2013-09-05 21:47:07 +08:00
|
|
|
case llvm::Triple::KFreeBSD:
|
|
|
|
return new KFreeBSDTargetInfo<X86_32TargetInfo>(Triple);
|
2010-07-08 00:01:42 +08:00
|
|
|
case llvm::Triple::Minix:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new MinixTargetInfo<X86_32TargetInfo>(Triple);
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::Solaris:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new SolarisTargetInfo<X86_32TargetInfo>(Triple);
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::Cygwin:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new CygwinX86_32TargetInfo(Triple);
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::MinGW32:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new MinGWX86_32TargetInfo(Triple);
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::Win32:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new VisualStudioWindowsX86_32TargetInfo(Triple);
|
2010-04-12 03:29:39 +08:00
|
|
|
case llvm::Triple::Haiku:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new HaikuX86_32TargetInfo(Triple);
|
2011-07-02 06:41:14 +08:00
|
|
|
case llvm::Triple::RTEMS:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new RTEMSX86_32TargetInfo(Triple);
|
2012-12-05 02:38:10 +08:00
|
|
|
case llvm::Triple::NaCl:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new NaClTargetInfo<X86_32TargetInfo>(Triple);
|
2009-08-18 13:47:58 +08:00
|
|
|
default:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new X86_32TargetInfo(Triple);
|
2009-08-18 13:47:58 +08:00
|
|
|
}
|
2008-05-20 22:21:01 +08:00
|
|
|
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::x86_64:
|
2011-04-20 05:43:27 +08:00
|
|
|
if (Triple.isOSDarwin() || Triple.getEnvironment() == llvm::Triple::MachO)
|
2013-06-30 00:37:14 +08:00
|
|
|
return new DarwinX86_64TargetInfo(Triple);
|
2011-04-20 05:43:27 +08:00
|
|
|
|
2009-08-18 13:47:58 +08:00
|
|
|
switch (os) {
|
2009-10-18 21:33:59 +08:00
|
|
|
case llvm::Triple::AuroraUX:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new AuroraUXTargetInfo<X86_64TargetInfo>(Triple);
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::Linux:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new LinuxTargetInfo<X86_64TargetInfo>(Triple);
|
2010-01-09 13:41:14 +08:00
|
|
|
case llvm::Triple::DragonFly:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new DragonFlyBSDTargetInfo<X86_64TargetInfo>(Triple);
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::NetBSD:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new NetBSDTargetInfo<X86_64TargetInfo>(Triple);
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::OpenBSD:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new OpenBSDX86_64TargetInfo(Triple);
|
2012-08-09 07:57:20 +08:00
|
|
|
case llvm::Triple::Bitrig:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new BitrigX86_64TargetInfo(Triple);
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::FreeBSD:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new FreeBSDTargetInfo<X86_64TargetInfo>(Triple);
|
2013-09-05 21:47:07 +08:00
|
|
|
case llvm::Triple::KFreeBSD:
|
|
|
|
return new KFreeBSDTargetInfo<X86_64TargetInfo>(Triple);
|
2009-08-18 13:47:58 +08:00
|
|
|
case llvm::Triple::Solaris:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new SolarisTargetInfo<X86_64TargetInfo>(Triple);
|
2011-02-17 16:51:38 +08:00
|
|
|
case llvm::Triple::MinGW32:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new MinGWX86_64TargetInfo(Triple);
|
2009-09-23 15:31:35 +08:00
|
|
|
case llvm::Triple::Win32: // This is what Triple.h supports now.
|
2013-06-30 00:37:14 +08:00
|
|
|
return new VisualStudioWindowsX86_64TargetInfo(Triple);
|
2012-12-05 02:38:10 +08:00
|
|
|
case llvm::Triple::NaCl:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new NaClTargetInfo<X86_64TargetInfo>(Triple);
|
2009-08-18 13:47:58 +08:00
|
|
|
default:
|
2013-06-30 00:37:14 +08:00
|
|
|
return new X86_64TargetInfo(Triple);
|
2009-08-18 13:47:58 +08:00
|
|
|
}
|
2012-12-12 05:38:14 +08:00
|
|
|
|
|
|
|
case llvm::Triple::spir: {
|
|
|
|
if (Triple.getOS() != llvm::Triple::UnknownOS ||
|
2013-06-30 00:37:14 +08:00
|
|
|
Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
|
2012-12-12 05:38:14 +08:00
|
|
|
return NULL;
|
2013-06-30 00:37:14 +08:00
|
|
|
return new SPIR32TargetInfo(Triple);
|
2012-12-12 05:38:14 +08:00
|
|
|
}
|
|
|
|
case llvm::Triple::spir64: {
|
|
|
|
if (Triple.getOS() != llvm::Triple::UnknownOS ||
|
2013-06-30 00:37:14 +08:00
|
|
|
Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
|
2012-12-12 05:38:14 +08:00
|
|
|
return NULL;
|
2013-06-30 00:37:14 +08:00
|
|
|
return new SPIR64TargetInfo(Triple);
|
2012-12-12 05:38:14 +08:00
|
|
|
}
|
2009-08-18 13:47:58 +08:00
|
|
|
}
|
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.
|
2011-09-26 07:23:43 +08:00
|
|
|
TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags,
|
2012-11-16 12:24:59 +08:00
|
|
|
TargetOptions *Opts) {
|
|
|
|
llvm::Triple Triple(Opts->Triple);
|
2009-11-15 14:48:46 +08:00
|
|
|
|
|
|
|
// Construct the target
|
2013-06-30 00:37:14 +08:00
|
|
|
OwningPtr<TargetInfo> Target(AllocateTarget(Triple));
|
2009-11-15 14:48:46 +08:00
|
|
|
if (!Target) {
|
|
|
|
Diags.Report(diag::err_target_unknown_triple) << Triple.str();
|
|
|
|
return 0;
|
|
|
|
}
|
2012-10-16 00:45:32 +08:00
|
|
|
Target->setTargetOpts(Opts);
|
2009-11-15 14:48:46 +08:00
|
|
|
|
2009-12-19 02:42:37 +08:00
|
|
|
// Set the target CPU if specified.
|
2012-11-16 12:24:59 +08:00
|
|
|
if (!Opts->CPU.empty() && !Target->setCPU(Opts->CPU)) {
|
|
|
|
Diags.Report(diag::err_target_unknown_cpu) << Opts->CPU;
|
2009-12-19 02:42:37 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-11-15 14:48:46 +08:00
|
|
|
// Set the target ABI if specified.
|
2012-11-16 12:24:59 +08:00
|
|
|
if (!Opts->ABI.empty() && !Target->setABI(Opts->ABI)) {
|
|
|
|
Diags.Report(diag::err_target_unknown_abi) << Opts->ABI;
|
2009-11-15 14:48:46 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-08-22 05:59:03 +08:00
|
|
|
// Set the fp math unit.
|
|
|
|
if (!Opts->FPMath.empty() && !Target->setFPMath(Opts->FPMath)) {
|
|
|
|
Diags.Report(diag::err_target_unknown_fpmath) << Opts->FPMath;
|
|
|
|
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;
|
2011-09-28 13:56:05 +08:00
|
|
|
Target->getDefaultFeatures(Features);
|
2009-11-15 14:48:46 +08:00
|
|
|
|
2013-08-21 02:57:55 +08:00
|
|
|
// Apply the user specified deltas.
|
|
|
|
for (unsigned I = 0, N = Opts->FeaturesAsWritten.size();
|
|
|
|
I < N; ++I) {
|
|
|
|
const char *Name = Opts->FeaturesAsWritten[I].c_str();
|
2009-11-15 14:48:46 +08:00
|
|
|
// Apply the feature via the target.
|
2013-08-21 02:57:55 +08:00
|
|
|
bool Enabled = Name[0] == '+';
|
|
|
|
Target->setFeatureEnabled(Features, Name + 1, Enabled);
|
2009-11-15 14:48:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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.
|
2012-11-16 12:24:59 +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)
|
2012-11-16 12:24:59 +08:00
|
|
|
Opts->Features.push_back((it->second ? "+" : "-") + it->first().str());
|
2013-10-17 05:26:26 +08:00
|
|
|
if (!Target->handleTargetFeatures(Opts->Features, Diags))
|
2013-08-22 05:59:03 +08:00
|
|
|
return 0;
|
2009-11-15 14:48:46 +08:00
|
|
|
|
|
|
|
return Target.take();
|
|
|
|
}
|