2015-08-26 04:23:11 +00:00
|
|
|
//===--- Targets.cpp - Implement target feature support -------------------===//
|
2006-10-14 07:39:34 +00:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-29 19:59:25 +00:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2006-10-14 07:39:34 +00:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2009-05-03 13:42:53 +00:00
|
|
|
// This file implements construction of a TargetInfo object from a
|
2007-12-12 18:05:32 +00:00
|
|
|
// target triple.
|
2006-10-14 07:39:34 +00:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "clang/Basic/TargetInfo.h"
|
2009-11-15 06:48:46 +00:00
|
|
|
#include "clang/Basic/Builtins.h"
|
|
|
|
#include "clang/Basic/Diagnostic.h"
|
2008-12-04 22:54:33 +00:00
|
|
|
#include "clang/Basic/LangOptions.h"
|
2010-01-20 06:13:02 +00:00
|
|
|
#include "clang/Basic/MacroBuilder.h"
|
2009-11-15 06:48:46 +00:00
|
|
|
#include "clang/Basic/TargetBuiltins.h"
|
|
|
|
#include "clang/Basic/TargetOptions.h"
|
2015-10-30 16:30:36 +00:00
|
|
|
#include "clang/Basic/Version.h"
|
2008-05-20 14:27:34 +00:00
|
|
|
#include "llvm/ADT/APFloat.h"
|
2009-11-11 09:38:56 +00:00
|
|
|
#include "llvm/ADT/STLExtras.h"
|
2014-09-18 02:13:33 +00:00
|
|
|
#include "llvm/ADT/StringExtras.h"
|
2009-08-19 20:04:03 +00:00
|
|
|
#include "llvm/ADT/StringRef.h"
|
2009-11-11 09:38:56 +00:00
|
|
|
#include "llvm/ADT/StringSwitch.h"
|
2009-08-12 06:24:27 +00:00
|
|
|
#include "llvm/ADT/Triple.h"
|
2009-08-10 19:03:04 +00:00
|
|
|
#include "llvm/MC/MCSectionMachO.h"
|
2011-09-23 05:35:21 +00:00
|
|
|
#include "llvm/Support/ErrorHandling.h"
|
2015-05-27 13:33:00 +00:00
|
|
|
#include "llvm/Support/TargetParser.h"
|
2010-01-09 18:20:57 +00:00
|
|
|
#include <algorithm>
|
2014-03-09 11:36:40 +00:00
|
|
|
#include <memory>
|
2015-09-10 17:07:54 +00:00
|
|
|
|
2007-12-03 22:06:55 +00:00
|
|
|
using namespace clang;
|
2006-10-14 07:39:34 +00:00
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
2006-10-14 18:32:12 +00:00
|
|
|
// Common code shared among targets.
|
2006-10-14 07:39:34 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2009-03-20 16:06:38 +00: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 10:55:15 +00:00
|
|
|
static void DefineStd(MacroBuilder &Builder, StringRef MacroName,
|
2009-03-20 16:06:38 +00:00
|
|
|
const LangOptions &Opts) {
|
|
|
|
assert(MacroName[0] != '_' && "Identifier should be in the user's namespace");
|
2009-05-03 13:42:53 +00:00
|
|
|
|
2009-03-20 16:06:38 +00: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-09 17:55:51 +00:00
|
|
|
Builder.defineMacro(MacroName);
|
2009-05-03 13:42:53 +00:00
|
|
|
|
2009-03-20 16:06:38 +00:00
|
|
|
// Define __unix.
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("__" + MacroName);
|
2009-05-03 13:42:53 +00:00
|
|
|
|
2009-03-20 16:06:38 +00:00
|
|
|
// Define __unix__.
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("__" + MacroName + "__");
|
2009-03-20 16:06:38 +00:00
|
|
|
}
|
|
|
|
|
2012-01-10 11:50:09 +00: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-05 21:50:58 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Defines specific to certain operating systems.
|
|
|
|
//===----------------------------------------------------------------------===//
|
2009-08-10 19:03:04 +00:00
|
|
|
|
2009-06-30 17:10:35 +00:00
|
|
|
namespace {
|
2009-07-01 15:12:53 +00:00
|
|
|
template<typename TgtInfo>
|
|
|
|
class OSTargetInfo : public TgtInfo {
|
2009-06-30 17:10:35 +00:00
|
|
|
protected:
|
2009-08-24 09:10:05 +00:00
|
|
|
virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
2010-01-09 17:55:51 +00:00
|
|
|
MacroBuilder &Builder) const=0;
|
2009-06-30 17:10:35 +00:00
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
OSTargetInfo(const llvm::Triple &Triple) : TgtInfo(Triple) {}
|
2014-03-11 03:39:26 +00:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
2010-01-09 17:55:51 +00:00
|
|
|
TgtInfo::getTargetDefines(Opts, Builder);
|
|
|
|
getOSDefines(Opts, TgtInfo::getTriple(), Builder);
|
2009-06-30 17:00:25 +00:00
|
|
|
}
|
|
|
|
|
2009-06-30 17:10:35 +00:00
|
|
|
};
|
2008-12-04 23:20:07 +00:00
|
|
|
|
2015-09-24 21:17:04 +00:00
|
|
|
// CloudABI Target
|
|
|
|
template <typename Target>
|
|
|
|
class CloudABITargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
|
|
|
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
|
|
|
MacroBuilder &Builder) const override {
|
|
|
|
Builder.defineMacro("__CloudABI__");
|
|
|
|
Builder.defineMacro("__ELF__");
|
|
|
|
|
|
|
|
// CloudABI uses ISO/IEC 10646:2012 for wchar_t, char16_t and char32_t.
|
|
|
|
Builder.defineMacro("__STDC_ISO_10646__", "201206L");
|
|
|
|
Builder.defineMacro("__STDC_UTF_16__");
|
|
|
|
Builder.defineMacro("__STDC_UTF_32__");
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
CloudABITargetInfo(const llvm::Triple &Triple)
|
2016-01-27 01:04:51 +00:00
|
|
|
: OSTargetInfo<Target>(Triple) {
|
|
|
|
this->UserLabelPrefix = "";
|
|
|
|
}
|
2015-09-24 21:17:04 +00:00
|
|
|
};
|
|
|
|
|
2010-01-26 01:44:04 +00: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 00:50:03 +00:00
|
|
|
const llvm::Triple &Triple,
|
2011-07-23 10:55:15 +00: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 00:50:03 +00:00
|
|
|
VersionTuple &PlatformMinVersion) {
|
2013-08-19 20:23:37 +00:00
|
|
|
Builder.defineMacro("__APPLE_CC__", "6000");
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("__APPLE__");
|
|
|
|
Builder.defineMacro("OBJC_NEW_PROPERTIES");
|
2012-09-20 10:10:01 +00:00
|
|
|
// AddressSanitizer doesn't play well with source fortification, which is on
|
|
|
|
// by default on Darwin.
|
2014-11-07 22:29:38 +00:00
|
|
|
if (Opts.Sanitize.has(SanitizerKind::Address))
|
|
|
|
Builder.defineMacro("_FORTIFY_SOURCE", "0");
|
2009-05-03 13:42:53 +00:00
|
|
|
|
Define weak and __weak to mean ARC-style weak references, even in MRC.
Previously, __weak was silently accepted and ignored in MRC mode.
That makes this a potentially source-breaking change that we have to
roll out cautiously. Accordingly, for the time being, actual support
for __weak references in MRC is experimental, and the compiler will
reject attempts to actually form such references. The intent is to
eventually enable the feature by default in all non-GC modes.
(It is, of course, incompatible with ObjC GC's interpretation of
__weak.)
If you like, you can enable this feature with
-Xclang -fobjc-weak
but like any -Xclang option, this option may be removed at any point,
e.g. if/when it is eventually enabled by default.
This patch also enables the use of the ARC __unsafe_unretained qualifier
in MRC. Unlike __weak, this is being enabled immediately. Since
variables are essentially __unsafe_unretained by default in MRC,
the only practical uses are (1) communication and (2) changing the
default behavior of by-value block capture.
As an implementation matter, this means that the ObjC ownership
qualifiers may appear in any ObjC language mode, and so this patch
removes a number of checks for getLangOpts().ObjCAutoRefCount
that were guarding the processing of these qualifiers. I don't
expect this to be a significant drain on performance; it may even
be faster to just check for these qualifiers directly on a type
(since it's probably in a register anyway) than to do N dependent
loads to grab the LangOptions.
rdar://9674298
llvm-svn: 251041
2015-10-22 18:38:17 +00:00
|
|
|
// Darwin defines __weak, __strong, and __unsafe_unretained even in C mode.
|
|
|
|
if (!Opts.ObjC1) {
|
2011-06-15 23:02:42 +00:00
|
|
|
// __weak is always defined, for use in blocks and with objc pointers.
|
|
|
|
Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))");
|
Define weak and __weak to mean ARC-style weak references, even in MRC.
Previously, __weak was silently accepted and ignored in MRC mode.
That makes this a potentially source-breaking change that we have to
roll out cautiously. Accordingly, for the time being, actual support
for __weak references in MRC is experimental, and the compiler will
reject attempts to actually form such references. The intent is to
eventually enable the feature by default in all non-GC modes.
(It is, of course, incompatible with ObjC GC's interpretation of
__weak.)
If you like, you can enable this feature with
-Xclang -fobjc-weak
but like any -Xclang option, this option may be removed at any point,
e.g. if/when it is eventually enabled by default.
This patch also enables the use of the ARC __unsafe_unretained qualifier
in MRC. Unlike __weak, this is being enabled immediately. Since
variables are essentially __unsafe_unretained by default in MRC,
the only practical uses are (1) communication and (2) changing the
default behavior of by-value block capture.
As an implementation matter, this means that the ObjC ownership
qualifiers may appear in any ObjC language mode, and so this patch
removes a number of checks for getLangOpts().ObjCAutoRefCount
that were guarding the processing of these qualifiers. I don't
expect this to be a significant drain on performance; it may even
be faster to just check for these qualifiers directly on a type
(since it's probably in a register anyway) than to do N dependent
loads to grab the LangOptions.
rdar://9674298
llvm-svn: 251041
2015-10-22 18:38:17 +00:00
|
|
|
Builder.defineMacro("__strong", "");
|
2011-06-15 23:02:42 +00:00
|
|
|
Builder.defineMacro("__unsafe_unretained", "");
|
|
|
|
}
|
2011-07-07 22:55:26 +00:00
|
|
|
|
2009-06-04 23:00:29 +00:00
|
|
|
if (Opts.Static)
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("__STATIC__");
|
2009-06-04 23:00:29 +00:00
|
|
|
else
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("__DYNAMIC__");
|
2009-09-03 04:54:28 +00:00
|
|
|
|
|
|
|
if (Opts.POSIXThreads)
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("_REENTRANT");
|
2009-09-09 15:08:12 +00:00
|
|
|
|
2011-04-19 21:40:34 +00:00
|
|
|
// Get the platform type and version number from the triple.
|
2009-04-10 19:52:24 +00:00
|
|
|
unsigned Maj, Min, Rev;
|
2012-01-31 23:52:58 +00:00
|
|
|
if (Triple.isMacOSX()) {
|
|
|
|
Triple.getMacOSXVersion(Maj, Min, Rev);
|
2011-04-19 21:40:34 +00:00
|
|
|
PlatformName = "macosx";
|
|
|
|
} else {
|
2012-01-31 23:52:58 +00:00
|
|
|
Triple.getOSVersion(Maj, Min, Rev);
|
|
|
|
PlatformName = llvm::Triple::getOSTypeName(Triple.getOS());
|
2011-04-19 21:40:34 +00:00
|
|
|
}
|
2010-01-26 01:44:04 +00:00
|
|
|
|
2012-01-20 22:01:23 +00:00
|
|
|
// If -target arch-pc-win32-macho option specified, we're
|
2011-07-29 21:20:35 +00:00
|
|
|
// generating code for Win32 ABI. No need to emit
|
2011-07-19 20:00:06 +00:00
|
|
|
// __ENVIRONMENT_XX_OS_VERSION_MIN_REQUIRED__.
|
|
|
|
if (PlatformName == "win32") {
|
|
|
|
PlatformMinVersion = VersionTuple(Maj, Min, Rev);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-01-26 23:12:43 +00:00
|
|
|
// 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';
|
2015-10-30 16:30:30 +00:00
|
|
|
if (Triple.isTvOS())
|
|
|
|
Builder.defineMacro("__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__", Str);
|
|
|
|
else
|
|
|
|
Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__",
|
|
|
|
Str);
|
|
|
|
|
|
|
|
} else if (Triple.isWatchOS()) {
|
|
|
|
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_WATCH_OS_VERSION_MIN_REQUIRED__", Str);
|
2014-01-26 23:12:43 +00:00
|
|
|
} else if (Triple.isMacOSX()) {
|
|
|
|
// 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(Maj < 100 && Min < 100 && Rev < 100 && "Invalid version!");
|
2014-08-08 21:45:53 +00:00
|
|
|
char Str[7];
|
|
|
|
if (Maj < 10 || (Maj == 10 && Min < 10)) {
|
|
|
|
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';
|
|
|
|
} else {
|
|
|
|
// Handle versions > 10.9.
|
|
|
|
Str[0] = '0' + (Maj / 10);
|
|
|
|
Str[1] = '0' + (Maj % 10);
|
|
|
|
Str[2] = '0' + (Min / 10);
|
|
|
|
Str[3] = '0' + (Min % 10);
|
|
|
|
Str[4] = '0' + (Rev / 10);
|
|
|
|
Str[5] = '0' + (Rev % 10);
|
|
|
|
Str[6] = '\0';
|
|
|
|
}
|
2014-01-26 23:12:43 +00:00
|
|
|
Builder.defineMacro("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", Str);
|
2008-09-30 01:00:25 +00:00
|
|
|
}
|
2011-04-19 21:40:34 +00:00
|
|
|
|
2014-01-16 08:48:16 +00:00
|
|
|
// Tell users about the kernel if there is one.
|
|
|
|
if (Triple.isOSDarwin())
|
|
|
|
Builder.defineMacro("__MACH__");
|
|
|
|
|
2011-04-19 21:40:34 +00:00
|
|
|
PlatformMinVersion = VersionTuple(Maj, Min, Rev);
|
2008-08-20 02:34:37 +00:00
|
|
|
}
|
2006-10-14 07:39:34 +00:00
|
|
|
|
2009-06-30 17:10:35 +00:00
|
|
|
template<typename Target>
|
|
|
|
class DarwinTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
2014-03-11 03:39:26 +00:00
|
|
|
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
|
|
|
MacroBuilder &Builder) const override {
|
2011-07-07 22:55:26 +00: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 00:50:03 +00:00
|
|
|
this->PlatformMinVersion);
|
2009-06-30 17:10:35 +00:00
|
|
|
}
|
2009-09-09 15:08:12 +00:00
|
|
|
|
2009-06-30 17:10:35 +00:00
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
DarwinTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
|
2016-01-07 09:04:46 +00:00
|
|
|
// By default, no TLS, and we whitelist permitted architecture/OS
|
|
|
|
// combinations.
|
|
|
|
this->TLSSupported = false;
|
|
|
|
|
|
|
|
if (Triple.isMacOSX())
|
|
|
|
this->TLSSupported = !Triple.isMacOSXVersionLT(10, 7);
|
|
|
|
else if (Triple.isiOS()) {
|
|
|
|
// 64-bit iOS supported it from 8 onwards, 32-bit from 9 onwards.
|
|
|
|
if (Triple.getArch() == llvm::Triple::x86_64 ||
|
|
|
|
Triple.getArch() == llvm::Triple::aarch64)
|
|
|
|
this->TLSSupported = !Triple.isOSVersionLT(8);
|
|
|
|
else if (Triple.getArch() == llvm::Triple::x86 ||
|
|
|
|
Triple.getArch() == llvm::Triple::arm ||
|
|
|
|
Triple.getArch() == llvm::Triple::thumb)
|
|
|
|
this->TLSSupported = !Triple.isOSVersionLT(9);
|
|
|
|
} else if (Triple.isWatchOS())
|
|
|
|
this->TLSSupported = !Triple.isOSVersionLT(2);
|
|
|
|
|
2013-06-29 16:37:14 +00:00
|
|
|
this->MCountName = "\01mcount";
|
|
|
|
}
|
2009-06-30 17:10:35 +00:00
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
std::string isValidSectionSpecifier(StringRef SR) const override {
|
2009-08-10 19:03:04 +00:00
|
|
|
// Let MCSectionMachO validate this.
|
2011-07-23 10:55:15 +00:00
|
|
|
StringRef Segment, Section;
|
2009-08-10 19:03:04 +00:00
|
|
|
unsigned TAA, StubSize;
|
2011-03-19 02:06:21 +00:00
|
|
|
bool HasTAA;
|
2009-08-10 19:03:04 +00:00
|
|
|
return llvm::MCSectionMachO::ParseSectionSpecifier(SR, Segment, Section,
|
2011-03-19 02:06:21 +00:00
|
|
|
TAA, HasTAA, StubSize);
|
2009-08-10 19:03:04 +00:00
|
|
|
}
|
2010-10-21 03:16:25 +00:00
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
const char *getStaticInitSectionSpecifier() const override {
|
2010-06-08 22:47:50 +00:00
|
|
|
// FIXME: We should return 0 when building kexts.
|
|
|
|
return "__TEXT,__StaticInit,regular,pure_instructions";
|
|
|
|
}
|
2010-10-21 03:16:25 +00:00
|
|
|
|
2012-01-29 01:20:30 +00: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.
|
2014-03-11 03:39:26 +00:00
|
|
|
bool hasProtectedVisibility() const override {
|
2012-01-29 01:20:30 +00:00
|
|
|
return false;
|
|
|
|
}
|
2009-06-30 17:10:35 +00:00
|
|
|
};
|
|
|
|
|
2009-08-10 19:03:04 +00:00
|
|
|
|
2009-06-30 17:10:35 +00:00
|
|
|
// DragonFlyBSD Target
|
|
|
|
template<typename Target>
|
|
|
|
class DragonFlyBSDTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
2014-03-11 03:39:26 +00:00
|
|
|
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
|
|
|
MacroBuilder &Builder) const override {
|
2009-06-30 17:10:35 +00:00
|
|
|
// DragonFly defines; list based off of gcc output
|
2010-01-09 17:55:51 +00: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-06-30 17:10:35 +00:00
|
|
|
}
|
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
DragonFlyBSDTargetInfo(const llvm::Triple &Triple)
|
|
|
|
: OSTargetInfo<Target>(Triple) {
|
2016-01-27 01:04:51 +00:00
|
|
|
this->UserLabelPrefix = "";
|
|
|
|
|
2013-06-29 16:37:14 +00:00
|
|
|
switch (Triple.getArch()) {
|
|
|
|
default:
|
|
|
|
case llvm::Triple::x86:
|
|
|
|
case llvm::Triple::x86_64:
|
|
|
|
this->MCountName = ".mcount";
|
|
|
|
break;
|
|
|
|
}
|
2012-02-10 23:02:29 +00:00
|
|
|
}
|
2009-06-30 17:10:35 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// FreeBSD Target
|
|
|
|
template<typename Target>
|
|
|
|
class FreeBSDTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
2014-03-11 03:39:26 +00:00
|
|
|
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
|
|
|
MacroBuilder &Builder) const override {
|
2009-06-30 17:10:35 +00:00
|
|
|
// FreeBSD defines; list based off of gcc output
|
|
|
|
|
2011-10-18 10:10:08 +00:00
|
|
|
unsigned Release = Triple.getOSMajorVersion();
|
|
|
|
if (Release == 0U)
|
|
|
|
Release = 8;
|
2010-01-30 19:55:01 +00:00
|
|
|
|
2011-10-18 10:10:08 +00:00
|
|
|
Builder.defineMacro("__FreeBSD__", Twine(Release));
|
|
|
|
Builder.defineMacro("__FreeBSD_cc_version", Twine(Release * 100000U + 1U));
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
|
|
|
|
DefineStd(Builder, "unix", Opts);
|
|
|
|
Builder.defineMacro("__ELF__");
|
2013-09-29 07:54:52 +00: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.
|
2015-01-13 01:47:45 +00:00
|
|
|
//
|
|
|
|
// FIXME: This is wrong; the macro refers to the numerical values
|
|
|
|
// of wchar_t *literals*, which are not locale-dependent. However,
|
|
|
|
// FreeBSD systems apparently depend on us getting this wrong, and
|
|
|
|
// setting this to 1 is conforming even if all the basic source
|
|
|
|
// character literals have the same encoding as char and wchar_t.
|
2013-09-29 07:54:52 +00:00
|
|
|
Builder.defineMacro("__STDC_MB_MIGHT_NEQ_WC__", "1");
|
2009-06-30 17:10:35 +00:00
|
|
|
}
|
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
FreeBSDTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
|
2016-01-27 01:04:51 +00:00
|
|
|
this->UserLabelPrefix = "";
|
|
|
|
|
2013-06-29 16:37:14 +00: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 01:36:11 +00:00
|
|
|
case llvm::Triple::ppc64le:
|
2013-06-29 16:37:14 +00:00
|
|
|
this->MCountName = "_mcount";
|
|
|
|
break;
|
|
|
|
case llvm::Triple::arm:
|
|
|
|
this->MCountName = "__mcount";
|
|
|
|
break;
|
2009-07-08 13:55:08 +00:00
|
|
|
}
|
2013-06-29 16:37:14 +00:00
|
|
|
}
|
2009-06-30 17:10:35 +00:00
|
|
|
};
|
|
|
|
|
2013-09-05 13:47:07 +00:00
|
|
|
// GNU/kFreeBSD Target
|
|
|
|
template<typename Target>
|
|
|
|
class KFreeBSDTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
2014-03-11 03:39:26 +00:00
|
|
|
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
|
|
|
MacroBuilder &Builder) const override {
|
2013-09-05 13:47:07 +00:00
|
|
|
// 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:
|
2014-11-18 22:36:15 +00:00
|
|
|
KFreeBSDTargetInfo(const llvm::Triple &Triple)
|
2016-01-27 01:04:51 +00:00
|
|
|
: OSTargetInfo<Target>(Triple) {
|
|
|
|
this->UserLabelPrefix = "";
|
|
|
|
}
|
2013-09-05 13:47:07 +00:00
|
|
|
};
|
|
|
|
|
2010-07-07 16:01:42 +00:00
|
|
|
// Minix Target
|
|
|
|
template<typename Target>
|
|
|
|
class MinixTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
2014-03-11 03:39:26 +00:00
|
|
|
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
|
|
|
MacroBuilder &Builder) const override {
|
2010-07-07 16:01:42 +00:00
|
|
|
// 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-08 23:54:21 +00:00
|
|
|
Builder.defineMacro("__ELF__");
|
2010-07-07 16:01:42 +00:00
|
|
|
DefineStd(Builder, "unix", Opts);
|
|
|
|
}
|
|
|
|
public:
|
2016-01-27 01:04:51 +00:00
|
|
|
MinixTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
|
|
|
|
this->UserLabelPrefix = "";
|
|
|
|
}
|
2010-07-07 16:01:42 +00:00
|
|
|
};
|
|
|
|
|
2009-06-30 17:10:35 +00:00
|
|
|
// Linux target
|
|
|
|
template<typename Target>
|
|
|
|
class LinuxTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
2014-03-11 03:39:26 +00:00
|
|
|
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
|
|
|
MacroBuilder &Builder) const override {
|
2009-06-30 17:10:35 +00:00
|
|
|
// Linux defines; list based off of gcc output
|
2010-01-09 17:55:51 +00:00
|
|
|
DefineStd(Builder, "unix", Opts);
|
|
|
|
DefineStd(Builder, "linux", Opts);
|
|
|
|
Builder.defineMacro("__gnu_linux__");
|
|
|
|
Builder.defineMacro("__ELF__");
|
2015-10-08 21:21:44 +00:00
|
|
|
if (Triple.isAndroid()) {
|
2012-04-26 12:08:09 +00:00
|
|
|
Builder.defineMacro("__ANDROID__", "1");
|
2015-03-03 18:28:38 +00:00
|
|
|
unsigned Maj, Min, Rev;
|
2015-06-01 23:38:25 +00:00
|
|
|
Triple.getEnvironmentVersion(Maj, Min, Rev);
|
2015-03-03 18:28:38 +00:00
|
|
|
this->PlatformName = "android";
|
|
|
|
this->PlatformMinVersion = VersionTuple(Maj, Min, Rev);
|
|
|
|
}
|
2009-09-03 04:54:28 +00:00
|
|
|
if (Opts.POSIXThreads)
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("_REENTRANT");
|
2010-04-21 05:52:38 +00:00
|
|
|
if (Opts.CPlusPlus)
|
|
|
|
Builder.defineMacro("_GNU_SOURCE");
|
2009-06-30 17:10:35 +00:00
|
|
|
}
|
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
LinuxTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
|
2009-06-30 17:10:35 +00:00
|
|
|
this->UserLabelPrefix = "";
|
2011-01-12 21:19:25 +00:00
|
|
|
this->WIntType = TargetInfo::UnsignedInt;
|
2014-03-30 13:00:06 +00:00
|
|
|
|
|
|
|
switch (Triple.getArch()) {
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
case llvm::Triple::ppc:
|
|
|
|
case llvm::Triple::ppc64:
|
|
|
|
case llvm::Triple::ppc64le:
|
|
|
|
this->MCountName = "_mcount";
|
|
|
|
break;
|
|
|
|
}
|
2009-06-30 17:10:35 +00:00
|
|
|
}
|
2011-10-15 17:53:33 +00:00
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
const char *getStaticInitSectionSpecifier() const override {
|
2011-10-15 17:53:33 +00:00
|
|
|
return ".text.startup";
|
|
|
|
}
|
2009-06-30 17:10:35 +00:00
|
|
|
};
|
|
|
|
|
2009-07-13 20:29:08 +00:00
|
|
|
// NetBSD Target
|
|
|
|
template<typename Target>
|
|
|
|
class NetBSDTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
2014-03-11 03:39:26 +00:00
|
|
|
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
|
|
|
MacroBuilder &Builder) const override {
|
2009-07-13 20:29:08 +00:00
|
|
|
// NetBSD defines; list based off of gcc output
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("__NetBSD__");
|
|
|
|
Builder.defineMacro("__unix__");
|
|
|
|
Builder.defineMacro("__ELF__");
|
2009-09-03 04:54:28 +00:00
|
|
|
if (Opts.POSIXThreads)
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("_POSIX_THREADS");
|
2014-05-13 18:58:36 +00:00
|
|
|
|
|
|
|
switch (Triple.getArch()) {
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
case llvm::Triple::arm:
|
|
|
|
case llvm::Triple::armeb:
|
|
|
|
case llvm::Triple::thumb:
|
|
|
|
case llvm::Triple::thumbeb:
|
|
|
|
Builder.defineMacro("__ARM_DWARF_EH__");
|
|
|
|
break;
|
|
|
|
}
|
2009-07-13 20:29:08 +00:00
|
|
|
}
|
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
NetBSDTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
|
2016-01-27 01:04:51 +00:00
|
|
|
this->UserLabelPrefix = "";
|
2015-04-10 21:02:53 +00:00
|
|
|
this->MCountName = "_mcount";
|
2013-06-29 16:37:14 +00:00
|
|
|
}
|
2009-07-13 20:29:08 +00:00
|
|
|
};
|
|
|
|
|
2009-06-30 17:10:35 +00:00
|
|
|
// OpenBSD Target
|
|
|
|
template<typename Target>
|
|
|
|
class OpenBSDTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
2014-03-11 03:39:26 +00:00
|
|
|
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
|
|
|
MacroBuilder &Builder) const override {
|
2009-06-30 17:10:35 +00:00
|
|
|
// OpenBSD defines; list based off of gcc output
|
|
|
|
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("__OpenBSD__");
|
|
|
|
DefineStd(Builder, "unix", Opts);
|
|
|
|
Builder.defineMacro("__ELF__");
|
2009-09-03 04:54:28 +00:00
|
|
|
if (Opts.POSIXThreads)
|
2012-04-25 06:12:24 +00:00
|
|
|
Builder.defineMacro("_REENTRANT");
|
2009-06-30 17:10:35 +00:00
|
|
|
}
|
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
OpenBSDTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
|
2016-01-27 01:04:51 +00:00
|
|
|
this->UserLabelPrefix = "";
|
2013-06-29 16:37:14 +00:00
|
|
|
this->TLSSupported = false;
|
2011-12-15 02:15:56 +00:00
|
|
|
|
|
|
|
switch (Triple.getArch()) {
|
|
|
|
default:
|
|
|
|
case llvm::Triple::x86:
|
|
|
|
case llvm::Triple::x86_64:
|
|
|
|
case llvm::Triple::arm:
|
2012-11-14 22:08:59 +00:00
|
|
|
case llvm::Triple::sparc:
|
2011-12-15 02:15:56 +00:00
|
|
|
this->MCountName = "__mcount";
|
|
|
|
break;
|
|
|
|
case llvm::Triple::mips64:
|
|
|
|
case llvm::Triple::mips64el:
|
|
|
|
case llvm::Triple::ppc:
|
2012-11-14 22:08:59 +00:00
|
|
|
case llvm::Triple::sparcv9:
|
2011-12-15 02:15:56 +00:00
|
|
|
this->MCountName = "_mcount";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2009-06-30 17:10:35 +00:00
|
|
|
};
|
|
|
|
|
2012-08-08 23:57:20 +00:00
|
|
|
// Bitrig Target
|
|
|
|
template<typename Target>
|
|
|
|
class BitrigTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
2014-03-11 03:39:26 +00:00
|
|
|
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
|
|
|
MacroBuilder &Builder) const override {
|
2012-08-08 23:57:20 +00:00
|
|
|
// Bitrig defines; list based off of gcc output
|
|
|
|
|
|
|
|
Builder.defineMacro("__Bitrig__");
|
|
|
|
DefineStd(Builder, "unix", Opts);
|
|
|
|
Builder.defineMacro("__ELF__");
|
|
|
|
if (Opts.POSIXThreads)
|
|
|
|
Builder.defineMacro("_REENTRANT");
|
2015-02-27 16:35:48 +00:00
|
|
|
|
|
|
|
switch (Triple.getArch()) {
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
case llvm::Triple::arm:
|
|
|
|
case llvm::Triple::armeb:
|
|
|
|
case llvm::Triple::thumb:
|
|
|
|
case llvm::Triple::thumbeb:
|
|
|
|
Builder.defineMacro("__ARM_DWARF_EH__");
|
|
|
|
break;
|
|
|
|
}
|
2012-08-08 23:57:20 +00:00
|
|
|
}
|
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
BitrigTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
|
2016-01-27 01:04:51 +00:00
|
|
|
this->UserLabelPrefix = "";
|
2013-06-29 16:37:14 +00:00
|
|
|
this->MCountName = "__mcount";
|
2012-08-08 23:57:20 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2009-11-15 10:22:07 +00:00
|
|
|
// PSP Target
|
|
|
|
template<typename Target>
|
|
|
|
class PSPTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
2014-03-11 03:39:26 +00:00
|
|
|
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
|
|
|
MacroBuilder &Builder) const override {
|
2009-11-15 10:22:07 +00:00
|
|
|
// PSP defines; list based on the output of the pspdev gcc toolchain.
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("PSP");
|
|
|
|
Builder.defineMacro("_PSP");
|
|
|
|
Builder.defineMacro("__psp__");
|
|
|
|
Builder.defineMacro("__ELF__");
|
2009-11-15 10:22:07 +00:00
|
|
|
}
|
|
|
|
public:
|
2016-01-27 01:04:51 +00:00
|
|
|
PSPTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
|
|
|
|
this->UserLabelPrefix = "";
|
|
|
|
}
|
2009-11-15 10:22:07 +00:00
|
|
|
};
|
|
|
|
|
2009-11-19 17:18:50 +00:00
|
|
|
// PS3 PPU Target
|
|
|
|
template<typename Target>
|
|
|
|
class PS3PPUTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
2014-03-11 03:39:26 +00:00
|
|
|
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
|
|
|
MacroBuilder &Builder) const override {
|
2009-11-19 17:18:50 +00:00
|
|
|
// PS3 PPU defines.
|
2010-03-25 16:18:32 +00:00
|
|
|
Builder.defineMacro("__PPC__");
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("__PPU__");
|
|
|
|
Builder.defineMacro("__CELLOS_LV2__");
|
|
|
|
Builder.defineMacro("__ELF__");
|
|
|
|
Builder.defineMacro("__LP32__");
|
2010-06-24 22:44:13 +00:00
|
|
|
Builder.defineMacro("_ARCH_PPC64");
|
|
|
|
Builder.defineMacro("__powerpc64__");
|
2009-11-19 17:18:50 +00:00
|
|
|
}
|
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
PS3PPUTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
|
2016-01-27 01:04:51 +00:00
|
|
|
this->UserLabelPrefix = "";
|
2011-12-16 22:32:39 +00:00
|
|
|
this->LongWidth = this->LongAlign = 32;
|
|
|
|
this->PointerWidth = this->PointerAlign = 32;
|
2010-06-24 22:44:13 +00:00
|
|
|
this->IntMaxType = TargetInfo::SignedLongLong;
|
|
|
|
this->Int64Type = TargetInfo::SignedLongLong;
|
2009-12-18 14:21:08 +00:00
|
|
|
this->SizeType = TargetInfo::UnsignedInt;
|
2015-08-05 23:48:05 +00:00
|
|
|
this->DataLayoutString = "E-m:e-p:32:32-i64:64-n32:64";
|
2009-11-19 17:18:50 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-01-27 14:47:44 +00:00
|
|
|
template <typename Target>
|
|
|
|
class PS4OSTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
|
|
|
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
|
|
|
MacroBuilder &Builder) const override {
|
|
|
|
Builder.defineMacro("__FreeBSD__", "9");
|
|
|
|
Builder.defineMacro("__FreeBSD_cc_version", "900001");
|
|
|
|
Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
|
|
|
|
DefineStd(Builder, "unix", Opts);
|
|
|
|
Builder.defineMacro("__ELF__");
|
|
|
|
Builder.defineMacro("__PS4__");
|
|
|
|
}
|
|
|
|
public:
|
|
|
|
PS4OSTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
|
|
|
|
this->WCharType = this->UnsignedShort;
|
|
|
|
|
2015-07-14 20:52:32 +00:00
|
|
|
// On PS4, TLS variable cannot be aligned to more than 32 bytes (256 bits).
|
|
|
|
this->MaxTLSAlign = 256;
|
2016-01-27 01:04:51 +00:00
|
|
|
this->UserLabelPrefix = "";
|
2015-01-27 14:47:44 +00:00
|
|
|
|
|
|
|
switch (Triple.getArch()) {
|
|
|
|
default:
|
|
|
|
case llvm::Triple::x86_64:
|
|
|
|
this->MCountName = ".mcount";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2009-06-30 17:10:35 +00:00
|
|
|
// Solaris target
|
|
|
|
template<typename Target>
|
|
|
|
class SolarisTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
2014-03-11 03:39:26 +00:00
|
|
|
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
|
|
|
MacroBuilder &Builder) const override {
|
2010-01-09 17:55:51 +00:00
|
|
|
DefineStd(Builder, "sun", Opts);
|
|
|
|
DefineStd(Builder, "unix", Opts);
|
|
|
|
Builder.defineMacro("__ELF__");
|
|
|
|
Builder.defineMacro("__svr4__");
|
|
|
|
Builder.defineMacro("__SVR4");
|
2012-02-28 17:10:04 +00: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
|
2014-10-20 23:26:58 +00:00
|
|
|
// with a new version.
|
|
|
|
if (Opts.C99)
|
2012-02-28 17:10:04 +00:00
|
|
|
Builder.defineMacro("_XOPEN_SOURCE", "600");
|
|
|
|
else
|
|
|
|
Builder.defineMacro("_XOPEN_SOURCE", "500");
|
2012-03-02 10:49:52 +00:00
|
|
|
if (Opts.CPlusPlus)
|
2012-02-28 17:10:04 +00:00
|
|
|
Builder.defineMacro("__C99FEATURES__");
|
2012-02-17 18:35:11 +00:00
|
|
|
Builder.defineMacro("_LARGEFILE_SOURCE");
|
|
|
|
Builder.defineMacro("_LARGEFILE64_SOURCE");
|
|
|
|
Builder.defineMacro("__EXTENSIONS__");
|
2012-02-28 17:10:04 +00:00
|
|
|
Builder.defineMacro("_REENTRANT");
|
2009-06-30 17:10:35 +00:00
|
|
|
}
|
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
SolarisTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
|
2009-06-30 17:10:35 +00:00
|
|
|
this->UserLabelPrefix = "";
|
2012-03-28 18:04:14 +00:00
|
|
|
this->WCharType = this->SignedInt;
|
2009-06-30 17:10:35 +00:00
|
|
|
// FIXME: WIntType should be SignedLong
|
|
|
|
}
|
|
|
|
};
|
2010-10-21 05:21:48 +00:00
|
|
|
|
|
|
|
// Windows target
|
|
|
|
template<typename Target>
|
|
|
|
class WindowsTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
2014-03-11 03:39:26 +00:00
|
|
|
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
|
|
|
MacroBuilder &Builder) const override {
|
2010-10-21 08:22:51 +00:00
|
|
|
Builder.defineMacro("_WIN32");
|
|
|
|
}
|
|
|
|
void getVisualStudioDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const {
|
2010-10-21 05:21:48 +00:00
|
|
|
if (Opts.CPlusPlus) {
|
2014-07-01 22:24:56 +00:00
|
|
|
if (Opts.RTTIData)
|
2010-10-21 05:21:48 +00:00
|
|
|
Builder.defineMacro("_CPPRTTI");
|
|
|
|
|
2015-01-30 21:42:55 +00:00
|
|
|
if (Opts.CXXExceptions)
|
2010-10-21 05:21:48 +00:00
|
|
|
Builder.defineMacro("_CPPUNWIND");
|
2015-07-22 22:36:26 +00:00
|
|
|
}
|
2015-07-15 17:32:34 +00:00
|
|
|
|
2015-07-22 22:36:26 +00:00
|
|
|
if (Opts.Bool)
|
2015-07-15 17:32:34 +00:00
|
|
|
Builder.defineMacro("__BOOL_DEFINED");
|
2010-10-21 05:21:48 +00:00
|
|
|
|
|
|
|
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 08:22:51 +00:00
|
|
|
|
2014-07-16 03:13:50 +00:00
|
|
|
if (Opts.MSCompatibilityVersion) {
|
|
|
|
Builder.defineMacro("_MSC_VER",
|
|
|
|
Twine(Opts.MSCompatibilityVersion / 100000));
|
|
|
|
Builder.defineMacro("_MSC_FULL_VER", Twine(Opts.MSCompatibilityVersion));
|
2014-06-20 22:58:35 +00:00
|
|
|
// FIXME We cannot encode the revision information into 32-bits
|
|
|
|
Builder.defineMacro("_MSC_BUILD", Twine(1));
|
2015-03-18 07:53:18 +00:00
|
|
|
|
2015-05-11 03:57:49 +00:00
|
|
|
if (Opts.CPlusPlus11 && Opts.isCompatibleWithMSVC(LangOptions::MSVC2015))
|
2015-03-18 07:53:18 +00:00
|
|
|
Builder.defineMacro("_HAS_CHAR16_T_LANGUAGE_SUPPORT", Twine(1));
|
2014-06-20 22:58:35 +00:00
|
|
|
}
|
2014-04-16 20:10:16 +00:00
|
|
|
|
|
|
|
if (Opts.MicrosoftExt) {
|
|
|
|
Builder.defineMacro("_MSC_EXTENSIONS");
|
|
|
|
|
|
|
|
if (Opts.CPlusPlus11) {
|
|
|
|
Builder.defineMacro("_RVALUE_REFERENCES_V2_SUPPORTED");
|
|
|
|
Builder.defineMacro("_RVALUE_REFERENCES_SUPPORTED");
|
|
|
|
Builder.defineMacro("_NATIVE_NULLPTR_SUPPORTED");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-21 05:21:48 +00:00
|
|
|
Builder.defineMacro("_INTEGRAL_MAX_BITS", "64");
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
WindowsTargetInfo(const llvm::Triple &Triple)
|
|
|
|
: OSTargetInfo<Target>(Triple) {}
|
2010-10-21 05:21:48 +00:00
|
|
|
};
|
|
|
|
|
2012-10-11 16:55:58 +00:00
|
|
|
template <typename Target>
|
|
|
|
class NaClTargetInfo : public OSTargetInfo<Target> {
|
2013-06-29 16:37:14 +00:00
|
|
|
protected:
|
2014-03-11 03:39:26 +00:00
|
|
|
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
|
|
|
MacroBuilder &Builder) const override {
|
2012-10-11 16:55:58 +00:00
|
|
|
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-29 16:37:14 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
NaClTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
|
2016-01-27 01:04:51 +00:00
|
|
|
this->UserLabelPrefix = "";
|
2012-10-11 16:55:58 +00:00
|
|
|
this->LongAlign = 32;
|
|
|
|
this->LongWidth = 32;
|
|
|
|
this->PointerAlign = 32;
|
|
|
|
this->PointerWidth = 32;
|
|
|
|
this->IntMaxType = TargetInfo::SignedLongLong;
|
|
|
|
this->Int64Type = TargetInfo::SignedLongLong;
|
|
|
|
this->DoubleAlign = 64;
|
|
|
|
this->LongDoubleWidth = 64;
|
|
|
|
this->LongDoubleAlign = 64;
|
2014-01-15 21:42:41 +00:00
|
|
|
this->LongLongWidth = 64;
|
|
|
|
this->LongLongAlign = 64;
|
2012-10-11 16:55:58 +00:00
|
|
|
this->SizeType = TargetInfo::UnsignedInt;
|
|
|
|
this->PtrDiffType = TargetInfo::SignedInt;
|
|
|
|
this->IntPtrType = TargetInfo::SignedInt;
|
2013-04-08 21:31:01 +00:00
|
|
|
// RegParmMax is inherited from the underlying architecture
|
2012-10-11 16:55:58 +00:00
|
|
|
this->LongDoubleFormat = &llvm::APFloat::IEEEdouble;
|
2013-12-18 23:41:04 +00:00
|
|
|
if (Triple.getArch() == llvm::Triple::arm) {
|
2015-03-30 20:31:33 +00:00
|
|
|
// Handled in ARM's setABI().
|
2013-12-18 23:41:04 +00:00
|
|
|
} else if (Triple.getArch() == llvm::Triple::x86) {
|
2015-08-05 23:48:05 +00:00
|
|
|
this->DataLayoutString = "e-m:e-p:32:32-i64:64-n8:16:32-S128";
|
2013-12-18 23:41:04 +00:00
|
|
|
} else if (Triple.getArch() == llvm::Triple::x86_64) {
|
2015-08-05 23:48:05 +00:00
|
|
|
this->DataLayoutString = "e-m:e-p:32:32-i64:64-n8:16:32:64-S128";
|
2013-12-18 23:41:04 +00:00
|
|
|
} else if (Triple.getArch() == llvm::Triple::mipsel) {
|
2015-08-05 23:48:05 +00:00
|
|
|
// Handled on mips' setDataLayoutString.
|
2013-12-18 23:41:04 +00:00
|
|
|
} else {
|
|
|
|
assert(Triple.getArch() == llvm::Triple::le32);
|
2015-08-05 23:48:05 +00:00
|
|
|
this->DataLayoutString = "e-p:32:32-i64:64";
|
2013-12-18 23:41:04 +00:00
|
|
|
}
|
2012-10-11 16:55:58 +00:00
|
|
|
}
|
|
|
|
};
|
2009-06-30 17:10:35 +00:00
|
|
|
|
2015-09-03 22:51:53 +00:00
|
|
|
// WebAssembly target
|
|
|
|
template <typename Target>
|
|
|
|
class WebAssemblyOSTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
2015-09-10 17:07:54 +00:00
|
|
|
MacroBuilder &Builder) const final {
|
2015-09-03 22:51:53 +00:00
|
|
|
// A common platform macro.
|
|
|
|
if (Opts.POSIXThreads)
|
|
|
|
Builder.defineMacro("_REENTRANT");
|
|
|
|
// Follow g++ convention and predefine _GNU_SOURCE for C++.
|
|
|
|
if (Opts.CPlusPlus)
|
|
|
|
Builder.defineMacro("_GNU_SOURCE");
|
|
|
|
}
|
|
|
|
|
|
|
|
// As an optimization, group static init code together in a section.
|
2015-09-10 17:07:54 +00:00
|
|
|
const char *getStaticInitSectionSpecifier() const final {
|
2015-09-03 22:51:53 +00:00
|
|
|
return ".text.__startup";
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
explicit WebAssemblyOSTargetInfo(const llvm::Triple &Triple)
|
|
|
|
: OSTargetInfo<Target>(Triple) {
|
|
|
|
this->MCountName = "__mcount";
|
2016-01-27 01:04:51 +00:00
|
|
|
this->UserLabelPrefix = "";
|
2015-09-03 22:51:53 +00:00
|
|
|
this->TheCXXABI.set(TargetCXXABI::WebAssembly);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2008-08-20 23:11:40 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Specific target implementations.
|
|
|
|
//===----------------------------------------------------------------------===//
|
2007-10-13 00:45:48 +00:00
|
|
|
|
2008-08-20 23:11:40 +00:00
|
|
|
// 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-11 22:35:19 +00:00
|
|
|
std::string CPU;
|
2013-10-16 21:19:26 +00:00
|
|
|
|
|
|
|
// Target cpu features.
|
|
|
|
bool HasVSX;
|
2014-10-10 17:21:23 +00:00
|
|
|
bool HasP8Vector;
|
2015-03-04 21:48:22 +00:00
|
|
|
bool HasP8Crypto;
|
2015-04-11 10:43:36 +00:00
|
|
|
bool HasDirectMove;
|
2015-03-11 19:14:15 +00:00
|
|
|
bool HasQPX;
|
2015-03-25 19:41:41 +00:00
|
|
|
bool HasHTM;
|
2015-04-09 23:58:16 +00:00
|
|
|
bool HasBPERMD;
|
|
|
|
bool HasExtDiv;
|
2013-10-16 21:19:26 +00:00
|
|
|
|
2014-07-28 13:17:52 +00:00
|
|
|
protected:
|
|
|
|
std::string ABI;
|
|
|
|
|
2008-08-20 23:11:40 +00:00
|
|
|
public:
|
2013-10-16 21:19:26 +00:00
|
|
|
PPCTargetInfo(const llvm::Triple &Triple)
|
2015-03-04 21:48:22 +00:00
|
|
|
: TargetInfo(Triple), HasVSX(false), HasP8Vector(false),
|
2015-04-11 10:43:36 +00:00
|
|
|
HasP8Crypto(false), HasDirectMove(false), HasQPX(false), HasHTM(false),
|
2015-04-09 23:58:16 +00:00
|
|
|
HasBPERMD(false), HasExtDiv(false) {
|
2013-07-26 01:36:11 +00:00
|
|
|
BigEndian = (Triple.getArch() != llvm::Triple::ppc64le);
|
2015-07-02 03:40:19 +00:00
|
|
|
SimdDefaultAlign = 128;
|
2012-01-31 02:07:33 +00:00
|
|
|
LongDoubleWidth = LongDoubleAlign = 128;
|
|
|
|
LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble;
|
|
|
|
}
|
2009-06-05 07:05:05 +00:00
|
|
|
|
2012-07-03 16:51:04 +00: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-01 20:23:10 +00:00
|
|
|
ArchDefinePwr5 = 1 << 7,
|
|
|
|
ArchDefinePwr5x = 1 << 8,
|
|
|
|
ArchDefinePwr6 = 1 << 9,
|
|
|
|
ArchDefinePwr6x = 1 << 10,
|
|
|
|
ArchDefinePwr7 = 1 << 11,
|
2014-06-26 13:34:10 +00:00
|
|
|
ArchDefinePwr8 = 1 << 12,
|
|
|
|
ArchDefineA2 = 1 << 13,
|
|
|
|
ArchDefineA2q = 1 << 14
|
2012-07-03 16:51:04 +00:00
|
|
|
} ArchDefineTypes;
|
|
|
|
|
2013-02-01 20:23:10 +00: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.
|
2014-03-11 03:39:26 +00:00
|
|
|
bool setCPU(const std::string &Name) override {
|
2012-06-11 22:35:19 +00:00
|
|
|
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-01 20:23:10 +00:00
|
|
|
.Case("630", true)
|
2012-06-11 22:35:19 +00: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 05:53:33 +00:00
|
|
|
.Case("a2q", true)
|
2012-09-18 22:25:03 +00:00
|
|
|
.Case("e500mc", true)
|
|
|
|
.Case("e5500", true)
|
2013-02-01 20:23:10 +00: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-11 22:35:19 +00:00
|
|
|
.Case("pwr6", true)
|
2013-02-01 20:23:10 +00:00
|
|
|
.Case("power6x", true)
|
|
|
|
.Case("pwr6x", true)
|
|
|
|
.Case("power7", true)
|
2012-06-11 22:35:19 +00:00
|
|
|
.Case("pwr7", true)
|
2014-06-26 13:34:10 +00:00
|
|
|
.Case("power8", true)
|
|
|
|
.Case("pwr8", true)
|
2013-02-01 20:23:10 +00:00
|
|
|
.Case("powerpc", true)
|
2012-06-11 22:35:19 +00:00
|
|
|
.Case("ppc", true)
|
2013-02-01 20:23:10 +00:00
|
|
|
.Case("powerpc64", true)
|
2012-06-11 22:35:19 +00:00
|
|
|
.Case("ppc64", true)
|
2013-07-26 01:36:11 +00:00
|
|
|
.Case("powerpc64le", true)
|
|
|
|
.Case("ppc64le", true)
|
2012-06-11 22:35:19 +00:00
|
|
|
.Default(false);
|
|
|
|
|
|
|
|
if (CPUKnown)
|
|
|
|
CPU = Name;
|
|
|
|
|
|
|
|
return CPUKnown;
|
|
|
|
}
|
|
|
|
|
2014-07-28 13:17:52 +00:00
|
|
|
|
|
|
|
StringRef getABI() const override { return ABI; }
|
|
|
|
|
2015-10-19 04:51:35 +00:00
|
|
|
ArrayRef<Builtin::Info> getTargetBuiltins() const override {
|
|
|
|
return llvm::makeArrayRef(BuiltinInfo,
|
|
|
|
clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin);
|
2007-01-29 05:24:35 +00:00
|
|
|
}
|
2009-05-03 13:42:53 +00:00
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
bool isCLZForZeroUndef() const override { return false; }
|
2012-01-28 18:02:29 +00:00
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override;
|
2009-05-03 13:42:53 +00:00
|
|
|
|
2015-10-09 18:39:55 +00:00
|
|
|
bool
|
|
|
|
initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
|
|
|
|
StringRef CPU,
|
|
|
|
const std::vector<std::string> &FeaturesVec) const override;
|
2013-02-01 02:14:03 +00:00
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
bool handleTargetFeatures(std::vector<std::string> &Features,
|
|
|
|
DiagnosticsEngine &Diags) override;
|
|
|
|
bool hasFeature(StringRef Feature) const override;
|
Add missing builtins to altivec.h for ABI compliance (vol. 3)
This patch corresponds to review:
http://reviews.llvm.org/D10972
Fix for the handling of dependent features that are enabled by default
on some CPU's (such as -mvsx, -mpower8-vector).
Also provides a number of new interfaces or fixes existing ones in
altivec.h.
Changed signatures to conform to ABI:
vector short vec_perm(vector signed short, vector signed short, vector unsigned char)
vector int vec_perm(vector signed int, vector signed int, vector unsigned char)
vector long long vec_perm(vector signed long long, vector signed long long, vector unsigned char)
vector signed char vec_sld(vector signed char, vector signed char, const int)
vector unsigned char vec_sld(vector unsigned char, vector unsigned char, const int)
vector bool char vec_sld(vector bool char, vector bool char, const int)
vector unsigned short vec_sld(vector unsigned short, vector unsigned short, const int)
vector signed short vec_sld(vector signed short, vector signed short, const int)
vector signed int vec_sld(vector signed int, vector signed int, const int)
vector unsigned int vec_sld(vector unsigned int, vector unsigned int, const int)
vector float vec_sld(vector float, vector float, const int)
vector signed char vec_splat(vector signed char, const int)
vector unsigned char vec_splat(vector unsigned char, const int)
vector bool char vec_splat(vector bool char, const int)
vector signed short vec_splat(vector signed short, const int)
vector unsigned short vec_splat(vector unsigned short, const int)
vector bool short vec_splat(vector bool short, const int)
vector pixel vec_splat(vector pixel, const int)
vector signed int vec_splat(vector signed int, const int)
vector unsigned int vec_splat(vector unsigned int, const int)
vector bool int vec_splat(vector bool int, const int)
vector float vec_splat(vector float, const int)
Added a VSX path to:
vector float vec_round(vector float)
Added interfaces:
vector signed char vec_eqv(vector signed char, vector signed char)
vector signed char vec_eqv(vector bool char, vector signed char)
vector signed char vec_eqv(vector signed char, vector bool char)
vector unsigned char vec_eqv(vector unsigned char, vector unsigned char)
vector unsigned char vec_eqv(vector bool char, vector unsigned char)
vector unsigned char vec_eqv(vector unsigned char, vector bool char)
vector signed short vec_eqv(vector signed short, vector signed short)
vector signed short vec_eqv(vector bool short, vector signed short)
vector signed short vec_eqv(vector signed short, vector bool short)
vector unsigned short vec_eqv(vector unsigned short, vector unsigned short)
vector unsigned short vec_eqv(vector bool short, vector unsigned short)
vector unsigned short vec_eqv(vector unsigned short, vector bool short)
vector signed int vec_eqv(vector signed int, vector signed int)
vector signed int vec_eqv(vector bool int, vector signed int)
vector signed int vec_eqv(vector signed int, vector bool int)
vector unsigned int vec_eqv(vector unsigned int, vector unsigned int)
vector unsigned int vec_eqv(vector bool int, vector unsigned int)
vector unsigned int vec_eqv(vector unsigned int, vector bool int)
vector signed long long vec_eqv(vector signed long long, vector signed long long)
vector signed long long vec_eqv(vector bool long long, vector signed long long)
vector signed long long vec_eqv(vector signed long long, vector bool long long)
vector unsigned long long vec_eqv(vector unsigned long long, vector unsigned long long)
vector unsigned long long vec_eqv(vector bool long long, vector unsigned long long)
vector unsigned long long vec_eqv(vector unsigned long long, vector bool long long)
vector float vec_eqv(vector float, vector float)
vector float vec_eqv(vector bool int, vector float)
vector float vec_eqv(vector float, vector bool int)
vector double vec_eqv(vector double, vector double)
vector double vec_eqv(vector bool long long, vector double)
vector double vec_eqv(vector double, vector bool long long)
vector bool long long vec_perm(vector bool long long, vector bool long long, vector unsigned char)
vector double vec_round(vector double)
vector double vec_splat(vector double, const int)
vector bool long long vec_splat(vector bool long long, const int)
vector signed long long vec_splat(vector signed long long, const int)
vector unsigned long long vec_splat(vector unsigned long long,
vector bool int vec_sld(vector bool int, vector bool int, const int)
vector bool short vec_sld(vector bool short, vector bool short, const int)
llvm-svn: 241904
2015-07-10 13:11:34 +00:00
|
|
|
void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name,
|
|
|
|
bool Enabled) const override;
|
2014-03-11 03:39:26 +00:00
|
|
|
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<const char *> getGCCRegNames() const override;
|
|
|
|
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
|
2014-03-11 03:39:26 +00:00
|
|
|
bool validateAsmConstraint(const char *&Name,
|
|
|
|
TargetInfo::ConstraintInfo &Info) const override {
|
2009-02-28 17:11:49 +00:00
|
|
|
switch (*Name) {
|
2007-11-27 04:11:28 +00:00
|
|
|
default: return false;
|
|
|
|
case 'O': // Zero
|
2010-06-24 22:44:13 +00:00
|
|
|
break;
|
2007-11-27 04:11:28 +00:00
|
|
|
case 'b': // Base register
|
|
|
|
case 'f': // Floating point register
|
2009-04-26 07:16:29 +00:00
|
|
|
Info.setAllowsRegister();
|
2010-06-24 22:44:13 +00: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 03:16:25 +00:00
|
|
|
case 'd': // Floating point register (containing 64-bit value)
|
2010-06-24 22:44:13 +00:00
|
|
|
case 'v': // Altivec vector register
|
|
|
|
Info.setAllowsRegister();
|
|
|
|
break;
|
|
|
|
case 'w':
|
|
|
|
switch (Name[1]) {
|
2010-10-21 03:16:25 +00: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
|
2014-03-02 18:24:18 +00:00
|
|
|
case 'c':// An individual CR bit
|
2010-06-24 22:44:13 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
Info.setAllowsRegister();
|
|
|
|
Name++; // Skip over 'w'.
|
|
|
|
break;
|
2010-10-21 03:16:25 +00: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-24 22:44:13 +00:00
|
|
|
Info.setAllowsRegister();
|
|
|
|
break;
|
2010-10-21 03:16:25 +00:00
|
|
|
case 'I': // Signed 16-bit constant
|
2010-06-24 22:44:13 +00:00
|
|
|
case 'J': // Unsigned 16-bit constant shifted left 16 bits
|
2010-10-21 03:16:25 +00: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-24 22:44:13 +00:00
|
|
|
case 'G': // Floating point constant that can be loaded into a
|
2010-10-21 03:16:25 +00:00
|
|
|
// register with one instruction per word
|
2010-06-24 22:44:13 +00:00
|
|
|
case 'H': // Integer/Floating point constant that can be loaded
|
2010-10-21 03:16:25 +00:00
|
|
|
// into a register using three instructions
|
2010-06-24 22:44:13 +00: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-17 22:42:34 +00:00
|
|
|
// placeholder for the "update" flag in the corresponding
|
2010-10-21 03:16:25 +00:00
|
|
|
// load or store instruction. For example:
|
2010-06-24 22:44:13 +00:00
|
|
|
// asm ("st%U0 %1,%0" : "=m" (mem) : "r" (val));
|
2010-10-21 03:16:25 +00:00
|
|
|
// is correct but:
|
2010-06-24 22:44:13 +00: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 03:16:25 +00:00
|
|
|
// register to be updated.
|
|
|
|
case 'e':
|
2010-06-25 00:02:05 +00:00
|
|
|
if (Name[1] != 's')
|
|
|
|
return false;
|
2010-08-17 22:42:34 +00:00
|
|
|
// es: A "stable" memory operand; that is, one which does not
|
2010-06-24 22:44:13 +00: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 00:02:05 +00:00
|
|
|
// access it at all.
|
2010-06-24 22:44:13 +00:00
|
|
|
Info.setAllowsMemory();
|
2010-06-25 00:02:05 +00:00
|
|
|
Name++; // Skip over 'e'.
|
2010-06-24 22:44:13 +00:00
|
|
|
break;
|
|
|
|
case 'Q': // Memory operand that is an offset from a register (it is
|
2010-10-21 03:16:25 +00:00
|
|
|
// usually better to use `m' or `es' in asm statements)
|
2010-06-24 22:44:13 +00: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 03:16:25 +00:00
|
|
|
// asm statements)
|
2010-06-24 22:44:13 +00:00
|
|
|
Info.setAllowsMemory();
|
|
|
|
Info.setAllowsRegister();
|
|
|
|
break;
|
2010-10-21 03:16:25 +00:00
|
|
|
case 'R': // AIX TOC entry
|
2010-06-24 22:44:13 +00:00
|
|
|
case 'a': // Address operand that is an indexed or indirect from a
|
2010-10-21 03:16:25 +00: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-24 22:44:13 +00:00
|
|
|
case 't': // AND masks that can be performed by two rldic{l, r}
|
2010-10-21 03:16:25 +00:00
|
|
|
// instructions
|
|
|
|
case 'W': // Vector constant that does not require memory
|
|
|
|
case 'j': // Vector constant that is all zeros.
|
2010-06-24 22:44:13 +00:00
|
|
|
break;
|
|
|
|
// End FIXME.
|
2007-11-27 04:11:28 +00:00
|
|
|
}
|
2010-06-24 22:44:13 +00:00
|
|
|
return true;
|
2007-11-27 04:11:28 +00:00
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
std::string convertConstraint(const char *&Constraint) const override {
|
2014-03-02 18:24:18 +00:00
|
|
|
std::string R;
|
|
|
|
switch (*Constraint) {
|
|
|
|
case 'e':
|
|
|
|
case 'w':
|
|
|
|
// Two-character constraint; add "^" hint for later parsing.
|
|
|
|
R = std::string("^") + std::string(Constraint, 2);
|
|
|
|
Constraint++;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return TargetInfo::convertConstraint(Constraint);
|
|
|
|
}
|
|
|
|
return R;
|
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
const char *getClobbers() const override {
|
2008-08-20 23:11:40 +00:00
|
|
|
return "";
|
2007-11-27 04:11:28 +00:00
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
int getEHDataRegisterNumber(unsigned RegNo) const override {
|
2013-01-22 20:02:45 +00:00
|
|
|
if (RegNo == 0) return 3;
|
|
|
|
if (RegNo == 1) return 4;
|
|
|
|
return -1;
|
|
|
|
}
|
2015-03-11 23:46:32 +00:00
|
|
|
|
|
|
|
bool hasSjLjLowering() const override {
|
|
|
|
return true;
|
|
|
|
}
|
2015-06-09 18:05:33 +00:00
|
|
|
|
|
|
|
bool useFloat128ManglingForLongDouble() const override {
|
|
|
|
return LongDoubleWidth == 128 &&
|
|
|
|
LongDoubleFormat == &llvm::APFloat::PPCDoubleDouble &&
|
|
|
|
getTriple().isOSBinFormatELF();
|
|
|
|
}
|
2008-08-20 23:11:40 +00:00
|
|
|
};
|
2007-11-27 04:11:28 +00:00
|
|
|
|
2008-08-20 23:11:40 +00:00
|
|
|
const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
|
2015-08-07 05:14:44 +00:00
|
|
|
#define BUILTIN(ID, TYPE, ATTRS) \
|
|
|
|
{ #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },
|
|
|
|
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
|
|
|
|
{ #ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr },
|
2009-06-14 01:05:48 +00:00
|
|
|
#include "clang/Basic/BuiltinsPPC.def"
|
2008-08-20 23:11:40 +00:00
|
|
|
};
|
2009-05-03 13:42:53 +00:00
|
|
|
|
2014-11-18 22:36:15 +00:00
|
|
|
/// handleTargetFeatures - Perform initialization based on the user
|
2013-10-16 21:19:26 +00:00
|
|
|
/// configured set of features.
|
2013-10-16 21:26:26 +00:00
|
|
|
bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
|
2013-10-16 21:19:26 +00:00
|
|
|
DiagnosticsEngine &Diags) {
|
2015-08-26 08:21:55 +00:00
|
|
|
for (const auto &Feature : Features) {
|
|
|
|
if (Feature == "+vsx") {
|
2013-10-16 21:19:26 +00:00
|
|
|
HasVSX = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
} else if (Feature == "+bpermd") {
|
2015-04-09 23:58:16 +00:00
|
|
|
HasBPERMD = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
} else if (Feature == "+extdiv") {
|
2015-04-09 23:58:16 +00:00
|
|
|
HasExtDiv = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
} else if (Feature == "+power8-vector") {
|
2014-10-10 17:21:23 +00:00
|
|
|
HasP8Vector = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
} else if (Feature == "+crypto") {
|
2015-03-04 21:48:22 +00:00
|
|
|
HasP8Crypto = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
} else if (Feature == "+direct-move") {
|
2015-04-11 10:43:36 +00:00
|
|
|
HasDirectMove = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
} else if (Feature == "+qpx") {
|
2015-03-11 19:14:15 +00:00
|
|
|
HasQPX = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
} else if (Feature == "+htm") {
|
2015-03-25 19:41:41 +00:00
|
|
|
HasHTM = true;
|
|
|
|
}
|
2013-10-16 21:19:26 +00:00
|
|
|
// TODO: Finish this list and add an assert that we've handled them
|
|
|
|
// all.
|
|
|
|
}
|
2015-08-25 00:59:11 +00:00
|
|
|
|
2015-08-25 13:45:28 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2009-03-02 22:27:17 +00:00
|
|
|
/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
|
|
|
|
/// #defines that are not tied to a specific subtarget.
|
2009-03-20 15:52:06 +00:00
|
|
|
void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
|
2010-01-09 17:55:51 +00:00
|
|
|
MacroBuilder &Builder) const {
|
2009-03-02 22:27:17 +00:00
|
|
|
// Target identification.
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("__ppc__");
|
2013-06-25 11:13:47 +00:00
|
|
|
Builder.defineMacro("__PPC__");
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("_ARCH_PPC");
|
2010-02-16 18:14:57 +00:00
|
|
|
Builder.defineMacro("__powerpc__");
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("__POWERPC__");
|
2009-03-02 22:27:17 +00:00
|
|
|
if (PointerWidth == 64) {
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("_ARCH_PPC64");
|
2010-02-16 18:14:57 +00:00
|
|
|
Builder.defineMacro("__powerpc64__");
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("__ppc64__");
|
2013-06-25 11:13:47 +00:00
|
|
|
Builder.defineMacro("__PPC64__");
|
2009-03-02 22:27:17 +00:00
|
|
|
}
|
2009-05-03 13:42:53 +00:00
|
|
|
|
2009-03-02 22:27:17 +00:00
|
|
|
// Target properties.
|
2013-07-26 01:36:11 +00:00
|
|
|
if (getTriple().getArch() == llvm::Triple::ppc64le) {
|
|
|
|
Builder.defineMacro("_LITTLE_ENDIAN");
|
|
|
|
} else {
|
|
|
|
if (getTriple().getOS() != llvm::Triple::NetBSD &&
|
|
|
|
getTriple().getOS() != llvm::Triple::OpenBSD)
|
|
|
|
Builder.defineMacro("_BIG_ENDIAN");
|
|
|
|
}
|
2009-05-03 13:42:53 +00:00
|
|
|
|
2014-07-28 13:17:52 +00:00
|
|
|
// ABI options.
|
2015-03-11 19:14:15 +00:00
|
|
|
if (ABI == "elfv1" || ABI == "elfv1-qpx")
|
2014-07-28 13:17:52 +00:00
|
|
|
Builder.defineMacro("_CALL_ELF", "1");
|
|
|
|
if (ABI == "elfv2")
|
|
|
|
Builder.defineMacro("_CALL_ELF", "2");
|
|
|
|
|
2009-03-02 22:27:17 +00:00
|
|
|
// Subtarget options.
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("__NATURAL_ALIGNMENT__");
|
|
|
|
Builder.defineMacro("__REGISTER_PREFIX__", "");
|
2009-05-03 13:42:53 +00:00
|
|
|
|
2009-03-02 22:27:17 +00:00
|
|
|
// FIXME: Should be controlled by command line option.
|
2013-07-03 19:45:54 +00:00
|
|
|
if (LongDoubleWidth == 128)
|
|
|
|
Builder.defineMacro("__LONG_DOUBLE_128__");
|
2010-10-21 03:16:25 +00:00
|
|
|
|
2009-11-19 17:18:50 +00:00
|
|
|
if (Opts.AltiVec) {
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("__VEC__", "10206");
|
|
|
|
Builder.defineMacro("__ALTIVEC__");
|
2009-11-19 17:18:50 +00:00
|
|
|
}
|
2012-06-11 22:35:19 +00:00
|
|
|
|
|
|
|
// CPU identification.
|
2012-07-03 16:51:04 +00: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-01 20:23:10 +00:00
|
|
|
.Case("630", ArchDefineName | ArchDefinePpcgr)
|
2012-07-03 16:51:04 +00:00
|
|
|
.Case("7400", ArchDefineName | ArchDefinePpcgr)
|
|
|
|
.Case("7450", ArchDefineName | ArchDefinePpcgr)
|
|
|
|
.Case("750", ArchDefineName | ArchDefinePpcgr)
|
|
|
|
.Case("970", ArchDefineName | ArchDefinePwr4 | ArchDefinePpcgr
|
|
|
|
| ArchDefinePpcsq)
|
2013-02-01 05:53:33 +00:00
|
|
|
.Case("a2", ArchDefineA2)
|
|
|
|
.Case("a2q", ArchDefineName | ArchDefineA2 | ArchDefineA2q)
|
2013-02-01 20:23:10 +00: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
|
2014-06-26 13:34:10 +00:00
|
|
|
| ArchDefinePpcgr | ArchDefinePpcsq)
|
|
|
|
.Case("pwr8", ArchDefineName | ArchDefinePwr7 | ArchDefinePwr6x
|
|
|
|
| ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5
|
|
|
|
| ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
|
2013-02-01 20:23:10 +00:00
|
|
|
.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
|
2014-06-26 13:34:10 +00:00
|
|
|
| ArchDefinePpcgr | ArchDefinePpcsq)
|
|
|
|
.Case("power8", ArchDefinePwr8 | ArchDefinePwr7 | ArchDefinePwr6x
|
|
|
|
| ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5
|
|
|
|
| ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
|
2012-07-03 16:51:04 +00: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-11 22:35:19 +00:00
|
|
|
Builder.defineMacro("_ARCH_440");
|
2012-07-03 16:51:04 +00:00
|
|
|
if (defs & ArchDefine603)
|
|
|
|
Builder.defineMacro("_ARCH_603");
|
|
|
|
if (defs & ArchDefine604)
|
|
|
|
Builder.defineMacro("_ARCH_604");
|
2013-02-01 20:23:10 +00:00
|
|
|
if (defs & ArchDefinePwr4)
|
2012-07-03 16:51:04 +00:00
|
|
|
Builder.defineMacro("_ARCH_PWR4");
|
2013-02-01 20:23:10 +00:00
|
|
|
if (defs & ArchDefinePwr5)
|
2012-07-03 16:51:04 +00:00
|
|
|
Builder.defineMacro("_ARCH_PWR5");
|
2013-02-01 20:23:10 +00:00
|
|
|
if (defs & ArchDefinePwr5x)
|
|
|
|
Builder.defineMacro("_ARCH_PWR5X");
|
|
|
|
if (defs & ArchDefinePwr6)
|
2012-06-11 22:35:19 +00:00
|
|
|
Builder.defineMacro("_ARCH_PWR6");
|
2013-02-01 20:23:10 +00:00
|
|
|
if (defs & ArchDefinePwr6x)
|
|
|
|
Builder.defineMacro("_ARCH_PWR6X");
|
|
|
|
if (defs & ArchDefinePwr7)
|
|
|
|
Builder.defineMacro("_ARCH_PWR7");
|
2014-06-26 13:34:10 +00:00
|
|
|
if (defs & ArchDefinePwr8)
|
|
|
|
Builder.defineMacro("_ARCH_PWR8");
|
2013-02-01 05:53:33 +00: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-01 20:23:10 +00:00
|
|
|
|
2013-10-16 21:19:26 +00:00
|
|
|
if (HasVSX)
|
|
|
|
Builder.defineMacro("__VSX__");
|
2014-10-10 17:21:23 +00:00
|
|
|
if (HasP8Vector)
|
2014-10-10 15:09:43 +00:00
|
|
|
Builder.defineMacro("__POWER8_VECTOR__");
|
2015-03-04 21:48:22 +00:00
|
|
|
if (HasP8Crypto)
|
|
|
|
Builder.defineMacro("__CRYPTO__");
|
2015-03-25 19:41:41 +00:00
|
|
|
if (HasHTM)
|
|
|
|
Builder.defineMacro("__HTM__");
|
2015-10-01 13:39:49 +00: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");
|
|
|
|
if (PointerWidth == 64)
|
|
|
|
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
|
2013-10-16 21:19:26 +00:00
|
|
|
|
2013-02-01 20:23:10 +00: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 02:14:03 +00:00
|
|
|
}
|
|
|
|
|
2015-08-31 18:39:16 +00:00
|
|
|
// Handle explicit options being passed to the compiler here: if we've
|
|
|
|
// explicitly turned off vsx and turned on power8-vector or direct-move then
|
|
|
|
// go ahead and error since the customer has expressed a somewhat incompatible
|
|
|
|
// set of options.
|
|
|
|
static bool ppcUserFeaturesCheck(DiagnosticsEngine &Diags,
|
2015-10-09 18:39:55 +00:00
|
|
|
const std::vector<std::string> &FeaturesVec) {
|
2015-08-31 18:39:16 +00:00
|
|
|
|
|
|
|
if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "-vsx") !=
|
|
|
|
FeaturesVec.end()) {
|
|
|
|
if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "+power8-vector") !=
|
|
|
|
FeaturesVec.end()) {
|
|
|
|
Diags.Report(diag::err_opt_not_valid_with_opt) << "-mpower8-vector"
|
|
|
|
<< "-mno-vsx";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "+direct-move") !=
|
|
|
|
FeaturesVec.end()) {
|
|
|
|
Diags.Report(diag::err_opt_not_valid_with_opt) << "-mdirect-move"
|
|
|
|
<< "-mno-vsx";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-10-09 18:39:55 +00:00
|
|
|
bool PPCTargetInfo::initFeatureMap(
|
|
|
|
llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
|
|
|
|
const std::vector<std::string> &FeaturesVec) const {
|
2013-02-01 02:14:03 +00:00
|
|
|
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)
|
2014-06-26 13:34:10 +00:00
|
|
|
.Case("pwr8", true)
|
2013-02-01 02:14:03 +00:00
|
|
|
.Case("ppc64", true)
|
2013-07-26 01:36:11 +00:00
|
|
|
.Case("ppc64le", true)
|
2013-02-01 02:14:03 +00:00
|
|
|
.Default(false);
|
2013-02-01 18:44:19 +00:00
|
|
|
|
|
|
|
Features["qpx"] = (CPU == "a2q");
|
2015-03-04 21:48:22 +00:00
|
|
|
Features["crypto"] = llvm::StringSwitch<bool>(CPU)
|
|
|
|
.Case("ppc64le", true)
|
|
|
|
.Case("pwr8", true)
|
|
|
|
.Default(false);
|
|
|
|
Features["power8-vector"] = llvm::StringSwitch<bool>(CPU)
|
|
|
|
.Case("ppc64le", true)
|
|
|
|
.Case("pwr8", true)
|
|
|
|
.Default(false);
|
2015-04-09 23:58:16 +00:00
|
|
|
Features["bpermd"] = llvm::StringSwitch<bool>(CPU)
|
|
|
|
.Case("ppc64le", true)
|
|
|
|
.Case("pwr8", true)
|
|
|
|
.Case("pwr7", true)
|
|
|
|
.Default(false);
|
|
|
|
Features["extdiv"] = llvm::StringSwitch<bool>(CPU)
|
|
|
|
.Case("ppc64le", true)
|
|
|
|
.Case("pwr8", true)
|
|
|
|
.Case("pwr7", true)
|
|
|
|
.Default(false);
|
2015-04-11 10:43:36 +00:00
|
|
|
Features["direct-move"] = llvm::StringSwitch<bool>(CPU)
|
|
|
|
.Case("ppc64le", true)
|
|
|
|
.Case("pwr8", true)
|
|
|
|
.Default(false);
|
Add missing builtins to altivec.h for ABI compliance (vol. 3)
This patch corresponds to review:
http://reviews.llvm.org/D10972
Fix for the handling of dependent features that are enabled by default
on some CPU's (such as -mvsx, -mpower8-vector).
Also provides a number of new interfaces or fixes existing ones in
altivec.h.
Changed signatures to conform to ABI:
vector short vec_perm(vector signed short, vector signed short, vector unsigned char)
vector int vec_perm(vector signed int, vector signed int, vector unsigned char)
vector long long vec_perm(vector signed long long, vector signed long long, vector unsigned char)
vector signed char vec_sld(vector signed char, vector signed char, const int)
vector unsigned char vec_sld(vector unsigned char, vector unsigned char, const int)
vector bool char vec_sld(vector bool char, vector bool char, const int)
vector unsigned short vec_sld(vector unsigned short, vector unsigned short, const int)
vector signed short vec_sld(vector signed short, vector signed short, const int)
vector signed int vec_sld(vector signed int, vector signed int, const int)
vector unsigned int vec_sld(vector unsigned int, vector unsigned int, const int)
vector float vec_sld(vector float, vector float, const int)
vector signed char vec_splat(vector signed char, const int)
vector unsigned char vec_splat(vector unsigned char, const int)
vector bool char vec_splat(vector bool char, const int)
vector signed short vec_splat(vector signed short, const int)
vector unsigned short vec_splat(vector unsigned short, const int)
vector bool short vec_splat(vector bool short, const int)
vector pixel vec_splat(vector pixel, const int)
vector signed int vec_splat(vector signed int, const int)
vector unsigned int vec_splat(vector unsigned int, const int)
vector bool int vec_splat(vector bool int, const int)
vector float vec_splat(vector float, const int)
Added a VSX path to:
vector float vec_round(vector float)
Added interfaces:
vector signed char vec_eqv(vector signed char, vector signed char)
vector signed char vec_eqv(vector bool char, vector signed char)
vector signed char vec_eqv(vector signed char, vector bool char)
vector unsigned char vec_eqv(vector unsigned char, vector unsigned char)
vector unsigned char vec_eqv(vector bool char, vector unsigned char)
vector unsigned char vec_eqv(vector unsigned char, vector bool char)
vector signed short vec_eqv(vector signed short, vector signed short)
vector signed short vec_eqv(vector bool short, vector signed short)
vector signed short vec_eqv(vector signed short, vector bool short)
vector unsigned short vec_eqv(vector unsigned short, vector unsigned short)
vector unsigned short vec_eqv(vector bool short, vector unsigned short)
vector unsigned short vec_eqv(vector unsigned short, vector bool short)
vector signed int vec_eqv(vector signed int, vector signed int)
vector signed int vec_eqv(vector bool int, vector signed int)
vector signed int vec_eqv(vector signed int, vector bool int)
vector unsigned int vec_eqv(vector unsigned int, vector unsigned int)
vector unsigned int vec_eqv(vector bool int, vector unsigned int)
vector unsigned int vec_eqv(vector unsigned int, vector bool int)
vector signed long long vec_eqv(vector signed long long, vector signed long long)
vector signed long long vec_eqv(vector bool long long, vector signed long long)
vector signed long long vec_eqv(vector signed long long, vector bool long long)
vector unsigned long long vec_eqv(vector unsigned long long, vector unsigned long long)
vector unsigned long long vec_eqv(vector bool long long, vector unsigned long long)
vector unsigned long long vec_eqv(vector unsigned long long, vector bool long long)
vector float vec_eqv(vector float, vector float)
vector float vec_eqv(vector bool int, vector float)
vector float vec_eqv(vector float, vector bool int)
vector double vec_eqv(vector double, vector double)
vector double vec_eqv(vector bool long long, vector double)
vector double vec_eqv(vector double, vector bool long long)
vector bool long long vec_perm(vector bool long long, vector bool long long, vector unsigned char)
vector double vec_round(vector double)
vector double vec_splat(vector double, const int)
vector bool long long vec_splat(vector bool long long, const int)
vector signed long long vec_splat(vector signed long long, const int)
vector unsigned long long vec_splat(vector unsigned long long,
vector bool int vec_sld(vector bool int, vector bool int, const int)
vector bool short vec_sld(vector bool short, vector bool short, const int)
llvm-svn: 241904
2015-07-10 13:11:34 +00:00
|
|
|
Features["vsx"] = llvm::StringSwitch<bool>(CPU)
|
|
|
|
.Case("ppc64le", true)
|
|
|
|
.Case("pwr8", true)
|
|
|
|
.Case("pwr7", true)
|
|
|
|
.Default(false);
|
2015-08-28 02:13:58 +00:00
|
|
|
|
2015-08-31 18:39:16 +00:00
|
|
|
if (!ppcUserFeaturesCheck(Diags, FeaturesVec))
|
|
|
|
return false;
|
2015-08-28 22:32:01 +00:00
|
|
|
|
|
|
|
return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
|
2013-02-01 02:14:03 +00:00
|
|
|
}
|
|
|
|
|
2012-01-30 06:38:25 +00:00
|
|
|
bool PPCTargetInfo::hasFeature(StringRef Feature) const {
|
2014-11-02 14:56:41 +00:00
|
|
|
return llvm::StringSwitch<bool>(Feature)
|
|
|
|
.Case("powerpc", true)
|
|
|
|
.Case("vsx", HasVSX)
|
|
|
|
.Case("power8-vector", HasP8Vector)
|
2015-03-04 21:48:22 +00:00
|
|
|
.Case("crypto", HasP8Crypto)
|
2015-04-11 10:43:36 +00:00
|
|
|
.Case("direct-move", HasDirectMove)
|
2015-03-11 19:14:15 +00:00
|
|
|
.Case("qpx", HasQPX)
|
2015-03-25 19:41:41 +00:00
|
|
|
.Case("htm", HasHTM)
|
2015-04-09 23:58:16 +00:00
|
|
|
.Case("bpermd", HasBPERMD)
|
|
|
|
.Case("extdiv", HasExtDiv)
|
2014-11-02 14:56:41 +00:00
|
|
|
.Default(false);
|
2012-01-30 06:38:25 +00:00
|
|
|
}
|
2008-04-21 18:56:49 +00:00
|
|
|
|
Add missing builtins to altivec.h for ABI compliance (vol. 3)
This patch corresponds to review:
http://reviews.llvm.org/D10972
Fix for the handling of dependent features that are enabled by default
on some CPU's (such as -mvsx, -mpower8-vector).
Also provides a number of new interfaces or fixes existing ones in
altivec.h.
Changed signatures to conform to ABI:
vector short vec_perm(vector signed short, vector signed short, vector unsigned char)
vector int vec_perm(vector signed int, vector signed int, vector unsigned char)
vector long long vec_perm(vector signed long long, vector signed long long, vector unsigned char)
vector signed char vec_sld(vector signed char, vector signed char, const int)
vector unsigned char vec_sld(vector unsigned char, vector unsigned char, const int)
vector bool char vec_sld(vector bool char, vector bool char, const int)
vector unsigned short vec_sld(vector unsigned short, vector unsigned short, const int)
vector signed short vec_sld(vector signed short, vector signed short, const int)
vector signed int vec_sld(vector signed int, vector signed int, const int)
vector unsigned int vec_sld(vector unsigned int, vector unsigned int, const int)
vector float vec_sld(vector float, vector float, const int)
vector signed char vec_splat(vector signed char, const int)
vector unsigned char vec_splat(vector unsigned char, const int)
vector bool char vec_splat(vector bool char, const int)
vector signed short vec_splat(vector signed short, const int)
vector unsigned short vec_splat(vector unsigned short, const int)
vector bool short vec_splat(vector bool short, const int)
vector pixel vec_splat(vector pixel, const int)
vector signed int vec_splat(vector signed int, const int)
vector unsigned int vec_splat(vector unsigned int, const int)
vector bool int vec_splat(vector bool int, const int)
vector float vec_splat(vector float, const int)
Added a VSX path to:
vector float vec_round(vector float)
Added interfaces:
vector signed char vec_eqv(vector signed char, vector signed char)
vector signed char vec_eqv(vector bool char, vector signed char)
vector signed char vec_eqv(vector signed char, vector bool char)
vector unsigned char vec_eqv(vector unsigned char, vector unsigned char)
vector unsigned char vec_eqv(vector bool char, vector unsigned char)
vector unsigned char vec_eqv(vector unsigned char, vector bool char)
vector signed short vec_eqv(vector signed short, vector signed short)
vector signed short vec_eqv(vector bool short, vector signed short)
vector signed short vec_eqv(vector signed short, vector bool short)
vector unsigned short vec_eqv(vector unsigned short, vector unsigned short)
vector unsigned short vec_eqv(vector bool short, vector unsigned short)
vector unsigned short vec_eqv(vector unsigned short, vector bool short)
vector signed int vec_eqv(vector signed int, vector signed int)
vector signed int vec_eqv(vector bool int, vector signed int)
vector signed int vec_eqv(vector signed int, vector bool int)
vector unsigned int vec_eqv(vector unsigned int, vector unsigned int)
vector unsigned int vec_eqv(vector bool int, vector unsigned int)
vector unsigned int vec_eqv(vector unsigned int, vector bool int)
vector signed long long vec_eqv(vector signed long long, vector signed long long)
vector signed long long vec_eqv(vector bool long long, vector signed long long)
vector signed long long vec_eqv(vector signed long long, vector bool long long)
vector unsigned long long vec_eqv(vector unsigned long long, vector unsigned long long)
vector unsigned long long vec_eqv(vector bool long long, vector unsigned long long)
vector unsigned long long vec_eqv(vector unsigned long long, vector bool long long)
vector float vec_eqv(vector float, vector float)
vector float vec_eqv(vector bool int, vector float)
vector float vec_eqv(vector float, vector bool int)
vector double vec_eqv(vector double, vector double)
vector double vec_eqv(vector bool long long, vector double)
vector double vec_eqv(vector double, vector bool long long)
vector bool long long vec_perm(vector bool long long, vector bool long long, vector unsigned char)
vector double vec_round(vector double)
vector double vec_splat(vector double, const int)
vector bool long long vec_splat(vector bool long long, const int)
vector signed long long vec_splat(vector signed long long, const int)
vector unsigned long long vec_splat(vector unsigned long long,
vector bool int vec_sld(vector bool int, vector bool int, const int)
vector bool short vec_sld(vector bool short, vector bool short, const int)
llvm-svn: 241904
2015-07-10 13:11:34 +00:00
|
|
|
void PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
|
|
|
|
StringRef Name, bool Enabled) const {
|
2015-08-25 13:45:28 +00:00
|
|
|
// If we're enabling direct-move or power8-vector go ahead and enable vsx
|
|
|
|
// as well. Do the inverse if we're disabling vsx. We'll diagnose any user
|
|
|
|
// incompatible options.
|
|
|
|
if (Enabled) {
|
|
|
|
if (Name == "vsx") {
|
|
|
|
Features[Name] = true;
|
|
|
|
} else if (Name == "direct-move") {
|
|
|
|
Features[Name] = Features["vsx"] = true;
|
|
|
|
} else if (Name == "power8-vector") {
|
|
|
|
Features[Name] = Features["vsx"] = true;
|
|
|
|
} else {
|
|
|
|
Features[Name] = true;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (Name == "vsx") {
|
|
|
|
Features[Name] = Features["direct-move"] = Features["power8-vector"] =
|
|
|
|
false;
|
|
|
|
} else {
|
|
|
|
Features[Name] = false;
|
Add missing builtins to altivec.h for ABI compliance (vol. 3)
This patch corresponds to review:
http://reviews.llvm.org/D10972
Fix for the handling of dependent features that are enabled by default
on some CPU's (such as -mvsx, -mpower8-vector).
Also provides a number of new interfaces or fixes existing ones in
altivec.h.
Changed signatures to conform to ABI:
vector short vec_perm(vector signed short, vector signed short, vector unsigned char)
vector int vec_perm(vector signed int, vector signed int, vector unsigned char)
vector long long vec_perm(vector signed long long, vector signed long long, vector unsigned char)
vector signed char vec_sld(vector signed char, vector signed char, const int)
vector unsigned char vec_sld(vector unsigned char, vector unsigned char, const int)
vector bool char vec_sld(vector bool char, vector bool char, const int)
vector unsigned short vec_sld(vector unsigned short, vector unsigned short, const int)
vector signed short vec_sld(vector signed short, vector signed short, const int)
vector signed int vec_sld(vector signed int, vector signed int, const int)
vector unsigned int vec_sld(vector unsigned int, vector unsigned int, const int)
vector float vec_sld(vector float, vector float, const int)
vector signed char vec_splat(vector signed char, const int)
vector unsigned char vec_splat(vector unsigned char, const int)
vector bool char vec_splat(vector bool char, const int)
vector signed short vec_splat(vector signed short, const int)
vector unsigned short vec_splat(vector unsigned short, const int)
vector bool short vec_splat(vector bool short, const int)
vector pixel vec_splat(vector pixel, const int)
vector signed int vec_splat(vector signed int, const int)
vector unsigned int vec_splat(vector unsigned int, const int)
vector bool int vec_splat(vector bool int, const int)
vector float vec_splat(vector float, const int)
Added a VSX path to:
vector float vec_round(vector float)
Added interfaces:
vector signed char vec_eqv(vector signed char, vector signed char)
vector signed char vec_eqv(vector bool char, vector signed char)
vector signed char vec_eqv(vector signed char, vector bool char)
vector unsigned char vec_eqv(vector unsigned char, vector unsigned char)
vector unsigned char vec_eqv(vector bool char, vector unsigned char)
vector unsigned char vec_eqv(vector unsigned char, vector bool char)
vector signed short vec_eqv(vector signed short, vector signed short)
vector signed short vec_eqv(vector bool short, vector signed short)
vector signed short vec_eqv(vector signed short, vector bool short)
vector unsigned short vec_eqv(vector unsigned short, vector unsigned short)
vector unsigned short vec_eqv(vector bool short, vector unsigned short)
vector unsigned short vec_eqv(vector unsigned short, vector bool short)
vector signed int vec_eqv(vector signed int, vector signed int)
vector signed int vec_eqv(vector bool int, vector signed int)
vector signed int vec_eqv(vector signed int, vector bool int)
vector unsigned int vec_eqv(vector unsigned int, vector unsigned int)
vector unsigned int vec_eqv(vector bool int, vector unsigned int)
vector unsigned int vec_eqv(vector unsigned int, vector bool int)
vector signed long long vec_eqv(vector signed long long, vector signed long long)
vector signed long long vec_eqv(vector bool long long, vector signed long long)
vector signed long long vec_eqv(vector signed long long, vector bool long long)
vector unsigned long long vec_eqv(vector unsigned long long, vector unsigned long long)
vector unsigned long long vec_eqv(vector bool long long, vector unsigned long long)
vector unsigned long long vec_eqv(vector unsigned long long, vector bool long long)
vector float vec_eqv(vector float, vector float)
vector float vec_eqv(vector bool int, vector float)
vector float vec_eqv(vector float, vector bool int)
vector double vec_eqv(vector double, vector double)
vector double vec_eqv(vector bool long long, vector double)
vector double vec_eqv(vector double, vector bool long long)
vector bool long long vec_perm(vector bool long long, vector bool long long, vector unsigned char)
vector double vec_round(vector double)
vector double vec_splat(vector double, const int)
vector bool long long vec_splat(vector bool long long, const int)
vector signed long long vec_splat(vector signed long long, const int)
vector unsigned long long vec_splat(vector unsigned long long,
vector bool int vec_sld(vector bool int, vector bool int, const int)
vector bool short vec_sld(vector bool short, vector bool short, const int)
llvm-svn: 241904
2015-07-10 13:11:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-08-20 23:11:40 +00:00
|
|
|
const char * const PPCTargetInfo::GCCRegNames[] = {
|
2009-09-16 05:05:27 +00: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-20 23:11:40 +00:00
|
|
|
"mq", "lr", "ctr", "ap",
|
2009-09-16 05:05:27 +00:00
|
|
|
"cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
|
2008-08-20 23:11:40 +00:00
|
|
|
"xer",
|
2009-09-16 05:05:27 +00: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-20 23:11:40 +00:00
|
|
|
"vrsave", "vscr",
|
|
|
|
"spe_acc", "spefscr",
|
|
|
|
"sfp"
|
|
|
|
};
|
2007-01-29 05:24:35 +00:00
|
|
|
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<const char*> PPCTargetInfo::getGCCRegNames() const {
|
|
|
|
return llvm::makeArrayRef(GCCRegNames);
|
2008-08-20 23:11:40 +00:00
|
|
|
}
|
2006-10-14 07:39:34 +00:00
|
|
|
|
2008-08-20 23:11:40 +00: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 07:03:19 +00: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-17 21:15:00 +00:00
|
|
|
{ { "fr10" }, "f10" },
|
2009-09-17 07:03:19 +00: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-20 23:11:40 +00:00
|
|
|
};
|
|
|
|
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<TargetInfo::GCCRegAlias> PPCTargetInfo::getGCCRegAliases() const {
|
|
|
|
return llvm::makeArrayRef(GCCRegAliases);
|
2008-08-20 23:11:40 +00:00
|
|
|
}
|
2006-10-14 07:50:21 +00:00
|
|
|
|
2008-08-20 23:11:40 +00:00
|
|
|
class PPC32TargetInfo : public PPCTargetInfo {
|
2006-10-14 07:39:34 +00:00
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
PPC32TargetInfo(const llvm::Triple &Triple) : PPCTargetInfo(Triple) {
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = "E-m:e-p:32:32-i64:64-n32";
|
2010-02-16 18:14:57 +00:00
|
|
|
|
2011-07-04 21:57:55 +00:00
|
|
|
switch (getTriple().getOS()) {
|
2012-01-31 02:07:33 +00:00
|
|
|
case llvm::Triple::Linux:
|
2011-07-04 21:57:55 +00:00
|
|
|
case llvm::Triple::FreeBSD:
|
|
|
|
case llvm::Triple::NetBSD:
|
2011-07-05 14:54:41 +00:00
|
|
|
SizeType = UnsignedInt;
|
2012-03-02 20:54:36 +00:00
|
|
|
PtrDiffType = SignedInt;
|
|
|
|
IntPtrType = SignedInt;
|
2011-07-05 14:54:41 +00:00
|
|
|
break;
|
2011-07-04 23:11:58 +00:00
|
|
|
default:
|
2011-07-05 14:54:41 +00:00
|
|
|
break;
|
2011-07-04 21:57:55 +00:00
|
|
|
}
|
2012-03-13 16:53:54 +00:00
|
|
|
|
2012-03-13 19:20:17 +00:00
|
|
|
if (getTriple().getOS() == llvm::Triple::FreeBSD) {
|
|
|
|
LongDoubleWidth = LongDoubleAlign = 64;
|
2012-03-13 16:53:54 +00:00
|
|
|
LongDoubleFormat = &llvm::APFloat::IEEEdouble;
|
2012-03-13 19:20:17 +00:00
|
|
|
}
|
2012-11-17 17:30:55 +00:00
|
|
|
|
|
|
|
// PPC32 supports atomics up to 4 bytes.
|
|
|
|
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32;
|
2011-01-06 08:27:10 +00:00
|
|
|
}
|
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
BuiltinVaListKind getBuiltinVaListKind() const override {
|
2011-01-06 08:27:10 +00:00
|
|
|
// This is the ELF definition, and is overridden by the Darwin sub-target
|
2012-06-16 03:34:49 +00:00
|
|
|
return TargetInfo::PowerABIBuiltinVaList;
|
2008-08-21 00:13:15 +00:00
|
|
|
}
|
2006-10-14 07:39:34 +00:00
|
|
|
};
|
|
|
|
|
2013-07-26 01:36:11 +00:00
|
|
|
// Note: ABI differences may eventually require us to have a separate
|
|
|
|
// TargetInfo for little endian.
|
2008-08-20 23:11:40 +00:00
|
|
|
class PPC64TargetInfo : public PPCTargetInfo {
|
2006-10-14 07:39:34 +00:00
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
PPC64TargetInfo(const llvm::Triple &Triple) : PPCTargetInfo(Triple) {
|
2008-05-09 06:17:04 +00:00
|
|
|
LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
|
2009-07-01 03:36:11 +00:00
|
|
|
IntMaxType = SignedLong;
|
|
|
|
Int64Type = SignedLong;
|
2012-03-13 16:53:54 +00:00
|
|
|
|
2014-10-15 19:47:15 +00:00
|
|
|
if ((Triple.getArch() == llvm::Triple::ppc64le)) {
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = "e-m:e-i64:64-n32:64";
|
2014-10-15 19:47:15 +00:00
|
|
|
ABI = "elfv2";
|
|
|
|
} else {
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = "E-m:e-i64:64-n32:64";
|
2014-10-15 19:47:15 +00:00
|
|
|
ABI = "elfv1";
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (getTriple().getOS()) {
|
|
|
|
case llvm::Triple::FreeBSD:
|
2012-03-13 19:20:17 +00:00
|
|
|
LongDoubleWidth = LongDoubleAlign = 64;
|
2012-03-13 16:53:54 +00:00
|
|
|
LongDoubleFormat = &llvm::APFloat::IEEEdouble;
|
2014-10-15 19:47:15 +00:00
|
|
|
break;
|
2014-10-15 19:52:03 +00:00
|
|
|
case llvm::Triple::NetBSD:
|
|
|
|
IntMaxType = SignedLongLong;
|
|
|
|
Int64Type = SignedLongLong;
|
|
|
|
break;
|
2014-10-15 19:47:15 +00:00
|
|
|
default:
|
|
|
|
break;
|
2014-07-28 13:17:52 +00:00
|
|
|
}
|
2012-11-17 17:30:55 +00:00
|
|
|
|
|
|
|
// PPC64 supports atomics up to 8 bytes.
|
|
|
|
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
|
2008-05-09 06:17:04 +00:00
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
BuiltinVaListKind getBuiltinVaListKind() const override {
|
2012-06-16 03:34:49 +00:00
|
|
|
return TargetInfo::CharPtrBuiltinVaList;
|
2011-01-06 08:27:10 +00:00
|
|
|
}
|
2015-07-10 18:25:52 +00:00
|
|
|
// PPC64 Linux-specific ABI options.
|
2014-07-28 13:17:52 +00:00
|
|
|
bool setABI(const std::string &Name) override {
|
2015-03-11 19:14:15 +00:00
|
|
|
if (Name == "elfv1" || Name == "elfv1-qpx" || Name == "elfv2") {
|
2014-07-28 13:17:52 +00:00
|
|
|
ABI = Name;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2008-08-20 23:11:40 +00:00
|
|
|
};
|
|
|
|
|
2011-01-06 08:27:10 +00:00
|
|
|
class DarwinPPC32TargetInfo :
|
|
|
|
public DarwinTargetInfo<PPC32TargetInfo> {
|
2010-05-30 00:07:30 +00:00
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
DarwinPPC32TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: DarwinTargetInfo<PPC32TargetInfo>(Triple) {
|
2010-05-30 00:07:30 +00:00
|
|
|
HasAlignMac68kSupport = true;
|
2011-01-06 08:27:10 +00:00
|
|
|
BoolWidth = BoolAlign = 32; //XXX support -mone-byte-bool?
|
2014-11-18 22:36:15 +00:00
|
|
|
PtrDiffType = SignedInt; // for http://llvm.org/bugs/show_bug.cgi?id=15726
|
2012-01-17 22:40:00 +00:00
|
|
|
LongLongAlign = 32;
|
2011-12-21 04:25:47 +00:00
|
|
|
SuitableAlign = 128;
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = "E-m:o-p:32:32-f64:32:64-n32";
|
2011-01-06 08:27:10 +00:00
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
BuiltinVaListKind getBuiltinVaListKind() const override {
|
2012-06-16 03:34:49 +00:00
|
|
|
return TargetInfo::CharPtrBuiltinVaList;
|
2010-05-30 00:07:30 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class DarwinPPC64TargetInfo :
|
|
|
|
public DarwinTargetInfo<PPC64TargetInfo> {
|
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
DarwinPPC64TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: DarwinTargetInfo<PPC64TargetInfo>(Triple) {
|
2010-05-30 00:07:30 +00:00
|
|
|
HasAlignMac68kSupport = true;
|
2011-12-21 04:25:47 +00:00
|
|
|
SuitableAlign = 128;
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = "E-m:o-i64:64-n32:64";
|
2010-05-30 00:07:30 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-09-18 21:26:24 +00:00
|
|
|
static const unsigned NVPTXAddrSpaceMap[] = {
|
|
|
|
1, // opencl_global
|
|
|
|
3, // opencl_local
|
|
|
|
4, // opencl_constant
|
2014-11-26 14:10:06 +00:00
|
|
|
// FIXME: generic has to be added to the target
|
2015-09-18 21:26:24 +00:00
|
|
|
0, // opencl_generic
|
|
|
|
1, // cuda_device
|
|
|
|
4, // cuda_constant
|
|
|
|
3, // cuda_shared
|
|
|
|
};
|
|
|
|
|
|
|
|
class NVPTXTargetInfo : public TargetInfo {
|
|
|
|
static const char *const GCCRegNames[];
|
|
|
|
static const Builtin::Info BuiltinInfo[];
|
2014-12-03 21:53:36 +00:00
|
|
|
|
|
|
|
// The GPU profiles supported by the NVPTX backend
|
|
|
|
enum GPUKind {
|
|
|
|
GK_NONE,
|
|
|
|
GK_SM20,
|
|
|
|
GK_SM21,
|
|
|
|
GK_SM30,
|
|
|
|
GK_SM35,
|
2015-03-31 17:03:16 +00:00
|
|
|
GK_SM37,
|
2014-12-03 21:53:36 +00:00
|
|
|
} GPU;
|
|
|
|
|
2015-09-18 21:26:24 +00:00
|
|
|
public:
|
|
|
|
NVPTXTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
|
|
|
|
BigEndian = false;
|
|
|
|
TLSSupported = false;
|
|
|
|
LongWidth = LongAlign = 64;
|
|
|
|
AddrSpaceMap = &NVPTXAddrSpaceMap;
|
|
|
|
UseAddrSpaceMapMangling = true;
|
|
|
|
// Define available target features
|
|
|
|
// These must be defined in sorted order!
|
|
|
|
NoAsmVariants = true;
|
|
|
|
// Set the default GPU to sm20
|
|
|
|
GPU = GK_SM20;
|
|
|
|
}
|
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
|
|
|
Builder.defineMacro("__PTX__");
|
|
|
|
Builder.defineMacro("__NVPTX__");
|
|
|
|
if (Opts.CUDAIsDevice) {
|
|
|
|
// Set __CUDA_ARCH__ for the GPU specified.
|
|
|
|
std::string CUDAArchCode;
|
|
|
|
switch (GPU) {
|
|
|
|
case GK_SM20:
|
|
|
|
CUDAArchCode = "200";
|
|
|
|
break;
|
|
|
|
case GK_SM21:
|
|
|
|
CUDAArchCode = "210";
|
|
|
|
break;
|
|
|
|
case GK_SM30:
|
|
|
|
CUDAArchCode = "300";
|
|
|
|
break;
|
|
|
|
case GK_SM35:
|
|
|
|
CUDAArchCode = "350";
|
|
|
|
break;
|
|
|
|
case GK_SM37:
|
|
|
|
CUDAArchCode = "370";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
llvm_unreachable("Unhandled target CPU");
|
2014-12-03 21:53:36 +00:00
|
|
|
}
|
2015-09-18 21:26:24 +00:00
|
|
|
Builder.defineMacro("__CUDA_ARCH__", CUDAArchCode);
|
2011-04-20 19:34:15 +00:00
|
|
|
}
|
2015-09-18 21:26:24 +00:00
|
|
|
}
|
2015-10-19 04:51:35 +00:00
|
|
|
ArrayRef<Builtin::Info> getTargetBuiltins() const override {
|
|
|
|
return llvm::makeArrayRef(BuiltinInfo,
|
|
|
|
clang::NVPTX::LastTSBuiltin - Builtin::FirstTSBuiltin);
|
2015-09-18 21:26:24 +00:00
|
|
|
}
|
|
|
|
bool hasFeature(StringRef Feature) const override {
|
|
|
|
return Feature == "ptx" || Feature == "nvptx";
|
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<const char *> getGCCRegNames() const override;
|
|
|
|
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
|
2015-09-18 21:26:24 +00:00
|
|
|
// No aliases.
|
2015-10-19 03:52:27 +00:00
|
|
|
return None;
|
2015-09-18 21:26:24 +00:00
|
|
|
}
|
|
|
|
bool validateAsmConstraint(const char *&Name,
|
|
|
|
TargetInfo::ConstraintInfo &Info) const override {
|
|
|
|
switch (*Name) {
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
case 'c':
|
|
|
|
case 'h':
|
|
|
|
case 'r':
|
|
|
|
case 'l':
|
|
|
|
case 'f':
|
|
|
|
case 'd':
|
|
|
|
Info.setAllowsRegister();
|
|
|
|
return true;
|
2012-05-24 17:43:12 +00:00
|
|
|
}
|
2015-09-18 21:26:24 +00:00
|
|
|
}
|
|
|
|
const char *getClobbers() const override {
|
|
|
|
// FIXME: Is this really right?
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
BuiltinVaListKind getBuiltinVaListKind() const override {
|
|
|
|
// FIXME: implement
|
|
|
|
return TargetInfo::CharPtrBuiltinVaList;
|
|
|
|
}
|
|
|
|
bool setCPU(const std::string &Name) override {
|
|
|
|
GPU = llvm::StringSwitch<GPUKind>(Name)
|
|
|
|
.Case("sm_20", GK_SM20)
|
|
|
|
.Case("sm_21", GK_SM21)
|
|
|
|
.Case("sm_30", GK_SM30)
|
|
|
|
.Case("sm_35", GK_SM35)
|
|
|
|
.Case("sm_37", GK_SM37)
|
|
|
|
.Default(GK_NONE);
|
2011-04-20 19:34:15 +00:00
|
|
|
|
2015-09-18 21:26:24 +00:00
|
|
|
return GPU != GK_NONE;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const Builtin::Info NVPTXTargetInfo::BuiltinInfo[] = {
|
|
|
|
#define BUILTIN(ID, TYPE, ATTRS) \
|
|
|
|
{ #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },
|
|
|
|
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
|
|
|
|
{ #ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr },
|
2012-05-24 17:43:12 +00:00
|
|
|
#include "clang/Basic/BuiltinsNVPTX.def"
|
2015-09-18 21:26:24 +00:00
|
|
|
};
|
2011-04-20 19:34:15 +00:00
|
|
|
|
2015-09-18 21:26:24 +00:00
|
|
|
const char *const NVPTXTargetInfo::GCCRegNames[] = {"r0"};
|
2011-04-20 19:34:15 +00:00
|
|
|
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<const char *> NVPTXTargetInfo::getGCCRegNames() const {
|
|
|
|
return llvm::makeArrayRef(GCCRegNames);
|
2015-09-18 21:26:24 +00:00
|
|
|
}
|
2011-04-20 19:34:15 +00:00
|
|
|
|
2015-09-18 21:26:24 +00:00
|
|
|
class NVPTX32TargetInfo : public NVPTXTargetInfo {
|
|
|
|
public:
|
|
|
|
NVPTX32TargetInfo(const llvm::Triple &Triple) : NVPTXTargetInfo(Triple) {
|
2015-09-28 22:54:08 +00:00
|
|
|
LongWidth = LongAlign = 32;
|
2015-09-18 21:26:24 +00:00
|
|
|
PointerWidth = PointerAlign = 32;
|
|
|
|
SizeType = TargetInfo::UnsignedInt;
|
|
|
|
PtrDiffType = TargetInfo::SignedInt;
|
|
|
|
IntPtrType = TargetInfo::SignedInt;
|
|
|
|
DataLayoutString = "e-p:32:32-i64:64-v16:16-v32:32-n16:32:64";
|
|
|
|
}
|
|
|
|
};
|
2012-05-20 23:28:41 +00:00
|
|
|
|
2015-09-18 21:26:24 +00:00
|
|
|
class NVPTX64TargetInfo : public NVPTXTargetInfo {
|
|
|
|
public:
|
|
|
|
NVPTX64TargetInfo(const llvm::Triple &Triple) : NVPTXTargetInfo(Triple) {
|
|
|
|
PointerWidth = PointerAlign = 64;
|
|
|
|
SizeType = TargetInfo::UnsignedLong;
|
|
|
|
PtrDiffType = TargetInfo::SignedLong;
|
|
|
|
IntPtrType = TargetInfo::SignedLong;
|
|
|
|
DataLayoutString = "e-i64:64-v16:16-v32:32-n16:32:64";
|
|
|
|
}
|
|
|
|
};
|
2012-10-12 23:32:00 +00:00
|
|
|
|
2015-06-19 17:54:10 +00:00
|
|
|
static const unsigned AMDGPUAddrSpaceMap[] = {
|
2012-10-12 23:32:00 +00:00
|
|
|
1, // opencl_global
|
|
|
|
3, // opencl_local
|
|
|
|
2, // opencl_constant
|
2014-12-01 16:46:03 +00:00
|
|
|
4, // opencl_generic
|
2012-10-12 23:32:00 +00:00
|
|
|
1, // cuda_device
|
|
|
|
2, // cuda_constant
|
|
|
|
3 // cuda_shared
|
|
|
|
};
|
|
|
|
|
2014-08-21 13:58:40 +00:00
|
|
|
// If you edit the description strings, make sure you update
|
|
|
|
// getPointerWidthV().
|
|
|
|
|
2015-10-18 05:29:26 +00:00
|
|
|
static const char *const DataLayoutStringR600 =
|
2014-01-03 18:13:17 +00: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-04 17:40:53 +00:00
|
|
|
|
2015-10-18 05:29:26 +00:00
|
|
|
static const char *const DataLayoutStringR600DoubleOps =
|
2014-01-03 18:13:17 +00: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-04 17:40:53 +00:00
|
|
|
|
2015-10-18 05:29:26 +00:00
|
|
|
static const char *const DataLayoutStringSI =
|
2014-05-22 18:33:55 +00:00
|
|
|
"e-p:32:32-p1:64:64-p2:64:64-p3:32:32-p4:64:64-p5:32:32-p24:64:64"
|
2014-01-03 18:13:17 +00:00
|
|
|
"-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-04 17:40:53 +00:00
|
|
|
|
2015-06-19 17:54:10 +00:00
|
|
|
class AMDGPUTargetInfo : public TargetInfo {
|
2014-06-24 20:45:01 +00:00
|
|
|
static const Builtin::Info BuiltinInfo[];
|
2015-04-14 14:36:56 +00:00
|
|
|
static const char * const GCCRegNames[];
|
2014-06-24 20:45:01 +00:00
|
|
|
|
2015-06-19 17:54:10 +00:00
|
|
|
/// \brief The GPU profiles supported by the AMDGPU target.
|
2013-03-04 17:40:53 +00:00
|
|
|
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-29 16:38:29 +00:00
|
|
|
GK_SOUTHERN_ISLANDS,
|
2015-06-18 19:14:15 +00:00
|
|
|
GK_SEA_ISLANDS,
|
|
|
|
GK_VOLCANIC_ISLANDS
|
2013-03-04 17:40:53 +00:00
|
|
|
} GPU;
|
|
|
|
|
2015-05-04 19:53:36 +00:00
|
|
|
bool hasFP64:1;
|
|
|
|
bool hasFMAF:1;
|
|
|
|
bool hasLDEXPF:1;
|
2015-05-01 17:38:13 +00:00
|
|
|
|
2012-10-12 23:32:00 +00:00
|
|
|
public:
|
2015-06-19 17:54:10 +00:00
|
|
|
AMDGPUTargetInfo(const llvm::Triple &Triple)
|
|
|
|
: TargetInfo(Triple) {
|
2015-01-28 15:38:44 +00:00
|
|
|
|
|
|
|
if (Triple.getArch() == llvm::Triple::amdgcn) {
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = DataLayoutStringSI;
|
2015-01-28 15:38:44 +00:00
|
|
|
GPU = GK_SOUTHERN_ISLANDS;
|
2015-05-01 17:38:13 +00:00
|
|
|
hasFP64 = true;
|
2015-05-04 19:53:36 +00:00
|
|
|
hasFMAF = true;
|
|
|
|
hasLDEXPF = true;
|
2015-01-28 15:38:44 +00:00
|
|
|
} else {
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = DataLayoutStringR600;
|
2015-01-28 15:38:44 +00:00
|
|
|
GPU = GK_R600;
|
2015-05-01 17:38:13 +00:00
|
|
|
hasFP64 = false;
|
2015-05-04 19:53:36 +00:00
|
|
|
hasFMAF = false;
|
|
|
|
hasLDEXPF = false;
|
2015-01-28 15:38:44 +00:00
|
|
|
}
|
2015-06-19 17:54:10 +00:00
|
|
|
AddrSpaceMap = &AMDGPUAddrSpaceMap;
|
2013-09-13 12:04:22 +00:00
|
|
|
UseAddrSpaceMapMangling = true;
|
2012-10-12 23:32:00 +00:00
|
|
|
}
|
|
|
|
|
2014-08-21 13:58:40 +00:00
|
|
|
uint64_t getPointerWidthV(unsigned AddrSpace) const override {
|
|
|
|
if (GPU <= GK_CAYMAN)
|
|
|
|
return 32;
|
|
|
|
|
|
|
|
switch(AddrSpace) {
|
|
|
|
default:
|
|
|
|
return 64;
|
|
|
|
case 0:
|
|
|
|
case 3:
|
|
|
|
case 5:
|
|
|
|
return 32;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
const char * getClobbers() const override {
|
2012-10-12 23:32:00 +00:00
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<const char *> getGCCRegNames() const override;
|
2012-10-12 23:32:00 +00:00
|
|
|
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
|
|
|
|
return None;
|
2012-10-12 23:32:00 +00:00
|
|
|
}
|
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
bool validateAsmConstraint(const char *&Name,
|
2015-11-19 22:11:58 +00:00
|
|
|
TargetInfo::ConstraintInfo &Info) const override {
|
|
|
|
switch (*Name) {
|
|
|
|
default: break;
|
|
|
|
case 'v': // vgpr
|
|
|
|
case 's': // sgpr
|
|
|
|
Info.setAllowsRegister();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
2012-10-12 23:32:00 +00:00
|
|
|
}
|
|
|
|
|
2015-10-19 04:51:35 +00:00
|
|
|
ArrayRef<Builtin::Info> getTargetBuiltins() const override {
|
|
|
|
return llvm::makeArrayRef(BuiltinInfo,
|
|
|
|
clang::AMDGPU::LastTSBuiltin - Builtin::FirstTSBuiltin);
|
2012-10-12 23:32:00 +00:00
|
|
|
}
|
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
2012-10-12 23:32:00 +00:00
|
|
|
Builder.defineMacro("__R600__");
|
2015-05-04 19:53:36 +00:00
|
|
|
if (hasFMAF)
|
|
|
|
Builder.defineMacro("__HAS_FMAF__");
|
|
|
|
if (hasLDEXPF)
|
|
|
|
Builder.defineMacro("__HAS_LDEXPF__");
|
2015-07-17 13:16:52 +00:00
|
|
|
if (hasFP64 && Opts.OpenCL)
|
2015-02-27 15:10:19 +00:00
|
|
|
Builder.defineMacro("cl_khr_fp64");
|
2015-07-17 13:16:52 +00:00
|
|
|
if (Opts.OpenCL) {
|
|
|
|
if (GPU >= GK_NORTHERN_ISLANDS) {
|
|
|
|
Builder.defineMacro("cl_khr_byte_addressable_store");
|
|
|
|
Builder.defineMacro("cl_khr_global_int32_base_atomics");
|
|
|
|
Builder.defineMacro("cl_khr_global_int32_extended_atomics");
|
|
|
|
Builder.defineMacro("cl_khr_local_int32_base_atomics");
|
|
|
|
Builder.defineMacro("cl_khr_local_int32_extended_atomics");
|
|
|
|
}
|
2015-05-01 17:38:13 +00:00
|
|
|
}
|
2012-10-12 23:32:00 +00:00
|
|
|
}
|
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
BuiltinVaListKind getBuiltinVaListKind() const override {
|
2012-10-12 23:32:00 +00:00
|
|
|
return TargetInfo::CharPtrBuiltinVaList;
|
|
|
|
}
|
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
bool setCPU(const std::string &Name) override {
|
2013-03-04 17:40:53 +00:00
|
|
|
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-01 20:56:49 +00:00
|
|
|
.Case("tahiti", GK_SOUTHERN_ISLANDS)
|
2013-03-04 17:40:53 +00:00
|
|
|
.Case("pitcairn", GK_SOUTHERN_ISLANDS)
|
|
|
|
.Case("verde", GK_SOUTHERN_ISLANDS)
|
|
|
|
.Case("oland", GK_SOUTHERN_ISLANDS)
|
2014-08-21 13:58:38 +00:00
|
|
|
.Case("hainan", GK_SOUTHERN_ISLANDS)
|
2013-10-29 16:38:29 +00:00
|
|
|
.Case("bonaire", GK_SEA_ISLANDS)
|
|
|
|
.Case("kabini", GK_SEA_ISLANDS)
|
|
|
|
.Case("kaveri", GK_SEA_ISLANDS)
|
2013-11-14 23:45:53 +00:00
|
|
|
.Case("hawaii", GK_SEA_ISLANDS)
|
2014-07-26 01:05:20 +00:00
|
|
|
.Case("mullins", GK_SEA_ISLANDS)
|
2015-06-18 19:14:15 +00:00
|
|
|
.Case("tonga", GK_VOLCANIC_ISLANDS)
|
|
|
|
.Case("iceland", GK_VOLCANIC_ISLANDS)
|
|
|
|
.Case("carrizo", GK_VOLCANIC_ISLANDS)
|
2013-03-04 17:40:53 +00: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:
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = DataLayoutStringR600;
|
2015-05-01 17:38:13 +00:00
|
|
|
hasFP64 = false;
|
2015-05-04 19:53:36 +00:00
|
|
|
hasFMAF = false;
|
|
|
|
hasLDEXPF = false;
|
2013-03-04 17:40:53 +00:00
|
|
|
break;
|
|
|
|
case GK_R600_DOUBLE_OPS:
|
|
|
|
case GK_R700_DOUBLE_OPS:
|
|
|
|
case GK_EVERGREEN_DOUBLE_OPS:
|
|
|
|
case GK_CAYMAN:
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = DataLayoutStringR600DoubleOps;
|
2015-05-01 17:38:13 +00:00
|
|
|
hasFP64 = true;
|
2015-05-04 19:53:36 +00:00
|
|
|
hasFMAF = true;
|
|
|
|
hasLDEXPF = false;
|
2013-03-04 17:40:53 +00:00
|
|
|
break;
|
|
|
|
case GK_SOUTHERN_ISLANDS:
|
2013-10-29 16:38:29 +00:00
|
|
|
case GK_SEA_ISLANDS:
|
2015-06-18 21:13:29 +00:00
|
|
|
case GK_VOLCANIC_ISLANDS:
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = DataLayoutStringSI;
|
2015-05-01 17:38:13 +00:00
|
|
|
hasFP64 = true;
|
2015-05-04 19:53:36 +00:00
|
|
|
hasFMAF = true;
|
|
|
|
hasLDEXPF = true;
|
2013-03-04 17:40:53 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2012-10-12 23:32:00 +00:00
|
|
|
};
|
|
|
|
|
2015-06-19 17:54:10 +00:00
|
|
|
const Builtin::Info AMDGPUTargetInfo::BuiltinInfo[] = {
|
2014-06-24 20:45:01 +00:00
|
|
|
#define BUILTIN(ID, TYPE, ATTRS) \
|
2015-08-07 05:14:44 +00:00
|
|
|
{ #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },
|
2015-06-19 17:54:10 +00:00
|
|
|
#include "clang/Basic/BuiltinsAMDGPU.def"
|
2014-06-24 20:45:01 +00:00
|
|
|
};
|
2015-06-19 17:54:10 +00:00
|
|
|
const char * const AMDGPUTargetInfo::GCCRegNames[] = {
|
2015-04-14 14:36:56 +00: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",
|
|
|
|
"v32", "v33", "v34", "v35", "v36", "v37", "v38", "v39",
|
|
|
|
"v40", "v41", "v42", "v43", "v44", "v45", "v46", "v47",
|
|
|
|
"v48", "v49", "v50", "v51", "v52", "v53", "v54", "v55",
|
|
|
|
"v56", "v57", "v58", "v59", "v60", "v61", "v62", "v63",
|
|
|
|
"v64", "v65", "v66", "v67", "v68", "v69", "v70", "v71",
|
|
|
|
"v72", "v73", "v74", "v75", "v76", "v77", "v78", "v79",
|
|
|
|
"v80", "v81", "v82", "v83", "v84", "v85", "v86", "v87",
|
|
|
|
"v88", "v89", "v90", "v91", "v92", "v93", "v94", "v95",
|
|
|
|
"v96", "v97", "v98", "v99", "v100", "v101", "v102", "v103",
|
|
|
|
"v104", "v105", "v106", "v107", "v108", "v109", "v110", "v111",
|
|
|
|
"v112", "v113", "v114", "v115", "v116", "v117", "v118", "v119",
|
|
|
|
"v120", "v121", "v122", "v123", "v124", "v125", "v126", "v127",
|
|
|
|
"v128", "v129", "v130", "v131", "v132", "v133", "v134", "v135",
|
|
|
|
"v136", "v137", "v138", "v139", "v140", "v141", "v142", "v143",
|
|
|
|
"v144", "v145", "v146", "v147", "v148", "v149", "v150", "v151",
|
|
|
|
"v152", "v153", "v154", "v155", "v156", "v157", "v158", "v159",
|
|
|
|
"v160", "v161", "v162", "v163", "v164", "v165", "v166", "v167",
|
|
|
|
"v168", "v169", "v170", "v171", "v172", "v173", "v174", "v175",
|
|
|
|
"v176", "v177", "v178", "v179", "v180", "v181", "v182", "v183",
|
|
|
|
"v184", "v185", "v186", "v187", "v188", "v189", "v190", "v191",
|
|
|
|
"v192", "v193", "v194", "v195", "v196", "v197", "v198", "v199",
|
|
|
|
"v200", "v201", "v202", "v203", "v204", "v205", "v206", "v207",
|
|
|
|
"v208", "v209", "v210", "v211", "v212", "v213", "v214", "v215",
|
|
|
|
"v216", "v217", "v218", "v219", "v220", "v221", "v222", "v223",
|
|
|
|
"v224", "v225", "v226", "v227", "v228", "v229", "v230", "v231",
|
|
|
|
"v232", "v233", "v234", "v235", "v236", "v237", "v238", "v239",
|
|
|
|
"v240", "v241", "v242", "v243", "v244", "v245", "v246", "v247",
|
|
|
|
"v248", "v249", "v250", "v251", "v252", "v253", "v254", "v255",
|
|
|
|
"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",
|
|
|
|
"s32", "s33", "s34", "s35", "s36", "s37", "s38", "s39",
|
|
|
|
"s40", "s41", "s42", "s43", "s44", "s45", "s46", "s47",
|
|
|
|
"s48", "s49", "s50", "s51", "s52", "s53", "s54", "s55",
|
|
|
|
"s56", "s57", "s58", "s59", "s60", "s61", "s62", "s63",
|
|
|
|
"s64", "s65", "s66", "s67", "s68", "s69", "s70", "s71",
|
|
|
|
"s72", "s73", "s74", "s75", "s76", "s77", "s78", "s79",
|
|
|
|
"s80", "s81", "s82", "s83", "s84", "s85", "s86", "s87",
|
|
|
|
"s88", "s89", "s90", "s91", "s92", "s93", "s94", "s95",
|
|
|
|
"s96", "s97", "s98", "s99", "s100", "s101", "s102", "s103",
|
|
|
|
"s104", "s105", "s106", "s107", "s108", "s109", "s110", "s111",
|
|
|
|
"s112", "s113", "s114", "s115", "s116", "s117", "s118", "s119",
|
|
|
|
"s120", "s121", "s122", "s123", "s124", "s125", "s126", "s127"
|
|
|
|
"exec", "vcc", "scc", "m0", "flat_scr", "exec_lo", "exec_hi",
|
|
|
|
"vcc_lo", "vcc_hi", "flat_scr_lo", "flat_scr_hi"
|
|
|
|
};
|
|
|
|
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<const char *> AMDGPUTargetInfo::getGCCRegNames() const {
|
|
|
|
return llvm::makeArrayRef(GCCRegNames);
|
2015-04-14 14:36:56 +00:00
|
|
|
}
|
2014-06-24 20:45:01 +00:00
|
|
|
|
2008-08-20 02:34:37 +00:00
|
|
|
// Namespace for x86 abstract base class
|
|
|
|
const Builtin::Info BuiltinInfo[] = {
|
2015-08-07 05:14:44 +00:00
|
|
|
#define BUILTIN(ID, TYPE, ATTRS) \
|
|
|
|
{ #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },
|
2015-08-06 22:11:54 +00:00
|
|
|
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
|
2015-08-07 05:14:44 +00:00
|
|
|
{ #ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr },
|
2015-08-06 22:11:54 +00:00
|
|
|
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
|
2015-08-07 05:14:44 +00:00
|
|
|
{ #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE },
|
2009-06-14 01:05:48 +00:00
|
|
|
#include "clang/Basic/BuiltinsX86.def"
|
2008-08-20 02:34:37 +00:00
|
|
|
};
|
|
|
|
|
2009-12-23 17:49:57 +00:00
|
|
|
static const char* const GCCRegNames[] = {
|
2008-08-20 02:34:37 +00: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-07 22:55:26 +00:00
|
|
|
"argp", "flags", "fpcr", "fpsr", "dirflag", "frame",
|
2008-08-20 02:34:37 +00: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 00:05:20 +00:00
|
|
|
"xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15",
|
2011-12-02 02:12:16 +00:00
|
|
|
"ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7",
|
|
|
|
"ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15",
|
2008-08-20 02:34:37 +00:00
|
|
|
};
|
|
|
|
|
2011-06-21 00:05:20 +00: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 },
|
2015-09-04 03:42:23 +00:00
|
|
|
{ { "r8d", "r8w", "r8b" }, 38 },
|
|
|
|
{ { "r9d", "r9w", "r9b" }, 39 },
|
|
|
|
{ { "r10d", "r10w", "r10b" }, 40 },
|
|
|
|
{ { "r11d", "r11w", "r11b" }, 41 },
|
|
|
|
{ { "r12d", "r12w", "r12b" }, 42 },
|
|
|
|
{ { "r13d", "r13w", "r13b" }, 43 },
|
|
|
|
{ { "r14d", "r14w", "r14b" }, 44 },
|
|
|
|
{ { "r15d", "r15w", "r15b" }, 45 },
|
2008-08-20 02:34:37 +00: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-02 22:40:39 +00:00
|
|
|
enum X86SSEEnum {
|
2013-08-21 03:59:22 +00:00
|
|
|
NoSSE, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, AVX, AVX2, AVX512F
|
2015-10-14 23:47:57 +00:00
|
|
|
} SSELevel = NoSSE;
|
2011-07-08 23:31:17 +00:00
|
|
|
enum MMX3DNowEnum {
|
|
|
|
NoMMX3DNow, MMX, AMD3DNow, AMD3DNowAthlon
|
2015-10-14 23:47:57 +00:00
|
|
|
} MMX3DNowLevel = NoMMX3DNow;
|
2013-08-20 13:44:29 +00:00
|
|
|
enum XOPEnum {
|
|
|
|
NoXOP,
|
|
|
|
SSE4A,
|
|
|
|
FMA4,
|
|
|
|
XOP
|
2015-10-14 23:47:57 +00:00
|
|
|
} XOPLevel = NoXOP;
|
|
|
|
|
|
|
|
bool HasAES = false;
|
|
|
|
bool HasPCLMUL = false;
|
|
|
|
bool HasLZCNT = false;
|
|
|
|
bool HasRDRND = false;
|
|
|
|
bool HasFSGSBASE = false;
|
|
|
|
bool HasBMI = false;
|
|
|
|
bool HasBMI2 = false;
|
|
|
|
bool HasPOPCNT = false;
|
|
|
|
bool HasRTM = false;
|
|
|
|
bool HasPRFCHW = false;
|
|
|
|
bool HasRDSEED = false;
|
|
|
|
bool HasADX = false;
|
|
|
|
bool HasTBM = false;
|
|
|
|
bool HasFMA = false;
|
|
|
|
bool HasF16C = false;
|
|
|
|
bool HasAVX512CD = false;
|
|
|
|
bool HasAVX512ER = false;
|
|
|
|
bool HasAVX512PF = false;
|
|
|
|
bool HasAVX512DQ = false;
|
|
|
|
bool HasAVX512BW = false;
|
|
|
|
bool HasAVX512VL = false;
|
|
|
|
bool HasSHA = false;
|
|
|
|
bool HasCX16 = false;
|
2015-10-16 06:22:36 +00:00
|
|
|
bool HasFXSR = false;
|
2015-10-15 05:23:38 +00:00
|
|
|
bool HasXSAVE = false;
|
|
|
|
bool HasXSAVEOPT = false;
|
|
|
|
bool HasXSAVEC = false;
|
|
|
|
bool HasXSAVES = false;
|
2015-12-31 14:14:07 +00:00
|
|
|
bool HasPKU = false;
|
2010-08-04 22:29:13 +00:00
|
|
|
|
2011-09-28 08:55:34 +00: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-28 18:17:30 +00:00
|
|
|
/// Netburst microarchitecture based processors.
|
2011-09-28 08:55:34 +00: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
|
|
|
|
//@{
|
2014-12-09 14:50:25 +00:00
|
|
|
CK_Bonnell,
|
2013-09-13 19:27:17 +00:00
|
|
|
CK_Silvermont,
|
2011-09-28 08:55:34 +00:00
|
|
|
//@}
|
|
|
|
|
|
|
|
/// \name Nehalem
|
|
|
|
/// Nehalem microarchitecture based processors.
|
2014-12-09 14:50:25 +00:00
|
|
|
CK_Nehalem,
|
|
|
|
|
|
|
|
/// \name Westmere
|
|
|
|
/// Westmere microarchitecture based processors.
|
|
|
|
CK_Westmere,
|
|
|
|
|
|
|
|
/// \name Sandy Bridge
|
|
|
|
/// Sandy Bridge microarchitecture based processors.
|
|
|
|
CK_SandyBridge,
|
|
|
|
|
|
|
|
/// \name Ivy Bridge
|
|
|
|
/// Ivy Bridge microarchitecture based processors.
|
|
|
|
CK_IvyBridge,
|
|
|
|
|
|
|
|
/// \name Haswell
|
|
|
|
/// Haswell microarchitecture based processors.
|
|
|
|
CK_Haswell,
|
|
|
|
|
|
|
|
/// \name Broadwell
|
|
|
|
/// Broadwell microarchitecture based processors.
|
2014-09-19 09:53:48 +00:00
|
|
|
CK_Broadwell,
|
2014-12-09 14:50:25 +00:00
|
|
|
|
|
|
|
/// \name Skylake
|
|
|
|
/// Skylake microarchitecture based processors.
|
|
|
|
CK_Skylake,
|
2011-09-28 08:55:34 +00:00
|
|
|
|
2013-08-20 07:09:39 +00:00
|
|
|
/// \name Knights Landing
|
|
|
|
/// Knights Landing processor.
|
|
|
|
CK_KNL,
|
|
|
|
|
2011-09-28 08:55:34 +00: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 08:55:37 +00:00
|
|
|
CK_K8SSE3,
|
2011-09-28 08:55:34 +00:00
|
|
|
CK_Opteron,
|
|
|
|
CK_OpteronSSE3,
|
2011-10-30 07:48:46 +00:00
|
|
|
CK_AMDFAM10,
|
2012-01-10 11:50:18 +00:00
|
|
|
//@}
|
|
|
|
|
|
|
|
/// \name Bobcat
|
|
|
|
/// Bobcat architecture processors.
|
|
|
|
//@{
|
|
|
|
CK_BTVER1,
|
2013-05-03 10:47:15 +00:00
|
|
|
CK_BTVER2,
|
2012-01-10 11:50:18 +00:00
|
|
|
//@}
|
2011-09-28 08:55:34 +00:00
|
|
|
|
2012-01-10 11:50:18 +00:00
|
|
|
/// \name Bulldozer
|
|
|
|
/// Bulldozer architecture processors.
|
2011-12-01 18:23:59 +00:00
|
|
|
//@{
|
|
|
|
CK_BDVER1,
|
|
|
|
CK_BDVER2,
|
2013-11-04 10:29:51 +00:00
|
|
|
CK_BDVER3,
|
2014-05-02 15:47:51 +00:00
|
|
|
CK_BDVER4,
|
2012-01-10 11:50:18 +00:00
|
|
|
//@}
|
2011-12-01 18:23:59 +00:00
|
|
|
|
2011-09-28 08:55:34 +00: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.
|
2014-11-17 18:40:15 +00:00
|
|
|
//@{
|
2011-09-28 08:55:34 +00:00
|
|
|
CK_x86_64,
|
|
|
|
//@}
|
|
|
|
|
|
|
|
/// \name Geode
|
|
|
|
/// Geode processors.
|
|
|
|
//@{
|
|
|
|
CK_Geode
|
|
|
|
//@}
|
2015-10-14 23:47:57 +00:00
|
|
|
} CPU = CK_Generic;
|
2011-09-28 08:55:34 +00:00
|
|
|
|
2015-08-27 00:05:50 +00:00
|
|
|
CPUKind getCPUKind(StringRef CPU) const {
|
2015-08-26 23:42:18 +00:00
|
|
|
return llvm::StringSwitch<CPUKind>(CPU)
|
|
|
|
.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("bonnell", CK_Bonnell)
|
|
|
|
.Case("atom", CK_Bonnell) // Legacy name.
|
|
|
|
.Case("silvermont", CK_Silvermont)
|
|
|
|
.Case("slm", CK_Silvermont) // Legacy name.
|
|
|
|
.Case("nehalem", CK_Nehalem)
|
|
|
|
.Case("corei7", CK_Nehalem) // Legacy name.
|
|
|
|
.Case("westmere", CK_Westmere)
|
|
|
|
.Case("sandybridge", CK_SandyBridge)
|
|
|
|
.Case("corei7-avx", CK_SandyBridge) // Legacy name.
|
|
|
|
.Case("ivybridge", CK_IvyBridge)
|
|
|
|
.Case("core-avx-i", CK_IvyBridge) // Legacy name.
|
|
|
|
.Case("haswell", CK_Haswell)
|
|
|
|
.Case("core-avx2", CK_Haswell) // Legacy name.
|
|
|
|
.Case("broadwell", CK_Broadwell)
|
|
|
|
.Case("skylake", CK_Skylake)
|
|
|
|
.Case("skx", CK_Skylake) // Legacy name.
|
|
|
|
.Case("knl", CK_KNL)
|
|
|
|
.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)
|
|
|
|
.Case("barcelona", CK_AMDFAM10)
|
|
|
|
.Case("amdfam10", CK_AMDFAM10)
|
|
|
|
.Case("btver1", CK_BTVER1)
|
|
|
|
.Case("btver2", CK_BTVER2)
|
|
|
|
.Case("bdver1", CK_BDVER1)
|
|
|
|
.Case("bdver2", CK_BDVER2)
|
|
|
|
.Case("bdver3", CK_BDVER3)
|
|
|
|
.Case("bdver4", CK_BDVER4)
|
|
|
|
.Case("x86-64", CK_x86_64)
|
|
|
|
.Case("geode", CK_Geode)
|
|
|
|
.Default(CK_Generic);
|
|
|
|
}
|
|
|
|
|
2013-08-21 21:59:03 +00:00
|
|
|
enum FPMathKind {
|
|
|
|
FP_Default,
|
|
|
|
FP_SSE,
|
|
|
|
FP_387
|
2015-10-14 23:47:57 +00:00
|
|
|
} FPMath = FP_Default;
|
2013-08-21 21:59:03 +00:00
|
|
|
|
2006-10-14 07:39:34 +00:00
|
|
|
public:
|
2015-10-14 23:47:57 +00:00
|
|
|
X86TargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
|
2011-12-22 03:51:45 +00:00
|
|
|
BigEndian = false;
|
2015-11-05 12:43:09 +00:00
|
|
|
LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
|
2008-05-20 14:21:01 +00:00
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
unsigned getFloatEvalMethod() const override {
|
2011-12-28 15:47:06 +00:00
|
|
|
// X87 evaluates with 80 bits "long double" precision.
|
|
|
|
return SSELevel == NoSSE ? 2 : 0;
|
|
|
|
}
|
2015-10-19 04:51:35 +00:00
|
|
|
ArrayRef<Builtin::Info> getTargetBuiltins() const override {
|
|
|
|
return llvm::makeArrayRef(BuiltinInfo,
|
|
|
|
clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin);
|
2007-01-29 05:24:35 +00:00
|
|
|
}
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<const char *> getGCCRegNames() const override {
|
|
|
|
return llvm::makeArrayRef(GCCRegNames);
|
2007-11-24 23:38:12 +00:00
|
|
|
}
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
|
|
|
|
return None;
|
2011-06-21 00:05:20 +00:00
|
|
|
}
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override {
|
|
|
|
return llvm::makeArrayRef(AddlRegNames);
|
2007-10-13 00:45:48 +00:00
|
|
|
}
|
2015-06-29 21:00:05 +00:00
|
|
|
bool validateCpuSupports(StringRef Name) const override;
|
2014-03-11 03:39:26 +00:00
|
|
|
bool validateAsmConstraint(const char *&Name,
|
2014-11-18 22:36:15 +00:00
|
|
|
TargetInfo::ConstraintInfo &info) const override;
|
[X86, inline-asm] Check that the input size is correct for constraints R, q, Q,
S, D, A, y, x, f, t, and u.
This is a follow-up patch for r167717.
rdar://problem/11846140
rdar://problem/17476970
llvm-svn: 217994
2014-09-17 23:35:14 +00:00
|
|
|
|
2015-11-18 00:15:28 +00:00
|
|
|
bool validateGlobalRegisterVariable(StringRef RegName,
|
|
|
|
unsigned RegSize,
|
|
|
|
bool &HasSizeMismatch) const override {
|
|
|
|
// esp and ebp are the only 32-bit registers the x86 backend can currently
|
|
|
|
// handle.
|
|
|
|
if (RegName.equals("esp") || RegName.equals("ebp")) {
|
|
|
|
// Check that the register size is 32-bit.
|
|
|
|
HasSizeMismatch = RegSize != 32;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-09-18 18:17:18 +00:00
|
|
|
bool validateOutputSize(StringRef Constraint, unsigned Size) const override;
|
|
|
|
|
[X86, inline-asm] Check that the input size is correct for constraints R, q, Q,
S, D, A, y, x, f, t, and u.
This is a follow-up patch for r167717.
rdar://problem/11846140
rdar://problem/17476970
llvm-svn: 217994
2014-09-17 23:35:14 +00:00
|
|
|
bool validateInputSize(StringRef Constraint, unsigned Size) const override;
|
|
|
|
|
2014-09-18 18:17:18 +00:00
|
|
|
virtual bool validateOperandSize(StringRef Constraint, unsigned Size) const;
|
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
std::string convertConstraint(const char *&Constraint) const override;
|
|
|
|
const char *getClobbers() const override {
|
2008-08-20 02:34:37 +00:00
|
|
|
return "~{dirflag},~{fpsr},~{flags}";
|
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override;
|
2013-09-17 04:12:55 +00: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);
|
2014-03-11 03:39:26 +00:00
|
|
|
void setFeatureEnabled(llvm::StringMap<bool> &Features,
|
|
|
|
StringRef Name, bool Enabled) const override {
|
2013-09-17 04:51:29 +00:00
|
|
|
setFeatureEnabledImpl(Features, Name, Enabled);
|
|
|
|
}
|
|
|
|
// This exists purely to cut down on the number of virtual calls in
|
2015-08-28 02:13:58 +00:00
|
|
|
// initFeatureMap which calls this repeatedly.
|
2013-09-17 04:51:29 +00:00
|
|
|
static void setFeatureEnabledImpl(llvm::StringMap<bool> &Features,
|
|
|
|
StringRef Name, bool Enabled);
|
2015-10-09 18:39:55 +00:00
|
|
|
bool
|
|
|
|
initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
|
|
|
|
StringRef CPU,
|
|
|
|
const std::vector<std::string> &FeaturesVec) const override;
|
2014-03-11 03:39:26 +00:00
|
|
|
bool hasFeature(StringRef Feature) const override;
|
|
|
|
bool handleTargetFeatures(std::vector<std::string> &Features,
|
|
|
|
DiagnosticsEngine &Diags) override;
|
2014-06-07 23:30:42 +00:00
|
|
|
StringRef getABI() const override {
|
2015-06-22 21:31:43 +00:00
|
|
|
if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX512F)
|
|
|
|
return "avx512";
|
2015-10-20 00:00:17 +00:00
|
|
|
if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX)
|
2011-12-02 00:11:43 +00:00
|
|
|
return "avx";
|
2015-10-20 00:00:17 +00:00
|
|
|
if (getTriple().getArch() == llvm::Triple::x86 &&
|
2012-10-11 15:52:22 +00:00
|
|
|
MMX3DNowLevel == NoMMX3DNow)
|
2011-12-02 00:11:43 +00:00
|
|
|
return "no-mmx";
|
|
|
|
return "";
|
2011-07-08 23:31:17 +00:00
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
bool setCPU(const std::string &Name) override {
|
2015-08-26 23:42:18 +00:00
|
|
|
CPU = getCPUKind(Name);
|
2011-09-28 08:55:37 +00:00
|
|
|
|
2011-09-28 09:45:08 +00: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 15:52:22 +00:00
|
|
|
if (getTriple().getArch() != llvm::Triple::x86)
|
2011-09-28 09:45:08 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
// Fallthrough
|
|
|
|
case CK_Nocona:
|
|
|
|
case CK_Core2:
|
|
|
|
case CK_Penryn:
|
2014-12-09 14:50:25 +00:00
|
|
|
case CK_Bonnell:
|
2013-09-13 19:27:17 +00:00
|
|
|
case CK_Silvermont:
|
2014-12-09 14:50:25 +00:00
|
|
|
case CK_Nehalem:
|
|
|
|
case CK_Westmere:
|
|
|
|
case CK_SandyBridge:
|
|
|
|
case CK_IvyBridge:
|
|
|
|
case CK_Haswell:
|
2014-09-19 09:53:48 +00:00
|
|
|
case CK_Broadwell:
|
2014-12-09 14:50:25 +00:00
|
|
|
case CK_Skylake:
|
2013-08-20 07:09:39 +00:00
|
|
|
case CK_KNL:
|
2011-09-28 09:45:08 +00: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 07:48:46 +00:00
|
|
|
case CK_AMDFAM10:
|
2012-01-10 11:50:18 +00:00
|
|
|
case CK_BTVER1:
|
2013-05-03 10:47:15 +00:00
|
|
|
case CK_BTVER2:
|
2011-12-01 18:23:59 +00:00
|
|
|
case CK_BDVER1:
|
|
|
|
case CK_BDVER2:
|
2013-11-04 10:29:51 +00:00
|
|
|
case CK_BDVER3:
|
2014-05-02 15:47:51 +00:00
|
|
|
case CK_BDVER4:
|
2011-09-28 09:45:08 +00:00
|
|
|
case CK_x86_64:
|
|
|
|
return true;
|
|
|
|
}
|
2011-09-28 10:49:06 +00:00
|
|
|
llvm_unreachable("Unhandled CPU kind");
|
2011-09-28 02:59:25 +00:00
|
|
|
}
|
2012-10-02 14:26:08 +00:00
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
bool setFPMath(StringRef Name) override;
|
2013-08-21 21:59:03 +00:00
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
|
2012-10-02 14:26:08 +00:00
|
|
|
// We accept all non-ARM calling conventions
|
|
|
|
return (CC == CC_X86ThisCall ||
|
|
|
|
CC == CC_X86FastCall ||
|
2014-10-24 17:42:17 +00:00
|
|
|
CC == CC_X86StdCall ||
|
|
|
|
CC == CC_X86VectorCall ||
|
|
|
|
CC == CC_C ||
|
2012-12-25 08:53:55 +00:00
|
|
|
CC == CC_X86Pascal ||
|
|
|
|
CC == CC_IntelOclBicc) ? CCCR_OK : CCCR_Warning;
|
2012-10-02 14:26:08 +00:00
|
|
|
}
|
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
CallingConv getDefaultCallingConv(CallingConvMethodType MT) const override {
|
2012-12-09 17:45:41 +00:00
|
|
|
return MT == CCMT_Member ? CC_X86ThisCall : CC_C;
|
2012-10-02 14:26:08 +00:00
|
|
|
}
|
2015-03-11 23:46:32 +00:00
|
|
|
|
|
|
|
bool hasSjLjLowering() const override {
|
|
|
|
return true;
|
|
|
|
}
|
2008-08-20 02:34:37 +00:00
|
|
|
};
|
2009-03-02 22:20:04 +00:00
|
|
|
|
2013-08-21 21:59:03 +00:00
|
|
|
bool X86TargetInfo::setFPMath(StringRef Name) {
|
|
|
|
if (Name == "387") {
|
|
|
|
FPMath = FP_387;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (Name == "sse") {
|
|
|
|
FPMath = FP_SSE;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-08-28 22:32:01 +00:00
|
|
|
bool X86TargetInfo::initFeatureMap(
|
|
|
|
llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
|
2015-10-09 18:39:55 +00:00
|
|
|
const std::vector<std::string> &FeaturesVec) const {
|
2009-05-06 03:16:41 +00:00
|
|
|
// FIXME: This *really* should not be here.
|
|
|
|
// X86_64 always has SSE2.
|
2012-10-11 15:52:22 +00:00
|
|
|
if (getTriple().getArch() == llvm::Triple::x86_64)
|
2013-09-17 04:51:29 +00:00
|
|
|
setFeatureEnabledImpl(Features, "sse2", true);
|
2009-05-06 03:16:41 +00:00
|
|
|
|
2015-08-27 00:05:52 +00:00
|
|
|
switch (getCPUKind(CPU)) {
|
2011-09-28 08:55:37 +00:00
|
|
|
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:
|
2014-11-06 05:52:19 +00:00
|
|
|
case CK_K6:
|
|
|
|
case CK_WinChipC6:
|
2013-09-17 04:51:29 +00:00
|
|
|
setFeatureEnabledImpl(Features, "mmx", true);
|
2011-09-28 08:55:37 +00:00
|
|
|
break;
|
|
|
|
case CK_Pentium3:
|
|
|
|
case CK_Pentium3M:
|
2014-11-06 05:52:19 +00:00
|
|
|
case CK_C3_2:
|
2013-09-17 04:51:29 +00:00
|
|
|
setFeatureEnabledImpl(Features, "sse", true);
|
2015-10-16 06:22:36 +00:00
|
|
|
setFeatureEnabledImpl(Features, "fxsr", true);
|
2011-09-28 08:55:37 +00:00
|
|
|
break;
|
|
|
|
case CK_PentiumM:
|
|
|
|
case CK_Pentium4:
|
|
|
|
case CK_Pentium4M:
|
|
|
|
case CK_x86_64:
|
2013-09-17 04:51:29 +00:00
|
|
|
setFeatureEnabledImpl(Features, "sse2", true);
|
2015-10-16 06:22:36 +00:00
|
|
|
setFeatureEnabledImpl(Features, "fxsr", true);
|
2011-09-28 08:55:37 +00:00
|
|
|
break;
|
|
|
|
case CK_Yonah:
|
|
|
|
case CK_Prescott:
|
|
|
|
case CK_Nocona:
|
2013-09-17 04:51:29 +00:00
|
|
|
setFeatureEnabledImpl(Features, "sse3", true);
|
2015-10-16 06:22:36 +00:00
|
|
|
setFeatureEnabledImpl(Features, "fxsr", true);
|
2013-10-05 20:14:27 +00:00
|
|
|
setFeatureEnabledImpl(Features, "cx16", true);
|
2011-09-28 08:55:37 +00:00
|
|
|
break;
|
|
|
|
case CK_Core2:
|
2014-12-09 14:50:25 +00:00
|
|
|
case CK_Bonnell:
|
2013-09-17 04:51:29 +00:00
|
|
|
setFeatureEnabledImpl(Features, "ssse3", true);
|
2015-10-16 06:22:36 +00:00
|
|
|
setFeatureEnabledImpl(Features, "fxsr", true);
|
2013-10-05 20:14:27 +00:00
|
|
|
setFeatureEnabledImpl(Features, "cx16", true);
|
2011-09-28 08:55:37 +00:00
|
|
|
break;
|
|
|
|
case CK_Penryn:
|
2013-09-17 04:51:29 +00:00
|
|
|
setFeatureEnabledImpl(Features, "sse4.1", true);
|
2015-10-16 06:22:36 +00:00
|
|
|
setFeatureEnabledImpl(Features, "fxsr", true);
|
2013-10-05 20:14:27 +00:00
|
|
|
setFeatureEnabledImpl(Features, "cx16", true);
|
2011-09-28 08:55:37 +00:00
|
|
|
break;
|
2014-12-09 14:50:25 +00:00
|
|
|
case CK_Skylake:
|
2014-11-06 05:52:19 +00:00
|
|
|
setFeatureEnabledImpl(Features, "avx512f", true);
|
|
|
|
setFeatureEnabledImpl(Features, "avx512cd", true);
|
|
|
|
setFeatureEnabledImpl(Features, "avx512dq", true);
|
|
|
|
setFeatureEnabledImpl(Features, "avx512bw", true);
|
|
|
|
setFeatureEnabledImpl(Features, "avx512vl", true);
|
2015-10-15 05:23:38 +00:00
|
|
|
setFeatureEnabledImpl(Features, "xsavec", true);
|
|
|
|
setFeatureEnabledImpl(Features, "xsaves", true);
|
2015-12-31 14:14:07 +00:00
|
|
|
setFeatureEnabledImpl(Features, "pku", true);
|
2014-11-06 05:52:19 +00:00
|
|
|
// FALLTHROUGH
|
|
|
|
case CK_Broadwell:
|
|
|
|
setFeatureEnabledImpl(Features, "rdseed", true);
|
|
|
|
setFeatureEnabledImpl(Features, "adx", true);
|
|
|
|
// FALLTHROUGH
|
2014-12-09 14:50:25 +00:00
|
|
|
case CK_Haswell:
|
2013-09-17 04:51:29 +00:00
|
|
|
setFeatureEnabledImpl(Features, "avx2", true);
|
|
|
|
setFeatureEnabledImpl(Features, "lzcnt", true);
|
|
|
|
setFeatureEnabledImpl(Features, "bmi", true);
|
|
|
|
setFeatureEnabledImpl(Features, "bmi2", true);
|
|
|
|
setFeatureEnabledImpl(Features, "rtm", true);
|
|
|
|
setFeatureEnabledImpl(Features, "fma", true);
|
2014-11-06 05:52:19 +00:00
|
|
|
// FALLTHROUGH
|
2014-12-09 14:50:25 +00:00
|
|
|
case CK_IvyBridge:
|
2014-09-19 09:53:48 +00:00
|
|
|
setFeatureEnabledImpl(Features, "rdrnd", true);
|
|
|
|
setFeatureEnabledImpl(Features, "f16c", true);
|
2014-11-03 06:51:41 +00:00
|
|
|
setFeatureEnabledImpl(Features, "fsgsbase", true);
|
2014-11-06 05:52:19 +00:00
|
|
|
// FALLTHROUGH
|
2014-12-09 14:50:25 +00:00
|
|
|
case CK_SandyBridge:
|
2014-11-06 05:52:19 +00:00
|
|
|
setFeatureEnabledImpl(Features, "avx", true);
|
2015-10-15 05:23:38 +00:00
|
|
|
setFeatureEnabledImpl(Features, "xsave", true);
|
|
|
|
setFeatureEnabledImpl(Features, "xsaveopt", true);
|
2014-11-06 05:52:19 +00:00
|
|
|
// FALLTHROUGH
|
2014-12-09 14:50:25 +00:00
|
|
|
case CK_Westmere:
|
2014-11-06 05:52:19 +00:00
|
|
|
case CK_Silvermont:
|
|
|
|
setFeatureEnabledImpl(Features, "aes", true);
|
|
|
|
setFeatureEnabledImpl(Features, "pclmul", true);
|
|
|
|
// FALLTHROUGH
|
2014-12-09 14:50:25 +00:00
|
|
|
case CK_Nehalem:
|
2014-11-06 05:52:19 +00:00
|
|
|
setFeatureEnabledImpl(Features, "sse4.2", true);
|
2015-10-16 06:22:36 +00:00
|
|
|
setFeatureEnabledImpl(Features, "fxsr", true);
|
2014-11-06 05:52:19 +00:00
|
|
|
setFeatureEnabledImpl(Features, "cx16", true);
|
2014-09-19 09:53:48 +00:00
|
|
|
break;
|
2013-08-20 07:09:39 +00:00
|
|
|
case CK_KNL:
|
2013-09-17 04:51:29 +00:00
|
|
|
setFeatureEnabledImpl(Features, "avx512f", true);
|
|
|
|
setFeatureEnabledImpl(Features, "avx512cd", true);
|
|
|
|
setFeatureEnabledImpl(Features, "avx512er", true);
|
|
|
|
setFeatureEnabledImpl(Features, "avx512pf", true);
|
2015-10-16 06:22:36 +00:00
|
|
|
setFeatureEnabledImpl(Features, "fxsr", true);
|
2014-11-06 05:52:19 +00:00
|
|
|
setFeatureEnabledImpl(Features, "rdseed", true);
|
|
|
|
setFeatureEnabledImpl(Features, "adx", true);
|
2013-09-17 04:51:29 +00:00
|
|
|
setFeatureEnabledImpl(Features, "lzcnt", true);
|
|
|
|
setFeatureEnabledImpl(Features, "bmi", true);
|
|
|
|
setFeatureEnabledImpl(Features, "bmi2", true);
|
|
|
|
setFeatureEnabledImpl(Features, "rtm", true);
|
|
|
|
setFeatureEnabledImpl(Features, "fma", true);
|
2014-07-30 13:53:40 +00:00
|
|
|
setFeatureEnabledImpl(Features, "rdrnd", true);
|
|
|
|
setFeatureEnabledImpl(Features, "f16c", true);
|
2014-11-03 06:51:41 +00:00
|
|
|
setFeatureEnabledImpl(Features, "fsgsbase", true);
|
2014-11-06 05:52:19 +00:00
|
|
|
setFeatureEnabledImpl(Features, "aes", true);
|
|
|
|
setFeatureEnabledImpl(Features, "pclmul", true);
|
|
|
|
setFeatureEnabledImpl(Features, "cx16", true);
|
2015-10-15 05:23:38 +00:00
|
|
|
setFeatureEnabledImpl(Features, "xsaveopt", true);
|
|
|
|
setFeatureEnabledImpl(Features, "xsave", true);
|
2011-09-28 08:55:37 +00:00
|
|
|
break;
|
|
|
|
case CK_K6_2:
|
|
|
|
case CK_K6_3:
|
|
|
|
case CK_WinChip2:
|
|
|
|
case CK_C3:
|
2013-09-17 04:51:29 +00:00
|
|
|
setFeatureEnabledImpl(Features, "3dnow", true);
|
2011-09-28 08:55:37 +00:00
|
|
|
break;
|
2011-09-28 10:36:46 +00:00
|
|
|
case CK_Athlon:
|
|
|
|
case CK_AthlonThunderbird:
|
|
|
|
case CK_Geode:
|
2013-09-17 04:51:29 +00:00
|
|
|
setFeatureEnabledImpl(Features, "3dnowa", true);
|
2011-09-28 10:36:46 +00:00
|
|
|
break;
|
2011-09-28 08:55:37 +00:00
|
|
|
case CK_Athlon4:
|
|
|
|
case CK_AthlonXP:
|
|
|
|
case CK_AthlonMP:
|
2013-09-17 04:51:29 +00:00
|
|
|
setFeatureEnabledImpl(Features, "sse", true);
|
|
|
|
setFeatureEnabledImpl(Features, "3dnowa", true);
|
2015-10-16 06:22:36 +00:00
|
|
|
setFeatureEnabledImpl(Features, "fxsr", true);
|
2011-09-28 08:55:37 +00:00
|
|
|
break;
|
|
|
|
case CK_K8:
|
|
|
|
case CK_Opteron:
|
|
|
|
case CK_Athlon64:
|
|
|
|
case CK_AthlonFX:
|
2013-09-17 04:51:29 +00:00
|
|
|
setFeatureEnabledImpl(Features, "sse2", true);
|
|
|
|
setFeatureEnabledImpl(Features, "3dnowa", true);
|
2015-10-16 06:22:36 +00:00
|
|
|
setFeatureEnabledImpl(Features, "fxsr", true);
|
2011-09-28 08:55:37 +00:00
|
|
|
break;
|
2014-11-06 05:52:19 +00:00
|
|
|
case CK_AMDFAM10:
|
|
|
|
setFeatureEnabledImpl(Features, "sse4a", true);
|
|
|
|
setFeatureEnabledImpl(Features, "lzcnt", true);
|
|
|
|
setFeatureEnabledImpl(Features, "popcnt", true);
|
|
|
|
// FALLTHROUGH
|
2011-09-28 08:55:37 +00:00
|
|
|
case CK_K8SSE3:
|
|
|
|
case CK_OpteronSSE3:
|
|
|
|
case CK_Athlon64SSE3:
|
2013-09-17 04:51:29 +00:00
|
|
|
setFeatureEnabledImpl(Features, "sse3", true);
|
|
|
|
setFeatureEnabledImpl(Features, "3dnowa", true);
|
2015-10-16 06:22:36 +00:00
|
|
|
setFeatureEnabledImpl(Features, "fxsr", true);
|
2011-10-30 13:47:56 +00:00
|
|
|
break;
|
2013-05-03 10:47:15 +00:00
|
|
|
case CK_BTVER2:
|
2013-09-17 04:51:29 +00:00
|
|
|
setFeatureEnabledImpl(Features, "avx", true);
|
|
|
|
setFeatureEnabledImpl(Features, "aes", true);
|
|
|
|
setFeatureEnabledImpl(Features, "pclmul", true);
|
|
|
|
setFeatureEnabledImpl(Features, "bmi", true);
|
|
|
|
setFeatureEnabledImpl(Features, "f16c", true);
|
2015-10-15 05:23:38 +00:00
|
|
|
setFeatureEnabledImpl(Features, "xsaveopt", true);
|
2014-11-06 05:52:19 +00:00
|
|
|
// FALLTHROUGH
|
|
|
|
case CK_BTVER1:
|
|
|
|
setFeatureEnabledImpl(Features, "ssse3", true);
|
|
|
|
setFeatureEnabledImpl(Features, "sse4a", true);
|
|
|
|
setFeatureEnabledImpl(Features, "lzcnt", true);
|
|
|
|
setFeatureEnabledImpl(Features, "popcnt", true);
|
|
|
|
setFeatureEnabledImpl(Features, "prfchw", true);
|
2013-10-05 20:14:27 +00:00
|
|
|
setFeatureEnabledImpl(Features, "cx16", true);
|
2015-10-16 06:22:36 +00:00
|
|
|
setFeatureEnabledImpl(Features, "fxsr", true);
|
2015-10-15 05:23:38 +00:00
|
|
|
setFeatureEnabledImpl(Features, "xsave", true);
|
2013-05-03 10:47:15 +00:00
|
|
|
break;
|
2014-05-02 15:47:51 +00:00
|
|
|
case CK_BDVER4:
|
|
|
|
setFeatureEnabledImpl(Features, "avx2", true);
|
|
|
|
setFeatureEnabledImpl(Features, "bmi2", true);
|
|
|
|
// FALLTHROUGH
|
2013-11-04 10:29:51 +00:00
|
|
|
case CK_BDVER3:
|
2014-11-03 06:51:41 +00:00
|
|
|
setFeatureEnabledImpl(Features, "fsgsbase", true);
|
2015-10-15 05:23:38 +00:00
|
|
|
setFeatureEnabledImpl(Features, "xsaveopt", true);
|
2014-11-03 06:51:41 +00:00
|
|
|
// FALLTHROUGH
|
|
|
|
case CK_BDVER2:
|
2014-11-06 12:08:57 +00:00
|
|
|
setFeatureEnabledImpl(Features, "bmi", true);
|
|
|
|
setFeatureEnabledImpl(Features, "fma", true);
|
|
|
|
setFeatureEnabledImpl(Features, "f16c", true);
|
|
|
|
setFeatureEnabledImpl(Features, "tbm", true);
|
|
|
|
// FALLTHROUGH
|
|
|
|
case CK_BDVER1:
|
|
|
|
// xop implies avx, sse4a and fma4.
|
2013-09-17 04:51:29 +00:00
|
|
|
setFeatureEnabledImpl(Features, "xop", true);
|
|
|
|
setFeatureEnabledImpl(Features, "lzcnt", true);
|
|
|
|
setFeatureEnabledImpl(Features, "aes", true);
|
|
|
|
setFeatureEnabledImpl(Features, "pclmul", true);
|
2013-10-16 19:07:02 +00:00
|
|
|
setFeatureEnabledImpl(Features, "prfchw", true);
|
2013-10-05 20:14:27 +00:00
|
|
|
setFeatureEnabledImpl(Features, "cx16", true);
|
2015-10-16 06:22:36 +00:00
|
|
|
setFeatureEnabledImpl(Features, "fxsr", true);
|
2015-10-15 05:23:38 +00:00
|
|
|
setFeatureEnabledImpl(Features, "xsave", true);
|
2011-12-01 18:23:59 +00:00
|
|
|
break;
|
2011-07-08 23:31:17 +00:00
|
|
|
}
|
2015-10-08 20:10:14 +00:00
|
|
|
if (!TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Can't do this earlier because we need to be able to explicitly enable
|
|
|
|
// or disable these features and the things that they depend upon.
|
|
|
|
|
|
|
|
// Enable popcnt if sse4.2 is enabled and popcnt is not explicitly disabled.
|
|
|
|
auto I = Features.find("sse4.2");
|
2015-10-24 23:15:31 +00:00
|
|
|
if (I != Features.end() && I->getValue() &&
|
2015-10-08 20:10:14 +00:00
|
|
|
std::find(FeaturesVec.begin(), FeaturesVec.end(), "-popcnt") ==
|
|
|
|
FeaturesVec.end())
|
|
|
|
Features["popcnt"] = true;
|
|
|
|
|
|
|
|
// Enable prfchw if 3DNow! is enabled and prfchw is not explicitly disabled.
|
|
|
|
I = Features.find("3dnow");
|
2015-10-24 23:15:31 +00:00
|
|
|
if (I != Features.end() && I->getValue() &&
|
2015-10-08 20:10:14 +00:00
|
|
|
std::find(FeaturesVec.begin(), FeaturesVec.end(), "-prfchw") ==
|
|
|
|
FeaturesVec.end())
|
|
|
|
Features["prfchw"] = true;
|
|
|
|
|
Handle sse turning on mmx, but no -mmx not turning off SSE.
Rationale :
// sse3
__m128d test_mm_addsub_pd(__m128d A, __m128d B) {
return _mm_addsub_pd(A, B);
}
// mmx
void shift(__m64 a, __m64 b, int c) {
_mm_slli_pi16(a, c);
_mm_slli_pi32(a, c);
_mm_slli_si64(a, c);
_mm_srli_pi16(a, c);
_mm_srli_pi32(a, c);
_mm_srli_si64(a, c);
_mm_srai_pi16(a, c);
_mm_srai_pi32(a, c);
}
clang -msse3 -mno-mmx file.c -c
For this code we should be able to explicitly turn off MMX
without affecting the compilation of the SSE3 function and then
diagnose and error on compiling the MMX function.
This is a preparatory patch to the actual diagnosis code which is
coming in a future patch. This sets us up to have the correct information
where we need it and verifies that it's being emitted for the backend
to handle.
llvm-svn: 249733
2015-10-08 20:10:18 +00:00
|
|
|
// Additionally, if SSE is enabled and mmx is not explicitly disabled,
|
|
|
|
// then enable MMX.
|
|
|
|
I = Features.find("sse");
|
2015-10-24 23:15:31 +00:00
|
|
|
if (I != Features.end() && I->getValue() &&
|
Handle sse turning on mmx, but no -mmx not turning off SSE.
Rationale :
// sse3
__m128d test_mm_addsub_pd(__m128d A, __m128d B) {
return _mm_addsub_pd(A, B);
}
// mmx
void shift(__m64 a, __m64 b, int c) {
_mm_slli_pi16(a, c);
_mm_slli_pi32(a, c);
_mm_slli_si64(a, c);
_mm_srli_pi16(a, c);
_mm_srli_pi32(a, c);
_mm_srli_si64(a, c);
_mm_srai_pi16(a, c);
_mm_srai_pi32(a, c);
}
clang -msse3 -mno-mmx file.c -c
For this code we should be able to explicitly turn off MMX
without affecting the compilation of the SSE3 function and then
diagnose and error on compiling the MMX function.
This is a preparatory patch to the actual diagnosis code which is
coming in a future patch. This sets us up to have the correct information
where we need it and verifies that it's being emitted for the backend
to handle.
llvm-svn: 249733
2015-10-08 20:10:18 +00:00
|
|
|
std::find(FeaturesVec.begin(), FeaturesVec.end(), "-mmx") ==
|
|
|
|
FeaturesVec.end())
|
|
|
|
Features["mmx"] = true;
|
|
|
|
|
2015-10-08 20:10:14 +00:00
|
|
|
return true;
|
2009-05-06 03:16:41 +00:00
|
|
|
}
|
|
|
|
|
2013-08-20 13:44:29 +00:00
|
|
|
void X86TargetInfo::setSSELevel(llvm::StringMap<bool> &Features,
|
2013-09-17 04:12:55 +00:00
|
|
|
X86SSEEnum Level, bool Enabled) {
|
2013-08-20 13:44:29 +00:00
|
|
|
if (Enabled) {
|
|
|
|
switch (Level) {
|
2013-08-21 03:59:22 +00:00
|
|
|
case AVX512F:
|
|
|
|
Features["avx512f"] = true;
|
2013-08-20 13:44:29 +00:00
|
|
|
case AVX2:
|
|
|
|
Features["avx2"] = true;
|
|
|
|
case AVX:
|
|
|
|
Features["avx"] = true;
|
2015-10-15 05:23:38 +00:00
|
|
|
Features["xsave"] = true;
|
2013-08-20 13:44:29 +00:00
|
|
|
case SSE42:
|
2013-09-10 06:55:47 +00:00
|
|
|
Features["sse4.2"] = true;
|
2013-08-20 13:44:29 +00:00
|
|
|
case SSE41:
|
2013-08-23 20:21:37 +00:00
|
|
|
Features["sse4.1"] = true;
|
2013-08-20 13:44:29 +00: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 13:22:04 +00:00
|
|
|
Features["sse2"] = Features["pclmul"] = Features["aes"] =
|
|
|
|
Features["sha"] = false;
|
2013-08-20 13:44:29 +00:00
|
|
|
case SSE3:
|
|
|
|
Features["sse3"] = false;
|
|
|
|
setXOPLevel(Features, NoXOP, false);
|
|
|
|
case SSSE3:
|
|
|
|
Features["ssse3"] = false;
|
|
|
|
case SSE41:
|
2013-08-23 20:21:37 +00:00
|
|
|
Features["sse4.1"] = false;
|
2013-08-20 13:44:29 +00:00
|
|
|
case SSE42:
|
2013-09-10 06:55:47 +00:00
|
|
|
Features["sse4.2"] = false;
|
2013-08-20 13:44:29 +00:00
|
|
|
case AVX:
|
2015-10-15 05:23:38 +00:00
|
|
|
Features["fma"] = Features["avx"] = Features["f16c"] = Features["xsave"] =
|
|
|
|
Features["xsaveopt"] = false;
|
2013-08-21 13:28:02 +00:00
|
|
|
setXOPLevel(Features, FMA4, false);
|
2013-08-20 13:44:29 +00:00
|
|
|
case AVX2:
|
|
|
|
Features["avx2"] = false;
|
2013-08-21 03:59:22 +00:00
|
|
|
case AVX512F:
|
2014-11-18 22:36:15 +00:00
|
|
|
Features["avx512f"] = Features["avx512cd"] = Features["avx512er"] =
|
2014-12-27 06:59:37 +00:00
|
|
|
Features["avx512pf"] = Features["avx512dq"] = Features["avx512bw"] =
|
|
|
|
Features["avx512vl"] = false;
|
2013-08-20 13:44:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void X86TargetInfo::setMMXLevel(llvm::StringMap<bool> &Features,
|
2013-09-17 04:12:55 +00:00
|
|
|
MMX3DNowEnum Level, bool Enabled) {
|
2013-08-20 13:44:29 +00: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 04:12:55 +00:00
|
|
|
bool Enabled) {
|
2013-08-20 13:44:29 +00: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 04:51:29 +00:00
|
|
|
void X86TargetInfo::setFeatureEnabledImpl(llvm::StringMap<bool> &Features,
|
|
|
|
StringRef Name, bool Enabled) {
|
2015-07-01 00:08:32 +00:00
|
|
|
// This is a bit of a hack to deal with the sse4 target feature when used
|
|
|
|
// as part of the target attribute. We handle sse4 correctly everywhere
|
|
|
|
// else. See below for more information on how we handle the sse4 options.
|
|
|
|
if (Name != "sse4")
|
|
|
|
Features[Name] = Enabled;
|
2013-08-20 13:44:29 +00:00
|
|
|
|
2013-09-19 01:13:07 +00:00
|
|
|
if (Name == "mmx") {
|
2013-08-20 13:44:29 +00:00
|
|
|
setMMXLevel(Features, MMX, Enabled);
|
2013-09-19 01:13:07 +00:00
|
|
|
} else if (Name == "sse") {
|
2013-08-20 13:44:29 +00:00
|
|
|
setSSELevel(Features, SSE1, Enabled);
|
2013-09-19 01:13:07 +00:00
|
|
|
} else if (Name == "sse2") {
|
2013-08-20 13:44:29 +00:00
|
|
|
setSSELevel(Features, SSE2, Enabled);
|
2013-09-19 01:13:07 +00:00
|
|
|
} else if (Name == "sse3") {
|
2013-08-20 13:44:29 +00:00
|
|
|
setSSELevel(Features, SSE3, Enabled);
|
2013-09-19 01:13:07 +00:00
|
|
|
} else if (Name == "ssse3") {
|
2013-08-20 13:44:29 +00:00
|
|
|
setSSELevel(Features, SSSE3, Enabled);
|
2013-09-19 01:13:07 +00:00
|
|
|
} else if (Name == "sse4.2") {
|
2013-08-20 13:44:29 +00:00
|
|
|
setSSELevel(Features, SSE42, Enabled);
|
2013-09-19 01:13:07 +00:00
|
|
|
} else if (Name == "sse4.1") {
|
2013-08-20 13:44:29 +00:00
|
|
|
setSSELevel(Features, SSE41, Enabled);
|
2013-09-19 01:13:07 +00:00
|
|
|
} else if (Name == "3dnow") {
|
2013-08-20 13:44:29 +00:00
|
|
|
setMMXLevel(Features, AMD3DNow, Enabled);
|
2013-09-19 01:13:07 +00:00
|
|
|
} else if (Name == "3dnowa") {
|
2013-08-20 13:44:29 +00:00
|
|
|
setMMXLevel(Features, AMD3DNowAthlon, Enabled);
|
2013-09-19 01:13:07 +00:00
|
|
|
} else if (Name == "aes") {
|
2013-08-20 13:44:29 +00:00
|
|
|
if (Enabled)
|
|
|
|
setSSELevel(Features, SSE2, Enabled);
|
|
|
|
} else if (Name == "pclmul") {
|
|
|
|
if (Enabled)
|
|
|
|
setSSELevel(Features, SSE2, Enabled);
|
2013-09-19 01:13:07 +00:00
|
|
|
} else if (Name == "avx") {
|
2013-08-20 13:44:29 +00:00
|
|
|
setSSELevel(Features, AVX, Enabled);
|
2013-09-19 01:13:07 +00:00
|
|
|
} else if (Name == "avx2") {
|
2013-08-20 13:44:29 +00:00
|
|
|
setSSELevel(Features, AVX2, Enabled);
|
2013-09-19 01:13:07 +00:00
|
|
|
} else if (Name == "avx512f") {
|
2013-08-21 03:59:22 +00:00
|
|
|
setSSELevel(Features, AVX512F, Enabled);
|
2014-07-30 13:53:40 +00:00
|
|
|
} else if (Name == "avx512cd" || Name == "avx512er" || Name == "avx512pf"
|
|
|
|
|| Name == "avx512dq" || Name == "avx512bw" || Name == "avx512vl") {
|
2013-08-21 05:29:10 +00:00
|
|
|
if (Enabled)
|
|
|
|
setSSELevel(Features, AVX512F, Enabled);
|
|
|
|
} else if (Name == "fma") {
|
2013-08-20 13:44:29 +00: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 04:54:13 +00:00
|
|
|
} else if (Name == "f16c") {
|
|
|
|
if (Enabled)
|
|
|
|
setSSELevel(Features, AVX, Enabled);
|
2013-09-19 13:22:04 +00:00
|
|
|
} else if (Name == "sha") {
|
|
|
|
if (Enabled)
|
|
|
|
setSSELevel(Features, SSE2, Enabled);
|
2015-07-01 00:08:32 +00:00
|
|
|
} else if (Name == "sse4") {
|
|
|
|
// We can get here via the __target__ attribute since that's not controlled
|
|
|
|
// via the -msse4/-mno-sse4 command line alias. Handle this the same way
|
|
|
|
// here - turn on the sse4.2 if enabled, turn off the sse4.1 level if
|
|
|
|
// disabled.
|
|
|
|
if (Enabled)
|
|
|
|
setSSELevel(Features, SSE42, Enabled);
|
|
|
|
else
|
|
|
|
setSSELevel(Features, SSE41, Enabled);
|
2015-10-15 05:23:38 +00:00
|
|
|
} else if (Name == "xsave") {
|
|
|
|
if (Enabled)
|
|
|
|
setSSELevel(Features, AVX, Enabled);
|
|
|
|
else
|
|
|
|
Features["xsaveopt"] = false;
|
|
|
|
} else if (Name == "xsaveopt" || Name == "xsavec" || Name == "xsaves") {
|
|
|
|
if (Enabled) {
|
|
|
|
Features["xsave"] = true;
|
|
|
|
setSSELevel(Features, AVX, Enabled);
|
|
|
|
}
|
2009-05-06 21:07:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-16 21:26:26 +00:00
|
|
|
/// handleTargetFeatures - Perform initialization based on the user
|
2009-05-06 03:16:41 +00:00
|
|
|
/// configured set of features.
|
2013-10-16 21:26:26 +00:00
|
|
|
bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
|
2013-08-21 21:59:03 +00:00
|
|
|
DiagnosticsEngine &Diags) {
|
2015-08-26 08:21:55 +00:00
|
|
|
for (const auto &Feature : Features) {
|
|
|
|
if (Feature[0] != '+')
|
2009-11-11 09:38:56 +00:00
|
|
|
continue;
|
|
|
|
|
2015-08-26 08:21:55 +00:00
|
|
|
if (Feature == "+aes") {
|
2010-04-02 23:50:19 +00:00
|
|
|
HasAES = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
} else if (Feature == "+pclmul") {
|
2012-05-31 05:18:48 +00:00
|
|
|
HasPCLMUL = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
} else if (Feature == "+lzcnt") {
|
2011-12-25 05:06:45 +00:00
|
|
|
HasLZCNT = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
} else if (Feature == "+rdrnd") {
|
2012-07-07 09:39:18 +00:00
|
|
|
HasRDRND = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
} else if (Feature == "+fsgsbase") {
|
2014-11-03 06:51:41 +00:00
|
|
|
HasFSGSBASE = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
} else if (Feature == "+bmi") {
|
2011-12-25 05:06:45 +00:00
|
|
|
HasBMI = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
} else if (Feature == "+bmi2") {
|
2011-12-25 05:06:45 +00:00
|
|
|
HasBMI2 = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
} else if (Feature == "+popcnt") {
|
2011-12-29 16:10:46 +00:00
|
|
|
HasPOPCNT = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
} else if (Feature == "+rtm") {
|
2012-11-10 05:17:46 +00:00
|
|
|
HasRTM = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
} else if (Feature == "+prfchw") {
|
2013-03-26 17:52:08 +00:00
|
|
|
HasPRFCHW = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
} else if (Feature == "+rdseed") {
|
2013-03-29 05:17:55 +00:00
|
|
|
HasRDSEED = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
} else if (Feature == "+adx") {
|
2014-09-19 09:53:48 +00:00
|
|
|
HasADX = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
} else if (Feature == "+tbm") {
|
2013-09-24 19:00:58 +00:00
|
|
|
HasTBM = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
} else if (Feature == "+fma") {
|
2012-06-03 21:46:30 +00:00
|
|
|
HasFMA = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
} else if (Feature == "+f16c") {
|
2012-10-11 00:59:55 +00:00
|
|
|
HasF16C = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
} else if (Feature == "+avx512cd") {
|
2013-08-21 05:29:10 +00:00
|
|
|
HasAVX512CD = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
} else if (Feature == "+avx512er") {
|
2013-08-21 05:29:10 +00:00
|
|
|
HasAVX512ER = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
} else if (Feature == "+avx512pf") {
|
2013-08-21 05:29:10 +00:00
|
|
|
HasAVX512PF = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
} else if (Feature == "+avx512dq") {
|
2014-07-30 13:53:40 +00:00
|
|
|
HasAVX512DQ = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
} else if (Feature == "+avx512bw") {
|
2014-07-30 13:53:40 +00:00
|
|
|
HasAVX512BW = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
} else if (Feature == "+avx512vl") {
|
2014-07-30 13:53:40 +00:00
|
|
|
HasAVX512VL = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
} else if (Feature == "+sha") {
|
2013-09-19 13:22:04 +00:00
|
|
|
HasSHA = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
} else if (Feature == "+cx16") {
|
2013-10-05 20:14:27 +00:00
|
|
|
HasCX16 = true;
|
2015-10-16 06:22:36 +00:00
|
|
|
} else if (Feature == "+fxsr") {
|
|
|
|
HasFXSR = true;
|
2015-10-15 05:23:38 +00:00
|
|
|
} else if (Feature == "+xsave") {
|
|
|
|
HasXSAVE = true;
|
|
|
|
} else if (Feature == "+xsaveopt") {
|
|
|
|
HasXSAVEOPT = true;
|
|
|
|
} else if (Feature == "+xsavec") {
|
|
|
|
HasXSAVEC = true;
|
|
|
|
} else if (Feature == "+xsaves") {
|
|
|
|
HasXSAVES = true;
|
2015-12-31 14:14:07 +00:00
|
|
|
} else if (Feature == "+pku") {
|
|
|
|
HasPKU = true;
|
2013-10-05 20:14:27 +00:00
|
|
|
}
|
|
|
|
|
2012-03-05 15:10:44 +00:00
|
|
|
X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature)
|
2015-08-26 08:21:55 +00:00
|
|
|
.Case("+avx512f", AVX512F)
|
|
|
|
.Case("+avx2", AVX2)
|
|
|
|
.Case("+avx", AVX)
|
|
|
|
.Case("+sse4.2", SSE42)
|
|
|
|
.Case("+sse4.1", SSE41)
|
|
|
|
.Case("+ssse3", SSSE3)
|
|
|
|
.Case("+sse3", SSE3)
|
|
|
|
.Case("+sse2", SSE2)
|
|
|
|
.Case("+sse", SSE1)
|
2011-07-08 23:31:17 +00:00
|
|
|
.Default(NoSSE);
|
2009-11-11 09:38:56 +00:00
|
|
|
SSELevel = std::max(SSELevel, Level);
|
2010-10-21 03:16:25 +00:00
|
|
|
|
2011-07-08 23:31:17 +00:00
|
|
|
MMX3DNowEnum ThreeDNowLevel =
|
2012-03-05 15:10:44 +00:00
|
|
|
llvm::StringSwitch<MMX3DNowEnum>(Feature)
|
2015-08-26 08:21:55 +00:00
|
|
|
.Case("+3dnowa", AMD3DNowAthlon)
|
|
|
|
.Case("+3dnow", AMD3DNow)
|
|
|
|
.Case("+mmx", MMX)
|
2011-07-08 23:31:17 +00:00
|
|
|
.Default(NoMMX3DNow);
|
|
|
|
MMX3DNowLevel = std::max(MMX3DNowLevel, ThreeDNowLevel);
|
2013-08-20 13:44:29 +00:00
|
|
|
|
|
|
|
XOPEnum XLevel = llvm::StringSwitch<XOPEnum>(Feature)
|
2015-08-26 08:21:55 +00:00
|
|
|
.Case("+xop", XOP)
|
|
|
|
.Case("+fma4", FMA4)
|
|
|
|
.Case("+sse4a", SSE4A)
|
2013-08-20 13:44:29 +00:00
|
|
|
.Default(NoXOP);
|
|
|
|
XOPLevel = std::max(XOPLevel, XLevel);
|
2009-11-11 09:38:56 +00:00
|
|
|
}
|
2011-07-08 23:31:17 +00:00
|
|
|
|
2013-08-21 21:59:03 +00:00
|
|
|
// LLVM doesn't have a separate switch for fpmath, so only accept it if it
|
|
|
|
// matches the selected sse level.
|
2015-10-20 00:00:17 +00:00
|
|
|
if ((FPMath == FP_SSE && SSELevel < SSE1) ||
|
|
|
|
(FPMath == FP_387 && SSELevel >= SSE1)) {
|
|
|
|
Diags.Report(diag::err_target_unsupported_fpmath) <<
|
|
|
|
(FPMath == FP_SSE ? "sse" : "387");
|
2013-08-21 21:59:03 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-07-02 03:40:19 +00:00
|
|
|
SimdDefaultAlign =
|
2015-08-27 22:24:56 +00:00
|
|
|
hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
|
2013-08-21 21:59:03 +00:00
|
|
|
return true;
|
2009-03-02 22:20:04 +00:00
|
|
|
}
|
2009-03-02 22:27:17 +00:00
|
|
|
|
2011-09-28 02:59:25 +00:00
|
|
|
/// X86TargetInfo::getTargetDefines - Return the set of the X86-specific macro
|
|
|
|
/// definitions for this particular subtarget.
|
2009-03-20 15:52:06 +00:00
|
|
|
void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
|
2010-01-09 17:55:51 +00:00
|
|
|
MacroBuilder &Builder) const {
|
2009-03-02 22:27:17 +00:00
|
|
|
// Target identification.
|
2012-10-11 15:52:22 +00:00
|
|
|
if (getTriple().getArch() == llvm::Triple::x86_64) {
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("__amd64__");
|
|
|
|
Builder.defineMacro("__amd64");
|
|
|
|
Builder.defineMacro("__x86_64");
|
|
|
|
Builder.defineMacro("__x86_64__");
|
2014-08-08 23:46:28 +00:00
|
|
|
if (getTriple().getArchName() == "x86_64h") {
|
|
|
|
Builder.defineMacro("__x86_64h");
|
|
|
|
Builder.defineMacro("__x86_64h__");
|
|
|
|
}
|
2009-03-02 22:27:17 +00:00
|
|
|
} else {
|
2010-01-09 17:55:51 +00:00
|
|
|
DefineStd(Builder, "i386", Opts);
|
2009-03-02 22:27:17 +00:00
|
|
|
}
|
2009-05-03 13:42:53 +00:00
|
|
|
|
2009-03-02 22:27:17 +00:00
|
|
|
// Subtarget options.
|
2011-09-28 02:59:25 +00: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 08:55:37 +00:00
|
|
|
switch (CPU) {
|
|
|
|
case CK_Generic:
|
|
|
|
break;
|
|
|
|
case CK_i386:
|
2011-09-28 02:59:25 +00:00
|
|
|
// The rest are coming from the i386 define above.
|
|
|
|
Builder.defineMacro("__tune_i386__");
|
2011-09-28 08:55:37 +00:00
|
|
|
break;
|
|
|
|
case CK_i486:
|
|
|
|
case CK_WinChipC6:
|
|
|
|
case CK_WinChip2:
|
|
|
|
case CK_C3:
|
2012-01-10 11:50:09 +00:00
|
|
|
defineCPUMacros(Builder, "i486");
|
2011-09-28 08:55:37 +00:00
|
|
|
break;
|
2011-09-28 09:45:05 +00:00
|
|
|
case CK_PentiumMMX:
|
|
|
|
Builder.defineMacro("__pentium_mmx__");
|
|
|
|
Builder.defineMacro("__tune_pentium_mmx__");
|
|
|
|
// Fallthrough
|
2011-09-28 08:55:37 +00:00
|
|
|
case CK_i586:
|
|
|
|
case CK_Pentium:
|
2012-01-10 11:50:09 +00:00
|
|
|
defineCPUMacros(Builder, "i586");
|
|
|
|
defineCPUMacros(Builder, "pentium");
|
2011-09-28 08:55:37 +00:00
|
|
|
break;
|
|
|
|
case CK_Pentium3:
|
|
|
|
case CK_Pentium3M:
|
|
|
|
case CK_PentiumM:
|
2011-09-28 09:45:05 +00:00
|
|
|
Builder.defineMacro("__tune_pentium3__");
|
|
|
|
// Fallthrough
|
|
|
|
case CK_Pentium2:
|
2011-09-28 08:55:37 +00:00
|
|
|
case CK_C3_2:
|
2011-09-28 09:45:05 +00:00
|
|
|
Builder.defineMacro("__tune_pentium2__");
|
|
|
|
// Fallthrough
|
|
|
|
case CK_PentiumPro:
|
|
|
|
Builder.defineMacro("__tune_i686__");
|
|
|
|
Builder.defineMacro("__tune_pentiumpro__");
|
|
|
|
// Fallthrough
|
|
|
|
case CK_i686:
|
2011-09-28 02:59:25 +00: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 08:55:37 +00:00
|
|
|
break;
|
|
|
|
case CK_Pentium4:
|
|
|
|
case CK_Pentium4M:
|
2012-01-10 11:50:09 +00:00
|
|
|
defineCPUMacros(Builder, "pentium4");
|
2011-09-28 08:55:37 +00:00
|
|
|
break;
|
|
|
|
case CK_Yonah:
|
|
|
|
case CK_Prescott:
|
|
|
|
case CK_Nocona:
|
2012-01-10 11:50:09 +00:00
|
|
|
defineCPUMacros(Builder, "nocona");
|
2011-09-28 08:55:37 +00:00
|
|
|
break;
|
|
|
|
case CK_Core2:
|
|
|
|
case CK_Penryn:
|
2012-01-10 11:50:09 +00:00
|
|
|
defineCPUMacros(Builder, "core2");
|
2011-09-28 08:55:37 +00:00
|
|
|
break;
|
2014-12-09 14:50:25 +00:00
|
|
|
case CK_Bonnell:
|
2012-01-10 11:50:09 +00:00
|
|
|
defineCPUMacros(Builder, "atom");
|
2011-09-28 08:55:37 +00:00
|
|
|
break;
|
2013-09-13 19:27:17 +00:00
|
|
|
case CK_Silvermont:
|
2013-08-30 14:05:34 +00:00
|
|
|
defineCPUMacros(Builder, "slm");
|
|
|
|
break;
|
2014-12-09 14:50:25 +00:00
|
|
|
case CK_Nehalem:
|
|
|
|
case CK_Westmere:
|
|
|
|
case CK_SandyBridge:
|
|
|
|
case CK_IvyBridge:
|
|
|
|
case CK_Haswell:
|
2014-09-19 09:53:48 +00:00
|
|
|
case CK_Broadwell:
|
2014-12-09 14:50:25 +00:00
|
|
|
// FIXME: Historically, we defined this legacy name, it would be nice to
|
|
|
|
// remove it at some point. We've never exposed fine-grained names for
|
|
|
|
// recent primary x86 CPUs, and we should keep it that way.
|
2012-01-10 11:50:09 +00:00
|
|
|
defineCPUMacros(Builder, "corei7");
|
2011-09-28 08:55:37 +00:00
|
|
|
break;
|
2014-12-09 14:50:25 +00:00
|
|
|
case CK_Skylake:
|
|
|
|
// FIXME: Historically, we defined this legacy name, it would be nice to
|
|
|
|
// remove it at some point. This is the only fine-grained CPU macro in the
|
|
|
|
// main intel CPU line, and it would be better to not have these and force
|
|
|
|
// people to use ISA macros.
|
|
|
|
defineCPUMacros(Builder, "skx");
|
|
|
|
break;
|
2013-08-20 07:09:39 +00:00
|
|
|
case CK_KNL:
|
|
|
|
defineCPUMacros(Builder, "knl");
|
|
|
|
break;
|
2011-09-28 08:55:37 +00:00
|
|
|
case CK_K6_2:
|
2011-09-28 09:45:05 +00:00
|
|
|
Builder.defineMacro("__k6_2__");
|
|
|
|
Builder.defineMacro("__tune_k6_2__");
|
|
|
|
// Fallthrough
|
2011-09-28 08:55:37 +00:00
|
|
|
case CK_K6_3:
|
2011-09-28 09:45:05 +00: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 02:59:25 +00:00
|
|
|
Builder.defineMacro("__k6_3__");
|
|
|
|
Builder.defineMacro("__tune_k6_3__");
|
|
|
|
}
|
2011-09-28 09:45:05 +00:00
|
|
|
// Fallthrough
|
|
|
|
case CK_K6:
|
2012-01-10 11:50:09 +00:00
|
|
|
defineCPUMacros(Builder, "k6");
|
2011-09-28 08:55:37 +00:00
|
|
|
break;
|
|
|
|
case CK_Athlon:
|
|
|
|
case CK_AthlonThunderbird:
|
|
|
|
case CK_Athlon4:
|
|
|
|
case CK_AthlonXP:
|
|
|
|
case CK_AthlonMP:
|
2012-01-10 11:50:09 +00:00
|
|
|
defineCPUMacros(Builder, "athlon");
|
2011-09-28 09:54:11 +00:00
|
|
|
if (SSELevel != NoSSE) {
|
2011-09-28 02:59:25 +00:00
|
|
|
Builder.defineMacro("__athlon_sse__");
|
2011-09-28 09:54:11 +00:00
|
|
|
Builder.defineMacro("__tune_athlon_sse__");
|
|
|
|
}
|
2011-09-28 08:55:37 +00: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 11:50:09 +00:00
|
|
|
defineCPUMacros(Builder, "k8");
|
2011-09-28 08:55:37 +00:00
|
|
|
break;
|
2011-10-30 07:48:46 +00:00
|
|
|
case CK_AMDFAM10:
|
2012-01-10 11:50:09 +00:00
|
|
|
defineCPUMacros(Builder, "amdfam10");
|
2011-10-30 07:48:46 +00:00
|
|
|
break;
|
2012-01-10 11:50:18 +00:00
|
|
|
case CK_BTVER1:
|
|
|
|
defineCPUMacros(Builder, "btver1");
|
|
|
|
break;
|
2013-05-03 10:47:15 +00:00
|
|
|
case CK_BTVER2:
|
|
|
|
defineCPUMacros(Builder, "btver2");
|
|
|
|
break;
|
2011-12-01 18:23:59 +00:00
|
|
|
case CK_BDVER1:
|
2012-01-10 11:50:09 +00:00
|
|
|
defineCPUMacros(Builder, "bdver1");
|
2011-12-01 18:23:59 +00:00
|
|
|
break;
|
|
|
|
case CK_BDVER2:
|
2012-01-10 11:50:09 +00:00
|
|
|
defineCPUMacros(Builder, "bdver2");
|
2011-12-01 18:23:59 +00:00
|
|
|
break;
|
2013-11-04 10:29:51 +00:00
|
|
|
case CK_BDVER3:
|
|
|
|
defineCPUMacros(Builder, "bdver3");
|
|
|
|
break;
|
2014-05-02 15:47:51 +00:00
|
|
|
case CK_BDVER4:
|
|
|
|
defineCPUMacros(Builder, "bdver4");
|
|
|
|
break;
|
2011-09-28 08:55:37 +00:00
|
|
|
case CK_Geode:
|
2012-01-10 11:50:09 +00:00
|
|
|
defineCPUMacros(Builder, "geode");
|
2011-09-28 08:55:37 +00:00
|
|
|
break;
|
2011-09-28 02:59:25 +00:00
|
|
|
}
|
2009-03-02 22:40:39 +00:00
|
|
|
|
2011-09-28 09:54:07 +00:00
|
|
|
// Target properties.
|
|
|
|
Builder.defineMacro("__REGISTER_PREFIX__", "");
|
|
|
|
|
2009-04-19 17:32:33 +00: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-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("__NO_MATH_INLINES");
|
2009-05-03 13:42:53 +00:00
|
|
|
|
2011-09-28 09:54:07 +00:00
|
|
|
if (HasAES)
|
|
|
|
Builder.defineMacro("__AES__");
|
|
|
|
|
2012-05-31 05:18:48 +00:00
|
|
|
if (HasPCLMUL)
|
|
|
|
Builder.defineMacro("__PCLMUL__");
|
|
|
|
|
2011-12-25 05:06:45 +00:00
|
|
|
if (HasLZCNT)
|
|
|
|
Builder.defineMacro("__LZCNT__");
|
|
|
|
|
2012-07-07 09:39:18 +00:00
|
|
|
if (HasRDRND)
|
|
|
|
Builder.defineMacro("__RDRND__");
|
|
|
|
|
2014-11-03 06:51:41 +00:00
|
|
|
if (HasFSGSBASE)
|
|
|
|
Builder.defineMacro("__FSGSBASE__");
|
|
|
|
|
2011-12-25 05:06:45 +00:00
|
|
|
if (HasBMI)
|
|
|
|
Builder.defineMacro("__BMI__");
|
|
|
|
|
|
|
|
if (HasBMI2)
|
|
|
|
Builder.defineMacro("__BMI2__");
|
|
|
|
|
2011-12-29 16:10:46 +00:00
|
|
|
if (HasPOPCNT)
|
|
|
|
Builder.defineMacro("__POPCNT__");
|
|
|
|
|
2012-11-10 05:17:46 +00:00
|
|
|
if (HasRTM)
|
|
|
|
Builder.defineMacro("__RTM__");
|
|
|
|
|
2013-03-26 17:52:08 +00:00
|
|
|
if (HasPRFCHW)
|
|
|
|
Builder.defineMacro("__PRFCHW__");
|
|
|
|
|
2013-03-29 05:17:55 +00:00
|
|
|
if (HasRDSEED)
|
|
|
|
Builder.defineMacro("__RDSEED__");
|
|
|
|
|
2014-09-19 09:53:48 +00:00
|
|
|
if (HasADX)
|
|
|
|
Builder.defineMacro("__ADX__");
|
|
|
|
|
2013-09-24 19:00:58 +00:00
|
|
|
if (HasTBM)
|
|
|
|
Builder.defineMacro("__TBM__");
|
|
|
|
|
2013-08-20 13:44:29 +00:00
|
|
|
switch (XOPLevel) {
|
|
|
|
case XOP:
|
|
|
|
Builder.defineMacro("__XOP__");
|
|
|
|
case FMA4:
|
2011-12-30 07:33:42 +00:00
|
|
|
Builder.defineMacro("__FMA4__");
|
2013-08-20 13:44:29 +00:00
|
|
|
case SSE4A:
|
|
|
|
Builder.defineMacro("__SSE4A__");
|
|
|
|
case NoXOP:
|
|
|
|
break;
|
|
|
|
}
|
2011-12-30 07:33:42 +00:00
|
|
|
|
2012-06-03 21:46:30 +00:00
|
|
|
if (HasFMA)
|
|
|
|
Builder.defineMacro("__FMA__");
|
|
|
|
|
2012-10-11 00:59:55 +00:00
|
|
|
if (HasF16C)
|
|
|
|
Builder.defineMacro("__F16C__");
|
|
|
|
|
2013-08-21 05:29:10 +00:00
|
|
|
if (HasAVX512CD)
|
|
|
|
Builder.defineMacro("__AVX512CD__");
|
|
|
|
if (HasAVX512ER)
|
|
|
|
Builder.defineMacro("__AVX512ER__");
|
|
|
|
if (HasAVX512PF)
|
|
|
|
Builder.defineMacro("__AVX512PF__");
|
2014-07-30 13:53:40 +00:00
|
|
|
if (HasAVX512DQ)
|
|
|
|
Builder.defineMacro("__AVX512DQ__");
|
|
|
|
if (HasAVX512BW)
|
|
|
|
Builder.defineMacro("__AVX512BW__");
|
|
|
|
if (HasAVX512VL)
|
|
|
|
Builder.defineMacro("__AVX512VL__");
|
2013-08-21 05:29:10 +00:00
|
|
|
|
2013-09-19 13:22:04 +00:00
|
|
|
if (HasSHA)
|
|
|
|
Builder.defineMacro("__SHA__");
|
|
|
|
|
2015-10-16 06:22:36 +00:00
|
|
|
if (HasFXSR)
|
|
|
|
Builder.defineMacro("__FXSR__");
|
2015-10-15 05:23:38 +00:00
|
|
|
if (HasXSAVE)
|
|
|
|
Builder.defineMacro("__XSAVE__");
|
|
|
|
if (HasXSAVEOPT)
|
|
|
|
Builder.defineMacro("__XSAVEOPT__");
|
|
|
|
if (HasXSAVEC)
|
|
|
|
Builder.defineMacro("__XSAVEC__");
|
|
|
|
if (HasXSAVES)
|
|
|
|
Builder.defineMacro("__XSAVES__");
|
2015-12-31 14:14:07 +00:00
|
|
|
if (HasPKU)
|
|
|
|
Builder.defineMacro("__PKU__");
|
2013-10-05 20:14:27 +00:00
|
|
|
if (HasCX16)
|
|
|
|
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16");
|
|
|
|
|
2009-03-02 22:40:39 +00:00
|
|
|
// Each case falls through to the previous one here.
|
|
|
|
switch (SSELevel) {
|
2013-08-21 03:59:22 +00:00
|
|
|
case AVX512F:
|
2013-08-20 07:39:54 +00:00
|
|
|
Builder.defineMacro("__AVX512F__");
|
2012-01-09 09:19:09 +00:00
|
|
|
case AVX2:
|
|
|
|
Builder.defineMacro("__AVX2__");
|
|
|
|
case AVX:
|
|
|
|
Builder.defineMacro("__AVX__");
|
2009-03-02 22:40:39 +00:00
|
|
|
case SSE42:
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("__SSE4_2__");
|
2009-03-02 22:40:39 +00:00
|
|
|
case SSE41:
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("__SSE4_1__");
|
2009-03-02 22:40:39 +00:00
|
|
|
case SSSE3:
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("__SSSE3__");
|
2009-03-02 22:40:39 +00:00
|
|
|
case SSE3:
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("__SSE3__");
|
2009-03-02 22:40:39 +00:00
|
|
|
case SSE2:
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("__SSE2__");
|
|
|
|
Builder.defineMacro("__SSE2_MATH__"); // -mfp-math=sse always implied.
|
2009-03-02 22:40:39 +00:00
|
|
|
case SSE1:
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("__SSE__");
|
|
|
|
Builder.defineMacro("__SSE_MATH__"); // -mfp-math=sse always implied.
|
2011-07-08 23:31:17 +00:00
|
|
|
case NoSSE:
|
2009-03-02 22:40:39 +00:00
|
|
|
break;
|
|
|
|
}
|
2010-10-18 07:10:59 +00:00
|
|
|
|
2012-10-11 15:52:22 +00:00
|
|
|
if (Opts.MicrosoftExt && getTriple().getArch() == llvm::Triple::x86) {
|
2010-10-21 05:21:48 +00:00
|
|
|
switch (SSELevel) {
|
2013-08-21 03:59:22 +00:00
|
|
|
case AVX512F:
|
2012-01-09 09:19:09 +00:00
|
|
|
case AVX2:
|
|
|
|
case AVX:
|
2010-10-21 08:22:51 +00:00
|
|
|
case SSE42:
|
|
|
|
case SSE41:
|
|
|
|
case SSSE3:
|
|
|
|
case SSE3:
|
2010-10-21 05:21:48 +00:00
|
|
|
case SSE2:
|
2011-07-23 10:55:15 +00:00
|
|
|
Builder.defineMacro("_M_IX86_FP", Twine(2));
|
2010-10-21 05:21:48 +00:00
|
|
|
break;
|
|
|
|
case SSE1:
|
2011-07-23 10:55:15 +00:00
|
|
|
Builder.defineMacro("_M_IX86_FP", Twine(1));
|
2010-10-21 05:21:48 +00:00
|
|
|
break;
|
|
|
|
default:
|
2011-07-23 10:55:15 +00:00
|
|
|
Builder.defineMacro("_M_IX86_FP", Twine(0));
|
2010-10-21 05:21:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-01-27 03:47:49 +00:00
|
|
|
// Each case falls through to the previous one here.
|
2011-07-08 23:31:17 +00:00
|
|
|
switch (MMX3DNowLevel) {
|
2010-01-27 03:47:49 +00:00
|
|
|
case AMD3DNowAthlon:
|
|
|
|
Builder.defineMacro("__3dNOW_A__");
|
|
|
|
case AMD3DNow:
|
|
|
|
Builder.defineMacro("__3dNOW__");
|
2011-07-08 23:31:17 +00:00
|
|
|
case MMX:
|
|
|
|
Builder.defineMacro("__MMX__");
|
|
|
|
case NoMMX3DNow:
|
2010-01-27 03:47:49 +00:00
|
|
|
break;
|
|
|
|
}
|
2013-04-04 23:53:43 +00: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-02 22:27:17 +00:00
|
|
|
}
|
2009-05-03 13:42:53 +00:00
|
|
|
|
2012-01-30 06:38:25 +00: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 03:59:22 +00:00
|
|
|
.Case("avx512f", SSELevel >= AVX512F)
|
2013-08-21 05:29:10 +00:00
|
|
|
.Case("avx512cd", HasAVX512CD)
|
|
|
|
.Case("avx512er", HasAVX512ER)
|
|
|
|
.Case("avx512pf", HasAVX512PF)
|
2014-07-30 13:53:40 +00:00
|
|
|
.Case("avx512dq", HasAVX512DQ)
|
|
|
|
.Case("avx512bw", HasAVX512BW)
|
|
|
|
.Case("avx512vl", HasAVX512VL)
|
2012-01-30 06:38:25 +00:00
|
|
|
.Case("bmi", HasBMI)
|
|
|
|
.Case("bmi2", HasBMI2)
|
2013-10-05 20:14:27 +00:00
|
|
|
.Case("cx16", HasCX16)
|
|
|
|
.Case("f16c", HasF16C)
|
2012-06-03 21:46:30 +00:00
|
|
|
.Case("fma", HasFMA)
|
2013-08-20 13:44:29 +00:00
|
|
|
.Case("fma4", XOPLevel >= FMA4)
|
2014-11-03 06:51:41 +00:00
|
|
|
.Case("fsgsbase", HasFSGSBASE)
|
2015-10-16 06:22:36 +00:00
|
|
|
.Case("fxsr", HasFXSR)
|
2014-11-03 07:05:26 +00:00
|
|
|
.Case("lzcnt", HasLZCNT)
|
2012-01-30 06:38:25 +00:00
|
|
|
.Case("mm3dnow", MMX3DNowLevel >= AMD3DNow)
|
|
|
|
.Case("mm3dnowa", MMX3DNowLevel >= AMD3DNowAthlon)
|
|
|
|
.Case("mmx", MMX3DNowLevel >= MMX)
|
2012-05-31 05:18:48 +00:00
|
|
|
.Case("pclmul", HasPCLMUL)
|
2012-01-30 06:38:25 +00:00
|
|
|
.Case("popcnt", HasPOPCNT)
|
2013-03-26 17:52:08 +00:00
|
|
|
.Case("prfchw", HasPRFCHW)
|
2014-11-03 07:05:26 +00:00
|
|
|
.Case("rdrnd", HasRDRND)
|
2013-03-29 05:17:55 +00:00
|
|
|
.Case("rdseed", HasRDSEED)
|
2014-11-03 07:05:26 +00:00
|
|
|
.Case("rtm", HasRTM)
|
2013-09-19 13:22:04 +00:00
|
|
|
.Case("sha", HasSHA)
|
2012-01-30 06:38:25 +00:00
|
|
|
.Case("sse", SSELevel >= SSE1)
|
|
|
|
.Case("sse2", SSELevel >= SSE2)
|
|
|
|
.Case("sse3", SSELevel >= SSE3)
|
|
|
|
.Case("ssse3", SSELevel >= SSSE3)
|
2013-08-23 20:21:37 +00:00
|
|
|
.Case("sse4.1", SSELevel >= SSE41)
|
|
|
|
.Case("sse4.2", SSELevel >= SSE42)
|
2013-08-20 13:44:29 +00:00
|
|
|
.Case("sse4a", XOPLevel >= SSE4A)
|
2014-11-03 07:05:26 +00:00
|
|
|
.Case("tbm", HasTBM)
|
2012-01-30 06:38:25 +00:00
|
|
|
.Case("x86", true)
|
2012-10-11 15:52:22 +00:00
|
|
|
.Case("x86_32", getTriple().getArch() == llvm::Triple::x86)
|
|
|
|
.Case("x86_64", getTriple().getArch() == llvm::Triple::x86_64)
|
2013-08-20 13:44:29 +00:00
|
|
|
.Case("xop", XOPLevel >= XOP)
|
2015-10-15 05:23:38 +00:00
|
|
|
.Case("xsave", HasXSAVE)
|
|
|
|
.Case("xsavec", HasXSAVEC)
|
|
|
|
.Case("xsaves", HasXSAVES)
|
|
|
|
.Case("xsaveopt", HasXSAVEOPT)
|
2015-12-31 14:14:07 +00:00
|
|
|
.Case("pku", HasPKU)
|
2012-01-30 06:38:25 +00:00
|
|
|
.Default(false);
|
|
|
|
}
|
2009-05-03 13:42:53 +00:00
|
|
|
|
2015-06-29 21:00:05 +00:00
|
|
|
// We can't use a generic validation scheme for the features accepted here
|
|
|
|
// versus subtarget features accepted in the target attribute because the
|
|
|
|
// bitfield structure that's initialized in the runtime only supports the
|
|
|
|
// below currently rather than the full range of subtarget features. (See
|
|
|
|
// X86TargetInfo::hasFeature for a somewhat comprehensive list).
|
|
|
|
bool X86TargetInfo::validateCpuSupports(StringRef FeatureStr) const {
|
|
|
|
return llvm::StringSwitch<bool>(FeatureStr)
|
|
|
|
.Case("cmov", true)
|
|
|
|
.Case("mmx", true)
|
|
|
|
.Case("popcnt", true)
|
|
|
|
.Case("sse", true)
|
|
|
|
.Case("sse2", true)
|
|
|
|
.Case("sse3", true)
|
|
|
|
.Case("sse4.1", true)
|
|
|
|
.Case("sse4.2", true)
|
|
|
|
.Case("avx", true)
|
|
|
|
.Case("avx2", true)
|
|
|
|
.Case("sse4a", true)
|
|
|
|
.Case("fma4", true)
|
|
|
|
.Case("xop", true)
|
|
|
|
.Case("fma", true)
|
|
|
|
.Case("avx512f", true)
|
|
|
|
.Case("bmi", true)
|
|
|
|
.Case("bmi2", true)
|
|
|
|
.Default(false);
|
|
|
|
}
|
|
|
|
|
2008-08-20 02:34:37 +00:00
|
|
|
bool
|
2009-02-28 17:11:49 +00:00
|
|
|
X86TargetInfo::validateAsmConstraint(const char *&Name,
|
2009-04-26 07:16:29 +00:00
|
|
|
TargetInfo::ConstraintInfo &Info) const {
|
2009-02-28 17:11:49 +00:00
|
|
|
switch (*Name) {
|
2008-08-20 02:34:37 +00:00
|
|
|
default: return false;
|
[X86, inlineasm] Improve analysis of x,Y0,Yi,Ym,Yt,L,e,Z,s asm constraints (patch by Alexey Frolov)
Improve Sema checking of 9 existing inline asm constraints (‘x’, ‘Y*’, ‘L’, ‘e’, ‘Z’, ‘s’).
Differential Revision: http://reviews.llvm.org/D10536
llvm-svn: 242665
2015-07-20 12:08:00 +00:00
|
|
|
// Constant constraints.
|
|
|
|
case 'e': // 32-bit signed integer constant for use with sign-extending x86_64
|
|
|
|
// instructions.
|
|
|
|
case 'Z': // 32-bit unsigned integer constant for use with zero-extending
|
|
|
|
// x86_64 instructions.
|
|
|
|
case 's':
|
|
|
|
Info.setRequiresImmediate();
|
|
|
|
return true;
|
2015-01-06 04:26:34 +00:00
|
|
|
case 'I':
|
|
|
|
Info.setRequiresImmediate(0, 31);
|
|
|
|
return true;
|
|
|
|
case 'J':
|
|
|
|
Info.setRequiresImmediate(0, 63);
|
|
|
|
return true;
|
|
|
|
case 'K':
|
|
|
|
Info.setRequiresImmediate(-128, 127);
|
|
|
|
return true;
|
|
|
|
case 'L':
|
[X86, inlineasm] Improve analysis of x,Y0,Yi,Ym,Yt,L,e,Z,s asm constraints (patch by Alexey Frolov)
Improve Sema checking of 9 existing inline asm constraints (‘x’, ‘Y*’, ‘L’, ‘e’, ‘Z’, ‘s’).
Differential Revision: http://reviews.llvm.org/D10536
llvm-svn: 242665
2015-07-20 12:08:00 +00:00
|
|
|
Info.setRequiresImmediate({ int(0xff), int(0xffff), int(0xffffffff) });
|
2015-01-06 04:26:34 +00:00
|
|
|
return true;
|
|
|
|
case 'M':
|
|
|
|
Info.setRequiresImmediate(0, 3);
|
|
|
|
return true;
|
|
|
|
case 'N':
|
|
|
|
Info.setRequiresImmediate(0, 255);
|
|
|
|
return true;
|
|
|
|
case 'O':
|
|
|
|
Info.setRequiresImmediate(0, 127);
|
|
|
|
return true;
|
[X86, inlineasm] Improve analysis of x,Y0,Yi,Ym,Yt,L,e,Z,s asm constraints (patch by Alexey Frolov)
Improve Sema checking of 9 existing inline asm constraints (‘x’, ‘Y*’, ‘L’, ‘e’, ‘Z’, ‘s’).
Differential Revision: http://reviews.llvm.org/D10536
llvm-svn: 242665
2015-07-20 12:08:00 +00:00
|
|
|
// Register constraints.
|
|
|
|
case 'Y': // 'Y' is the first character for several 2-character constraints.
|
|
|
|
// Shift the pointer to the second character of the constraint.
|
|
|
|
Name++;
|
|
|
|
switch (*Name) {
|
|
|
|
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.
|
|
|
|
Info.setAllowsRegister();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
case 'f': // Any x87 floating point stack register.
|
2014-07-18 23:30:30 +00:00
|
|
|
// Constraint 'f' cannot be used for output operands.
|
|
|
|
if (Info.ConstraintStr[0] == '=')
|
|
|
|
return false;
|
|
|
|
Info.setAllowsRegister();
|
|
|
|
return true;
|
2008-08-20 02:34:37 +00:00
|
|
|
case 'a': // eax.
|
|
|
|
case 'b': // ebx.
|
|
|
|
case 'c': // ecx.
|
|
|
|
case 'd': // edx.
|
|
|
|
case 'S': // esi.
|
|
|
|
case 'D': // edi.
|
|
|
|
case 'A': // edx:eax.
|
[X86, inlineasm] Improve analysis of x,Y0,Yi,Ym,Yt,L,e,Z,s asm constraints (patch by Alexey Frolov)
Improve Sema checking of 9 existing inline asm constraints (‘x’, ‘Y*’, ‘L’, ‘e’, ‘Z’, ‘s’).
Differential Revision: http://reviews.llvm.org/D10536
llvm-svn: 242665
2015-07-20 12:08:00 +00:00
|
|
|
case 't': // Top of floating point stack.
|
|
|
|
case 'u': // Second from top of floating point stack.
|
2008-08-20 02:34:37 +00:00
|
|
|
case 'q': // Any register accessible as [r]l: a, b, c, and d.
|
2008-10-06 00:41:45 +00:00
|
|
|
case 'y': // Any MMX register.
|
2008-10-06 19:17:39 +00:00
|
|
|
case 'x': // Any SSE register.
|
2008-08-20 02:34:37 +00:00
|
|
|
case 'Q': // Any register accessible as [r]h: a, b, c, and d.
|
2010-08-24 22:33:12 +00: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;
|
[X86, inlineasm] Improve analysis of x,Y0,Yi,Ym,Yt,L,e,Z,s asm constraints (patch by Alexey Frolov)
Improve Sema checking of 9 existing inline asm constraints (‘x’, ‘Y*’, ‘L’, ‘e’, ‘Z’, ‘s’).
Differential Revision: http://reviews.llvm.org/D10536
llvm-svn: 242665
2015-07-20 12:08:00 +00:00
|
|
|
// Floating point constant constraints.
|
2010-08-24 22:33:12 +00:00
|
|
|
case 'C': // SSE floating point constant.
|
|
|
|
case 'G': // x87 floating point constant.
|
2008-08-20 02:34:37 +00:00
|
|
|
return true;
|
2007-11-27 04:11:28 +00:00
|
|
|
}
|
2008-08-20 02:34:37 +00:00
|
|
|
}
|
2008-02-26 18:33:46 +00:00
|
|
|
|
2014-09-18 18:17:18 +00:00
|
|
|
bool X86TargetInfo::validateOutputSize(StringRef Constraint,
|
|
|
|
unsigned Size) const {
|
|
|
|
// Strip off constraint modifiers.
|
|
|
|
while (Constraint[0] == '=' ||
|
|
|
|
Constraint[0] == '+' ||
|
|
|
|
Constraint[0] == '&')
|
|
|
|
Constraint = Constraint.substr(1);
|
|
|
|
|
|
|
|
return validateOperandSize(Constraint, Size);
|
|
|
|
}
|
|
|
|
|
[X86, inline-asm] Check that the input size is correct for constraints R, q, Q,
S, D, A, y, x, f, t, and u.
This is a follow-up patch for r167717.
rdar://problem/11846140
rdar://problem/17476970
llvm-svn: 217994
2014-09-17 23:35:14 +00:00
|
|
|
bool X86TargetInfo::validateInputSize(StringRef Constraint,
|
|
|
|
unsigned Size) const {
|
2014-09-18 18:17:18 +00:00
|
|
|
return validateOperandSize(Constraint, Size);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool X86TargetInfo::validateOperandSize(StringRef Constraint,
|
|
|
|
unsigned Size) const {
|
[X86, inline-asm] Check that the input size is correct for constraints R, q, Q,
S, D, A, y, x, f, t, and u.
This is a follow-up patch for r167717.
rdar://problem/11846140
rdar://problem/17476970
llvm-svn: 217994
2014-09-17 23:35:14 +00:00
|
|
|
switch (Constraint[0]) {
|
|
|
|
default: break;
|
|
|
|
case 'y':
|
|
|
|
return Size <= 64;
|
|
|
|
case 'f':
|
|
|
|
case 't':
|
|
|
|
case 'u':
|
|
|
|
return Size <= 128;
|
2014-09-18 20:24:04 +00:00
|
|
|
case 'x':
|
[X86, inlineasm] Improve analysis of x,Y0,Yi,Ym,Yt,L,e,Z,s asm constraints (patch by Alexey Frolov)
Improve Sema checking of 9 existing inline asm constraints (‘x’, ‘Y*’, ‘L’, ‘e’, ‘Z’, ‘s’).
Differential Revision: http://reviews.llvm.org/D10536
llvm-svn: 242665
2015-07-20 12:08:00 +00:00
|
|
|
if (SSELevel >= AVX512F)
|
|
|
|
// 512-bit zmm registers can be used if target supports AVX512F.
|
|
|
|
return Size <= 512U;
|
|
|
|
else if (SSELevel >= AVX)
|
|
|
|
// 256-bit ymm registers can be used if target supports AVX.
|
|
|
|
return Size <= 256U;
|
|
|
|
return Size <= 128U;
|
|
|
|
case 'Y':
|
|
|
|
// 'Y' is the first character for several 2-character constraints.
|
|
|
|
switch (Constraint[1]) {
|
|
|
|
default: break;
|
|
|
|
case 'm':
|
|
|
|
// 'Ym' is synonymous with 'y'.
|
|
|
|
return Size <= 64;
|
|
|
|
case 'i':
|
|
|
|
case 't':
|
|
|
|
// 'Yi' and 'Yt' are synonymous with 'x' when SSE2 is enabled.
|
|
|
|
if (SSELevel >= AVX512F)
|
|
|
|
return Size <= 512U;
|
|
|
|
else if (SSELevel >= AVX)
|
|
|
|
return Size <= 256U;
|
|
|
|
return SSELevel >= SSE2 && Size <= 128U;
|
|
|
|
}
|
|
|
|
|
[X86, inline-asm] Check that the input size is correct for constraints R, q, Q,
S, D, A, y, x, f, t, and u.
This is a follow-up patch for r167717.
rdar://problem/11846140
rdar://problem/17476970
llvm-svn: 217994
2014-09-17 23:35:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2010-10-29 23:12:32 +00:00
|
|
|
|
2008-08-20 02:34:37 +00:00
|
|
|
std::string
|
2011-06-07 23:45:05 +00:00
|
|
|
X86TargetInfo::convertConstraint(const char *&Constraint) const {
|
|
|
|
switch (*Constraint) {
|
2008-08-20 02:34:37 +00: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-22 21:07:10 +00:00
|
|
|
case 'p': // address
|
|
|
|
return std::string("im");
|
2008-08-20 02:34:37 +00: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-07 23:45:05 +00:00
|
|
|
return std::string(1, *Constraint);
|
2008-02-26 18:33:46 +00:00
|
|
|
}
|
2008-08-20 02:34:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// X86-32 generic target
|
|
|
|
class X86_32TargetInfo : public X86TargetInfo {
|
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
X86_32TargetInfo(const llvm::Triple &Triple) : X86TargetInfo(Triple) {
|
2008-08-20 02:34:37 +00:00
|
|
|
DoubleAlign = LongLongAlign = 32;
|
|
|
|
LongDoubleWidth = 96;
|
|
|
|
LongDoubleAlign = 32;
|
2011-12-21 04:25:47 +00:00
|
|
|
SuitableAlign = 128;
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128";
|
2009-03-29 20:31:09 +00:00
|
|
|
SizeType = UnsignedInt;
|
|
|
|
PtrDiffType = SignedInt;
|
|
|
|
IntPtrType = SignedInt;
|
2009-04-03 23:38:25 +00:00
|
|
|
RegParmMax = 3;
|
2010-07-14 23:39:36 +00:00
|
|
|
|
|
|
|
// Use fpret for all types.
|
|
|
|
RealTypeUsesObjCFPRet = ((1 << TargetInfo::Float) |
|
|
|
|
(1 << TargetInfo::Double) |
|
|
|
|
(1 << TargetInfo::LongDouble));
|
2011-10-14 20:59:01 +00: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 02:34:37 +00:00
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
BuiltinVaListKind getBuiltinVaListKind() const override {
|
2012-06-16 03:34:49 +00:00
|
|
|
return TargetInfo::CharPtrBuiltinVaList;
|
2008-08-20 02:34:37 +00:00
|
|
|
}
|
2010-10-21 03:16:25 +00:00
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
int getEHDataRegisterNumber(unsigned RegNo) const override {
|
2009-09-23 06:06:36 +00:00
|
|
|
if (RegNo == 0) return 0;
|
|
|
|
if (RegNo == 1) return 2;
|
|
|
|
return -1;
|
|
|
|
}
|
2014-09-18 18:17:18 +00:00
|
|
|
bool validateOperandSize(StringRef Constraint,
|
|
|
|
unsigned Size) const override {
|
2012-11-12 06:42:51 +00:00
|
|
|
switch (Constraint[0]) {
|
|
|
|
default: break;
|
[X86, inline-asm] Check that the input size is correct for constraints R, q, Q,
S, D, A, y, x, f, t, and u.
This is a follow-up patch for r167717.
rdar://problem/11846140
rdar://problem/17476970
llvm-svn: 217994
2014-09-17 23:35:14 +00:00
|
|
|
case 'R':
|
|
|
|
case 'q':
|
|
|
|
case 'Q':
|
2012-11-12 06:42:51 +00:00
|
|
|
case 'a':
|
|
|
|
case 'b':
|
|
|
|
case 'c':
|
|
|
|
case 'd':
|
[X86, inline-asm] Check that the input size is correct for constraints R, q, Q,
S, D, A, y, x, f, t, and u.
This is a follow-up patch for r167717.
rdar://problem/11846140
rdar://problem/17476970
llvm-svn: 217994
2014-09-17 23:35:14 +00:00
|
|
|
case 'S':
|
|
|
|
case 'D':
|
2012-11-12 18:52:32 +00:00
|
|
|
return Size <= 32;
|
[X86, inline-asm] Check that the input size is correct for constraints R, q, Q,
S, D, A, y, x, f, t, and u.
This is a follow-up patch for r167717.
rdar://problem/11846140
rdar://problem/17476970
llvm-svn: 217994
2014-09-17 23:35:14 +00:00
|
|
|
case 'A':
|
|
|
|
return Size <= 64;
|
2012-11-12 06:42:51 +00:00
|
|
|
}
|
|
|
|
|
2014-09-18 18:17:18 +00:00
|
|
|
return X86TargetInfo::validateOperandSize(Constraint, Size);
|
2012-11-12 06:42:51 +00:00
|
|
|
}
|
2006-10-14 07:39:34 +00:00
|
|
|
};
|
|
|
|
|
2012-01-06 18:32:26 +00:00
|
|
|
class NetBSDI386TargetInfo : public NetBSDTargetInfo<X86_32TargetInfo> {
|
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
NetBSDI386TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: NetBSDTargetInfo<X86_32TargetInfo>(Triple) {}
|
2012-01-06 18:32:26 +00:00
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
unsigned getFloatEvalMethod() const override {
|
2013-11-11 14:00:37 +00: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-06 18:32:26 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2009-07-05 18:47:56 +00:00
|
|
|
class OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> {
|
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
OpenBSDI386TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: OpenBSDTargetInfo<X86_32TargetInfo>(Triple) {
|
2009-07-05 18:47:56 +00:00
|
|
|
SizeType = UnsignedLong;
|
|
|
|
IntPtrType = SignedLong;
|
2009-07-05 22:31:18 +00:00
|
|
|
PtrDiffType = SignedLong;
|
2009-07-05 18:47:56 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2012-08-08 23:57:20 +00:00
|
|
|
class BitrigI386TargetInfo : public BitrigTargetInfo<X86_32TargetInfo> {
|
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
BitrigI386TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: BitrigTargetInfo<X86_32TargetInfo>(Triple) {
|
2012-08-08 23:57:20 +00:00
|
|
|
SizeType = UnsignedLong;
|
|
|
|
IntPtrType = SignedLong;
|
|
|
|
PtrDiffType = SignedLong;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2009-06-30 17:10:35 +00:00
|
|
|
class DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> {
|
2006-10-14 07:39:34 +00:00
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
DarwinI386TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: DarwinTargetInfo<X86_32TargetInfo>(Triple) {
|
2008-05-20 14:21:01 +00:00
|
|
|
LongDoubleWidth = 128;
|
|
|
|
LongDoubleAlign = 128;
|
2011-12-16 22:34:14 +00:00
|
|
|
SuitableAlign = 128;
|
2015-10-30 16:30:45 +00:00
|
|
|
MaxVectorAlign = 256;
|
|
|
|
// The watchOS simulator uses the builtin bool type for Objective-C.
|
|
|
|
llvm::Triple T = llvm::Triple(Triple);
|
|
|
|
if (T.isWatchOS())
|
|
|
|
UseSignedCharForObjCBool = false;
|
2009-03-29 20:31:09 +00:00
|
|
|
SizeType = UnsignedLong;
|
|
|
|
IntPtrType = SignedLong;
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = "e-m:o-p:32:32-f64:32:64-f80:128-n8:16:32-S128";
|
2010-05-27 00:35:16 +00:00
|
|
|
HasAlignMac68kSupport = true;
|
2008-08-23 18:23:14 +00:00
|
|
|
}
|
|
|
|
|
2015-08-27 22:30:38 +00:00
|
|
|
bool handleTargetFeatures(std::vector<std::string> &Features,
|
|
|
|
DiagnosticsEngine &Diags) override {
|
|
|
|
if (!DarwinTargetInfo<X86_32TargetInfo>::handleTargetFeatures(Features,
|
|
|
|
Diags))
|
|
|
|
return false;
|
2015-08-27 22:42:12 +00:00
|
|
|
// We now know the features we have: we can decide how to align vectors.
|
|
|
|
MaxVectorAlign =
|
|
|
|
hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
|
2015-08-27 22:30:38 +00:00
|
|
|
return true;
|
|
|
|
}
|
2009-06-30 17:00:25 +00:00
|
|
|
};
|
2008-08-21 00:24:02 +00: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 01:40:19 +00:00
|
|
|
// x86-32 Windows target
|
2010-10-21 05:21:48 +00: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 01:40:19 +00:00
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
WindowsX86_32TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: WindowsTargetInfo<X86_32TargetInfo>(Triple) {
|
2009-06-24 17:12:15 +00:00
|
|
|
WCharType = UnsignedShort;
|
2009-06-08 21:16:17 +00:00
|
|
|
DoubleAlign = LongLongAlign = 64;
|
2015-04-01 16:45:06 +00:00
|
|
|
bool IsWinCOFF =
|
|
|
|
getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = IsWinCOFF
|
|
|
|
? "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
|
|
|
|
: "e-m:e-p:32:32-i64:64-f80:32-n8:16:32-a:0: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 01:40:19 +00:00
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
2010-10-21 08:22:51 +00:00
|
|
|
WindowsTargetInfo<X86_32TargetInfo>::getTargetDefines(Opts, Builder);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// x86-32 Windows Visual Studio target
|
2014-04-04 05:08:53 +00:00
|
|
|
class MicrosoftX86_32TargetInfo : public WindowsX86_32TargetInfo {
|
2010-10-21 08:22:51 +00:00
|
|
|
public:
|
2014-04-04 05:08:53 +00:00
|
|
|
MicrosoftX86_32TargetInfo(const llvm::Triple &Triple)
|
2013-06-29 16:37:14 +00:00
|
|
|
: WindowsX86_32TargetInfo(Triple) {
|
2011-03-22 21:25:11 +00:00
|
|
|
LongDoubleWidth = LongDoubleAlign = 64;
|
2010-10-21 08:22:51 +00:00
|
|
|
LongDoubleFormat = &llvm::APFloat::IEEEdouble;
|
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
2010-10-21 08:22:51 +00:00
|
|
|
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 07:31:35 +00:00
|
|
|
};
|
|
|
|
|
2015-05-28 04:36:18 +00:00
|
|
|
static void addCygMingDefines(const LangOptions &Opts, MacroBuilder &Builder) {
|
2015-10-09 18:39:59 +00:00
|
|
|
// Mingw and cygwin define __declspec(a) to __attribute__((a)). Clang
|
|
|
|
// supports __declspec natively under -fms-extensions, but we define a no-op
|
|
|
|
// __declspec macro anyway for pre-processor compatibility.
|
2014-04-21 20:58:00 +00:00
|
|
|
if (Opts.MicrosoftExt)
|
|
|
|
Builder.defineMacro("__declspec", "__declspec");
|
|
|
|
else
|
|
|
|
Builder.defineMacro("__declspec(a)", "__attribute__((a))");
|
|
|
|
|
|
|
|
if (!Opts.MicrosoftExt) {
|
|
|
|
// Provide macros for all the calling convention keywords. Provide both
|
|
|
|
// single and double underscore prefixed variants. These are available on
|
|
|
|
// x64 as well as x86, even though they have no effect.
|
|
|
|
const char *CCs[] = {"cdecl", "stdcall", "fastcall", "thiscall", "pascal"};
|
|
|
|
for (const char *CC : CCs) {
|
2014-04-21 22:29:45 +00:00
|
|
|
std::string GCCSpelling = "__attribute__((__";
|
|
|
|
GCCSpelling += CC;
|
|
|
|
GCCSpelling += "__))";
|
2014-04-21 20:58:00 +00:00
|
|
|
Builder.defineMacro(Twine("_") + CC, GCCSpelling);
|
|
|
|
Builder.defineMacro(Twine("__") + CC, GCCSpelling);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-28 04:36:18 +00:00
|
|
|
static void addMinGWDefines(const LangOptions &Opts, MacroBuilder &Builder) {
|
|
|
|
Builder.defineMacro("__MSVCRT__");
|
|
|
|
Builder.defineMacro("__MINGW32__");
|
|
|
|
addCygMingDefines(Opts, Builder);
|
|
|
|
}
|
|
|
|
|
2009-09-23 07:31:35 +00:00
|
|
|
// x86-32 MinGW target
|
|
|
|
class MinGWX86_32TargetInfo : public WindowsX86_32TargetInfo {
|
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
MinGWX86_32TargetInfo(const llvm::Triple &Triple)
|
2015-08-20 21:36:14 +00:00
|
|
|
: WindowsX86_32TargetInfo(Triple) {}
|
2014-03-11 03:39:26 +00:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
2010-01-09 17:55:51 +00:00
|
|
|
WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
|
2010-10-21 08:22:51 +00:00
|
|
|
DefineStd(Builder, "WIN32", Opts);
|
|
|
|
DefineStd(Builder, "WINNT", Opts);
|
|
|
|
Builder.defineMacro("_X86_");
|
2014-04-21 20:58:00 +00:00
|
|
|
addMinGWDefines(Opts, Builder);
|
2009-09-23 07:31:35 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// x86-32 Cygwin target
|
|
|
|
class CygwinX86_32TargetInfo : public X86_32TargetInfo {
|
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
CygwinX86_32TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: X86_32TargetInfo(Triple) {
|
2009-09-23 07:31:35 +00:00
|
|
|
WCharType = UnsignedShort;
|
|
|
|
DoubleAlign = LongLongAlign = 64;
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32";
|
2009-09-23 07:31:35 +00:00
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
2010-01-09 17:55:51 +00:00
|
|
|
X86_32TargetInfo::getTargetDefines(Opts, Builder);
|
2012-12-14 10:17:26 +00:00
|
|
|
Builder.defineMacro("_X86_");
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("__CYGWIN__");
|
|
|
|
Builder.defineMacro("__CYGWIN32__");
|
2015-05-28 04:36:18 +00:00
|
|
|
addCygMingDefines(Opts, Builder);
|
2010-01-09 17:55:51 +00:00
|
|
|
DefineStd(Builder, "unix", Opts);
|
2010-04-21 05:52:38 +00:00
|
|
|
if (Opts.CPlusPlus)
|
|
|
|
Builder.defineMacro("_GNU_SOURCE");
|
2009-06-08 06:11:14 +00: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 01:40:19 +00:00
|
|
|
};
|
|
|
|
|
2010-04-11 19:29:39 +00:00
|
|
|
// x86-32 Haiku target
|
|
|
|
class HaikuX86_32TargetInfo : public X86_32TargetInfo {
|
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
HaikuX86_32TargetInfo(const llvm::Triple &Triple) : X86_32TargetInfo(Triple) {
|
2010-04-11 19:29:39 +00:00
|
|
|
SizeType = UnsignedLong;
|
2010-04-22 17:48:00 +00:00
|
|
|
IntPtrType = SignedLong;
|
|
|
|
PtrDiffType = SignedLong;
|
2012-11-27 02:58:24 +00:00
|
|
|
ProcessIDType = SignedLong;
|
2016-01-27 01:04:51 +00:00
|
|
|
this->UserLabelPrefix = "";
|
2012-11-08 12:59:15 +00:00
|
|
|
this->TLSSupported = false;
|
2010-08-22 01:00:03 +00:00
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
2010-04-11 19:29:39 +00:00
|
|
|
X86_32TargetInfo::getTargetDefines(Opts, Builder);
|
|
|
|
Builder.defineMacro("__INTEL__");
|
|
|
|
Builder.defineMacro("__HAIKU__");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-11-25 09:24:26 +00:00
|
|
|
// X86-32 MCU target
|
|
|
|
class MCUX86_32TargetInfo : public X86_32TargetInfo {
|
|
|
|
public:
|
|
|
|
MCUX86_32TargetInfo(const llvm::Triple &Triple) : X86_32TargetInfo(Triple) {
|
|
|
|
LongDoubleWidth = 64;
|
|
|
|
LongDoubleFormat = &llvm::APFloat::IEEEdouble;
|
2016-01-14 10:59:36 +00:00
|
|
|
UserLabelPrefix = "";
|
2015-11-25 09:24:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
|
|
|
|
// On MCU we support only C calling convention.
|
|
|
|
return CC == CC_C ? CCCR_OK : CCCR_Warning;
|
|
|
|
}
|
|
|
|
|
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
|
|
|
X86_32TargetInfo::getTargetDefines(Opts, Builder);
|
|
|
|
Builder.defineMacro("__iamcu");
|
|
|
|
Builder.defineMacro("__iamcu__");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2011-07-01 22:41:14 +00:00
|
|
|
// RTEMS Target
|
|
|
|
template<typename Target>
|
|
|
|
class RTEMSTargetInfo : public OSTargetInfo<Target> {
|
|
|
|
protected:
|
2014-03-11 03:39:26 +00:00
|
|
|
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
|
|
|
MacroBuilder &Builder) const override {
|
2011-07-01 22:41:14 +00:00
|
|
|
// RTEMS defines; list based off of gcc output
|
|
|
|
|
|
|
|
Builder.defineMacro("__rtems__");
|
|
|
|
Builder.defineMacro("__ELF__");
|
|
|
|
}
|
|
|
|
|
2013-06-29 16:37:14 +00:00
|
|
|
public:
|
|
|
|
RTEMSTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
|
2016-01-27 01:04:51 +00:00
|
|
|
this->UserLabelPrefix = "";
|
|
|
|
|
2013-06-29 16:37:14 +00: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 01:36:11 +00:00
|
|
|
case llvm::Triple::ppc64le:
|
2013-06-29 16:37:14 +00:00
|
|
|
// this->MCountName = "_mcount";
|
|
|
|
break;
|
|
|
|
case llvm::Triple::arm:
|
|
|
|
// this->MCountName = "__mcount";
|
|
|
|
break;
|
2011-07-01 22:41:14 +00:00
|
|
|
}
|
2013-06-29 16:37:14 +00:00
|
|
|
}
|
2011-07-01 22:41:14 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// x86-32 RTEMS target
|
|
|
|
class RTEMSX86_32TargetInfo : public X86_32TargetInfo {
|
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
RTEMSX86_32TargetInfo(const llvm::Triple &Triple) : X86_32TargetInfo(Triple) {
|
2011-07-01 22:41:14 +00:00
|
|
|
SizeType = UnsignedLong;
|
|
|
|
IntPtrType = SignedLong;
|
|
|
|
PtrDiffType = SignedLong;
|
2016-01-27 01:04:51 +00:00
|
|
|
this->UserLabelPrefix = "";
|
2011-07-01 22:41:14 +00:00
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
2011-07-01 22:41:14 +00:00
|
|
|
X86_32TargetInfo::getTargetDefines(Opts, Builder);
|
|
|
|
Builder.defineMacro("__INTEL__");
|
|
|
|
Builder.defineMacro("__rtems__");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2008-08-20 02:34:37 +00:00
|
|
|
// x86-64 generic target
|
|
|
|
class X86_64TargetInfo : public X86TargetInfo {
|
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
X86_64TargetInfo(const llvm::Triple &Triple) : X86TargetInfo(Triple) {
|
2014-07-10 18:46:15 +00:00
|
|
|
const bool IsX32 = getTriple().getEnvironment() == llvm::Triple::GNUX32;
|
2015-03-17 23:55:00 +00:00
|
|
|
bool IsWinCOFF =
|
|
|
|
getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
|
2014-07-10 15:27:19 +00:00
|
|
|
LongWidth = LongAlign = PointerWidth = PointerAlign = IsX32 ? 32 : 64;
|
2008-08-20 02:34:37 +00:00
|
|
|
LongDoubleWidth = 128;
|
|
|
|
LongDoubleAlign = 128;
|
2010-06-04 23:15:27 +00:00
|
|
|
LargeArrayMinWidth = 128;
|
|
|
|
LargeArrayAlign = 128;
|
2011-12-16 22:34:14 +00:00
|
|
|
SuitableAlign = 128;
|
2014-07-10 15:27:19 +00:00
|
|
|
SizeType = IsX32 ? UnsignedInt : UnsignedLong;
|
|
|
|
PtrDiffType = IsX32 ? SignedInt : SignedLong;
|
|
|
|
IntPtrType = IsX32 ? SignedInt : SignedLong;
|
|
|
|
IntMaxType = IsX32 ? SignedLongLong : SignedLong;
|
|
|
|
Int64Type = IsX32 ? SignedLongLong : SignedLong;
|
2009-04-03 23:38:25 +00:00
|
|
|
RegParmMax = 6;
|
2009-02-05 07:32:46 +00:00
|
|
|
|
2014-11-18 22:36:15 +00:00
|
|
|
// Pointers are 32-bit in x32.
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = IsX32 ? "e-m:e-p:32:32-i64:64-f80:128-n8:16:32:64-S128"
|
|
|
|
: IsWinCOFF
|
|
|
|
? "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
|
|
|
|
: "e-m:e-i64:64-f80:128-n8:16:32:64-S128";
|
2010-07-14 23:39:36 +00:00
|
|
|
|
|
|
|
// Use fpret only for long double.
|
|
|
|
RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble);
|
2011-10-14 20:59:01 +00:00
|
|
|
|
2011-10-31 16:27:11 +00:00
|
|
|
// Use fp2ret for _Complex long double.
|
|
|
|
ComplexLongDoubleUsesFP2Ret = true;
|
|
|
|
|
2015-09-17 20:55:33 +00:00
|
|
|
// Make __builtin_ms_va_list available.
|
|
|
|
HasBuiltinMSVaList = true;
|
|
|
|
|
2011-10-14 20:59:01 +00:00
|
|
|
// x86-64 has atomics up to 16 bytes.
|
|
|
|
MaxAtomicPromoteWidth = 128;
|
2014-07-02 10:25:45 +00:00
|
|
|
MaxAtomicInlineWidth = 128;
|
2007-01-29 05:24:35 +00:00
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
BuiltinVaListKind getBuiltinVaListKind() const override {
|
2012-06-16 03:34:49 +00:00
|
|
|
return TargetInfo::X86_64ABIBuiltinVaList;
|
2007-11-24 23:38:12 +00:00
|
|
|
}
|
2010-10-18 07:10:59 +00:00
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
int getEHDataRegisterNumber(unsigned RegNo) const override {
|
2009-09-23 06:06:36 +00:00
|
|
|
if (RegNo == 0) return 0;
|
|
|
|
if (RegNo == 1) return 1;
|
|
|
|
return -1;
|
|
|
|
}
|
2012-10-02 14:26:08 +00:00
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
|
2013-08-30 04:39:01 +00:00
|
|
|
return (CC == CC_C ||
|
2014-10-31 22:00:51 +00:00
|
|
|
CC == CC_X86VectorCall ||
|
2013-08-30 04:39:01 +00:00
|
|
|
CC == CC_IntelOclBicc ||
|
|
|
|
CC == CC_X86_64Win64) ? CCCR_OK : CCCR_Warning;
|
2012-10-02 14:26:08 +00:00
|
|
|
}
|
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
CallingConv getDefaultCallingConv(CallingConvMethodType MT) const override {
|
2012-12-09 17:45:41 +00:00
|
|
|
return CC_C;
|
2012-10-02 14:26:08 +00:00
|
|
|
}
|
|
|
|
|
2014-08-04 12:39:43 +00:00
|
|
|
// for x32 we need it here explicitly
|
|
|
|
bool hasInt128Type() const override { return true; }
|
2016-02-01 18:58:24 +00:00
|
|
|
unsigned getUnwindWordWidth() const override { return 64; }
|
|
|
|
unsigned getRegisterWidth() const override { return 64; }
|
2015-11-18 00:15:28 +00:00
|
|
|
|
|
|
|
bool validateGlobalRegisterVariable(StringRef RegName,
|
|
|
|
unsigned RegSize,
|
|
|
|
bool &HasSizeMismatch) const override {
|
|
|
|
// rsp and rbp are the only 64-bit registers the x86 backend can currently
|
|
|
|
// handle.
|
|
|
|
if (RegName.equals("rsp") || RegName.equals("rbp")) {
|
|
|
|
// Check that the register size is 64-bit.
|
|
|
|
HasSizeMismatch = RegSize != 64;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check if the register is a 32-bit register the backend can handle.
|
|
|
|
return X86TargetInfo::validateGlobalRegisterVariable(RegName, RegSize,
|
|
|
|
HasSizeMismatch);
|
|
|
|
}
|
2008-08-20 02:34:37 +00:00
|
|
|
};
|
|
|
|
|
2009-09-23 07:31:35 +00:00
|
|
|
// x86-64 Windows target
|
2010-10-21 05:21:48 +00:00
|
|
|
class WindowsX86_64TargetInfo : public WindowsTargetInfo<X86_64TargetInfo> {
|
2009-09-23 07:31:35 +00:00
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
WindowsX86_64TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: WindowsTargetInfo<X86_64TargetInfo>(Triple) {
|
2009-09-23 07:31:35 +00:00
|
|
|
WCharType = UnsignedShort;
|
2009-10-08 23:00:00 +00:00
|
|
|
LongWidth = LongAlign = 32;
|
2010-10-18 07:10:59 +00:00
|
|
|
DoubleAlign = LongLongAlign = 64;
|
2010-07-21 02:02:56 +00:00
|
|
|
IntMaxType = SignedLongLong;
|
|
|
|
Int64Type = SignedLongLong;
|
2010-09-15 00:28:12 +00:00
|
|
|
SizeType = UnsignedLongLong;
|
|
|
|
PtrDiffType = SignedLongLong;
|
|
|
|
IntPtrType = SignedLongLong;
|
2016-01-27 01:04:51 +00:00
|
|
|
this->UserLabelPrefix = "";
|
2009-09-23 07:31:35 +00:00
|
|
|
}
|
2015-02-26 19:43:46 +00:00
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
2010-10-21 05:21:48 +00:00
|
|
|
WindowsTargetInfo<X86_64TargetInfo>::getTargetDefines(Opts, Builder);
|
|
|
|
Builder.defineMacro("_WIN64");
|
2010-10-21 08:22:51 +00:00
|
|
|
}
|
2015-02-26 19:43:46 +00:00
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
BuiltinVaListKind getBuiltinVaListKind() const override {
|
2012-06-16 03:34:49 +00:00
|
|
|
return TargetInfo::CharPtrBuiltinVaList;
|
2011-01-17 22:56:23 +00:00
|
|
|
}
|
2015-02-26 19:43:46 +00:00
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
|
2015-02-26 19:43:46 +00:00
|
|
|
switch (CC) {
|
|
|
|
case CC_X86StdCall:
|
|
|
|
case CC_X86ThisCall:
|
|
|
|
case CC_X86FastCall:
|
|
|
|
return CCCR_Ignore;
|
|
|
|
case CC_C:
|
|
|
|
case CC_X86VectorCall:
|
|
|
|
case CC_IntelOclBicc:
|
|
|
|
case CC_X86_64SysV:
|
|
|
|
return CCCR_OK;
|
|
|
|
default:
|
|
|
|
return CCCR_Warning;
|
|
|
|
}
|
2013-08-30 04:39:01 +00:00
|
|
|
}
|
2010-10-21 08:22:51 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// x86-64 Windows Visual Studio target
|
2014-04-04 05:08:53 +00:00
|
|
|
class MicrosoftX86_64TargetInfo : public WindowsX86_64TargetInfo {
|
2010-10-21 08:22:51 +00:00
|
|
|
public:
|
2014-04-04 05:08:53 +00:00
|
|
|
MicrosoftX86_64TargetInfo(const llvm::Triple &Triple)
|
2013-06-29 16:37:14 +00:00
|
|
|
: WindowsX86_64TargetInfo(Triple) {
|
2011-03-22 21:25:11 +00:00
|
|
|
LongDoubleWidth = LongDoubleAlign = 64;
|
|
|
|
LongDoubleFormat = &llvm::APFloat::IEEEdouble;
|
2010-10-21 08:22:51 +00:00
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
2010-10-21 08:22:51 +00:00
|
|
|
WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
|
|
|
|
WindowsX86_64TargetInfo::getVisualStudioDefines(Opts, Builder);
|
2015-07-26 23:17:29 +00:00
|
|
|
Builder.defineMacro("_M_X64", "100");
|
|
|
|
Builder.defineMacro("_M_AMD64", "100");
|
2009-09-23 07:31:35 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// x86-64 MinGW target
|
|
|
|
class MinGWX86_64TargetInfo : public WindowsX86_64TargetInfo {
|
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
MinGWX86_64TargetInfo(const llvm::Triple &Triple)
|
2015-10-28 22:29:52 +00:00
|
|
|
: WindowsX86_64TargetInfo(Triple) {
|
|
|
|
// Mingw64 rounds long double size and alignment up to 16 bytes, but sticks
|
|
|
|
// with x86 FP ops. Weird.
|
|
|
|
LongDoubleWidth = LongDoubleAlign = 128;
|
|
|
|
LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
|
|
|
|
}
|
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
2010-01-09 17:55:51 +00:00
|
|
|
WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
|
2010-10-21 08:22:51 +00:00
|
|
|
DefineStd(Builder, "WIN64", Opts);
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("__MINGW64__");
|
2014-04-21 20:58:00 +00:00
|
|
|
addMinGWDefines(Opts, Builder);
|
2014-11-14 02:01:10 +00:00
|
|
|
|
|
|
|
// GCC defines this macro when it is using __gxx_personality_seh0.
|
|
|
|
if (!Opts.SjLjExceptions)
|
|
|
|
Builder.defineMacro("__SEH__");
|
2009-09-23 07:31:35 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-07-22 17:38:19 +00:00
|
|
|
// x86-64 Cygwin target
|
|
|
|
class CygwinX86_64TargetInfo : public X86_64TargetInfo {
|
|
|
|
public:
|
|
|
|
CygwinX86_64TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: X86_64TargetInfo(Triple) {
|
|
|
|
TLSSupported = false;
|
|
|
|
WCharType = UnsignedShort;
|
|
|
|
}
|
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
|
|
|
X86_64TargetInfo::getTargetDefines(Opts, Builder);
|
|
|
|
Builder.defineMacro("__x86_64__");
|
|
|
|
Builder.defineMacro("__CYGWIN__");
|
|
|
|
Builder.defineMacro("__CYGWIN64__");
|
|
|
|
addCygMingDefines(Opts, Builder);
|
|
|
|
DefineStd(Builder, "unix", Opts);
|
|
|
|
if (Opts.CPlusPlus)
|
|
|
|
Builder.defineMacro("_GNU_SOURCE");
|
|
|
|
|
|
|
|
// GCC defines this macro when it is using __gxx_personality_seh0.
|
|
|
|
if (!Opts.SjLjExceptions)
|
|
|
|
Builder.defineMacro("__SEH__");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2009-07-01 03:36:11 +00:00
|
|
|
class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> {
|
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
DarwinX86_64TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: DarwinTargetInfo<X86_64TargetInfo>(Triple) {
|
2009-07-01 03:36:11 +00:00
|
|
|
Int64Type = SignedLongLong;
|
2014-03-29 15:09:45 +00:00
|
|
|
// The 64-bit iOS simulator uses the builtin bool type for Objective-C.
|
|
|
|
llvm::Triple T = llvm::Triple(Triple);
|
2014-10-19 02:19:27 +00:00
|
|
|
if (T.isiOS())
|
2014-03-29 15:09:45 +00:00
|
|
|
UseSignedCharForObjCBool = false;
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = "e-m:o-i64:64-f80:128-n8:16:32:64-S128";
|
2009-07-01 03:36:11 +00:00
|
|
|
}
|
2015-08-27 22:30:38 +00:00
|
|
|
|
|
|
|
bool handleTargetFeatures(std::vector<std::string> &Features,
|
|
|
|
DiagnosticsEngine &Diags) override {
|
|
|
|
if (!DarwinTargetInfo<X86_64TargetInfo>::handleTargetFeatures(Features,
|
|
|
|
Diags))
|
|
|
|
return false;
|
2015-08-27 22:42:12 +00:00
|
|
|
// We now know the features we have: we can decide how to align vectors.
|
|
|
|
MaxVectorAlign =
|
|
|
|
hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
|
2015-08-27 22:30:38 +00:00
|
|
|
return true;
|
|
|
|
}
|
2009-07-01 03:36:11 +00:00
|
|
|
};
|
|
|
|
|
2009-07-05 22:31:18 +00:00
|
|
|
class OpenBSDX86_64TargetInfo : public OpenBSDTargetInfo<X86_64TargetInfo> {
|
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
OpenBSDX86_64TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: OpenBSDTargetInfo<X86_64TargetInfo>(Triple) {
|
2009-07-05 22:31:18 +00:00
|
|
|
IntMaxType = SignedLongLong;
|
|
|
|
Int64Type = SignedLongLong;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2012-08-08 23:57:20 +00:00
|
|
|
class BitrigX86_64TargetInfo : public BitrigTargetInfo<X86_64TargetInfo> {
|
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
BitrigX86_64TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: BitrigTargetInfo<X86_64TargetInfo>(Triple) {
|
|
|
|
IntMaxType = SignedLongLong;
|
|
|
|
Int64Type = SignedLongLong;
|
2012-08-08 23:57:20 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2008-08-20 07:44:10 +00:00
|
|
|
class ARMTargetInfo : public TargetInfo {
|
2009-12-21 23:28:17 +00:00
|
|
|
// Possible FPU choices.
|
|
|
|
enum FPUMode {
|
2012-09-29 23:52:52 +00:00
|
|
|
VFP2FPU = (1 << 0),
|
|
|
|
VFP3FPU = (1 << 1),
|
|
|
|
VFP4FPU = (1 << 2),
|
2013-10-24 18:32:51 +00:00
|
|
|
NeonFPU = (1 << 3),
|
|
|
|
FPARMV8 = (1 << 4)
|
2009-12-21 23:28:17 +00:00
|
|
|
};
|
|
|
|
|
2013-10-21 10:54:53 +00:00
|
|
|
// Possible HWDiv features.
|
|
|
|
enum HWDivMode {
|
|
|
|
HWDivThumb = (1 << 0),
|
|
|
|
HWDivARM = (1 << 1)
|
|
|
|
};
|
|
|
|
|
2009-12-21 23:28:17 +00:00
|
|
|
static bool FPUModeIsVFP(FPUMode Mode) {
|
2013-10-24 18:32:51 +00:00
|
|
|
return Mode & (VFP2FPU | VFP3FPU | VFP4FPU | NeonFPU | FPARMV8);
|
2009-12-21 23:28:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static const TargetInfo::GCCRegAlias GCCRegAliases[];
|
|
|
|
static const char * const GCCRegNames[];
|
2009-09-17 07:03:19 +00:00
|
|
|
|
2009-12-18 18:42:37 +00:00
|
|
|
std::string ABI, CPU;
|
2009-12-21 23:28:17 +00:00
|
|
|
|
2015-07-17 09:08:37 +00:00
|
|
|
StringRef CPUProfile;
|
|
|
|
StringRef CPUAttr;
|
|
|
|
|
2013-08-21 21:59:03 +00:00
|
|
|
enum {
|
|
|
|
FP_Default,
|
|
|
|
FP_VFP,
|
|
|
|
FP_Neon
|
|
|
|
} FPMath;
|
|
|
|
|
2015-07-17 09:08:37 +00:00
|
|
|
unsigned ArchISA;
|
2015-10-08 16:43:26 +00:00
|
|
|
unsigned ArchKind = llvm::ARM::AK_ARMV4T;
|
2015-07-17 09:08:37 +00:00
|
|
|
unsigned ArchProfile;
|
|
|
|
unsigned ArchVersion;
|
|
|
|
|
2013-10-24 18:32:51 +00:00
|
|
|
unsigned FPU : 5;
|
2009-12-21 23:28:17 +00:00
|
|
|
|
2012-10-10 06:56:20 +00:00
|
|
|
unsigned IsAAPCS : 1;
|
2013-10-21 10:54:53 +00:00
|
|
|
unsigned HWDiv : 2;
|
2009-12-19 04:15:38 +00:00
|
|
|
|
|
|
|
// Initialized via features.
|
|
|
|
unsigned SoftFloat : 1;
|
|
|
|
unsigned SoftFloatABI : 1;
|
2009-09-14 00:35:03 +00:00
|
|
|
|
2013-10-29 09:47:51 +00:00
|
|
|
unsigned CRC : 1;
|
2014-02-03 17:28:04 +00:00
|
|
|
unsigned Crypto : 1;
|
2015-09-24 17:34:05 +00:00
|
|
|
unsigned DSP : 1;
|
2015-09-03 14:40:57 +00:00
|
|
|
unsigned Unaligned : 1;
|
|
|
|
|
|
|
|
enum {
|
|
|
|
LDREX_B = (1 << 0), /// byte (8-bit)
|
|
|
|
LDREX_H = (1 << 1), /// half (16-bit)
|
|
|
|
LDREX_W = (1 << 2), /// word (32-bit)
|
|
|
|
LDREX_D = (1 << 3), /// double (64-bit)
|
|
|
|
};
|
|
|
|
|
|
|
|
uint32_t LDREX;
|
2013-10-29 09:47:51 +00:00
|
|
|
|
2014-09-17 14:50:27 +00:00
|
|
|
// ACLE 6.5.1 Hardware floating point
|
|
|
|
enum {
|
|
|
|
HW_FP_HP = (1 << 1), /// half (16-bit)
|
|
|
|
HW_FP_SP = (1 << 2), /// single (32-bit)
|
|
|
|
HW_FP_DP = (1 << 3), /// double (64-bit)
|
|
|
|
};
|
|
|
|
uint32_t HW_FP;
|
|
|
|
|
2010-03-03 19:03:45 +00:00
|
|
|
static const Builtin::Info BuiltinInfo[];
|
|
|
|
|
2013-12-18 19:47:32 +00:00
|
|
|
void setABIAAPCS() {
|
2013-12-18 20:24:51 +00:00
|
|
|
IsAAPCS = true;
|
|
|
|
|
|
|
|
DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
|
2014-01-03 19:22:05 +00:00
|
|
|
const llvm::Triple &T = getTriple();
|
2013-12-18 19:47:32 +00:00
|
|
|
|
2015-02-27 16:35:48 +00:00
|
|
|
// size_t is unsigned long on MachO-derived environments, NetBSD and Bitrig.
|
|
|
|
if (T.isOSBinFormatMachO() || T.getOS() == llvm::Triple::NetBSD ||
|
|
|
|
T.getOS() == llvm::Triple::Bitrig)
|
2013-12-18 19:47:32 +00:00
|
|
|
SizeType = UnsignedLong;
|
2013-12-18 20:24:51 +00:00
|
|
|
else
|
|
|
|
SizeType = UnsignedInt;
|
|
|
|
|
2014-05-04 01:56:04 +00:00
|
|
|
switch (T.getOS()) {
|
|
|
|
case llvm::Triple::NetBSD:
|
2013-12-18 20:24:51 +00:00
|
|
|
WCharType = SignedInt;
|
2014-05-04 01:56:04 +00:00
|
|
|
break;
|
|
|
|
case llvm::Triple::Win32:
|
|
|
|
WCharType = UnsignedShort;
|
|
|
|
break;
|
|
|
|
case llvm::Triple::Linux:
|
|
|
|
default:
|
2013-12-18 20:24:51 +00:00
|
|
|
// AAPCS 7.1.1, ARM-Linux ABI 2.4: type of wchar_t is unsigned int.
|
|
|
|
WCharType = UnsignedInt;
|
2014-05-04 01:56:04 +00:00
|
|
|
break;
|
2013-12-18 20:24:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
UseBitFieldTypeAlignment = true;
|
|
|
|
|
|
|
|
ZeroLengthBitfieldBoundary = 0;
|
|
|
|
|
2014-10-14 22:12:21 +00:00
|
|
|
// Thumb1 add sp, #imm requires the immediate value be multiple of 4,
|
|
|
|
// so set preferred for small types to 32.
|
|
|
|
if (T.isOSBinFormatMachO()) {
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString =
|
2014-10-14 22:12:21 +00:00
|
|
|
BigEndian ? "E-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
|
|
|
|
: "e-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64";
|
|
|
|
} else if (T.isOSWindows()) {
|
|
|
|
assert(!BigEndian && "Windows on ARM does not support big endian");
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = "e"
|
|
|
|
"-m:w"
|
|
|
|
"-p:32:32"
|
|
|
|
"-i64:64"
|
|
|
|
"-v128:64:128"
|
|
|
|
"-a:0:32"
|
|
|
|
"-n32"
|
|
|
|
"-S64";
|
2015-03-30 20:31:33 +00:00
|
|
|
} else if (T.isOSNaCl()) {
|
|
|
|
assert(!BigEndian && "NaCl on ARM does not support big endian");
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S128";
|
2013-12-18 20:24:51 +00:00
|
|
|
} else {
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString =
|
2014-10-14 22:12:21 +00:00
|
|
|
BigEndian ? "E-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
|
|
|
|
: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64";
|
2013-12-18 20:24:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME: Enumerated types are variable width in straight AAPCS.
|
2013-12-18 19:47:32 +00:00
|
|
|
}
|
|
|
|
|
2015-10-30 16:30:45 +00:00
|
|
|
void setABIAPCS(bool IsAAPCS16) {
|
2014-01-03 19:22:05 +00:00
|
|
|
const llvm::Triple &T = getTriple();
|
|
|
|
|
2013-12-18 20:24:51 +00:00
|
|
|
IsAAPCS = false;
|
|
|
|
|
2015-10-30 16:30:45 +00:00
|
|
|
if (IsAAPCS16)
|
|
|
|
DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
|
|
|
|
else
|
|
|
|
DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32;
|
2013-12-18 20:24:51 +00:00
|
|
|
|
2013-12-18 19:47:32 +00:00
|
|
|
// size_t is unsigned int on FreeBSD.
|
2014-01-03 19:22:05 +00:00
|
|
|
if (T.getOS() == llvm::Triple::FreeBSD)
|
2013-12-18 20:24:51 +00:00
|
|
|
SizeType = UnsignedInt;
|
|
|
|
else
|
2013-12-18 19:47:32 +00: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;
|
|
|
|
|
2015-10-30 16:30:45 +00:00
|
|
|
if (T.isOSBinFormatMachO() && IsAAPCS16) {
|
|
|
|
assert(!BigEndian && "AAPCS16 does not support big-endian");
|
|
|
|
DataLayoutString = "e-m:o-p:32:32-i64:64-a:0:32-n32-S128";
|
|
|
|
} else if (T.isOSBinFormatMachO())
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString =
|
2014-10-14 22:12:21 +00:00
|
|
|
BigEndian
|
|
|
|
? "E-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
|
|
|
|
: "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32";
|
|
|
|
else
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString =
|
2014-10-14 22:12:21 +00:00
|
|
|
BigEndian
|
|
|
|
? "E-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
|
|
|
|
: "e-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32";
|
2013-12-18 19:47:32 +00:00
|
|
|
|
|
|
|
// FIXME: Override "preferred align" for double and long long.
|
|
|
|
}
|
|
|
|
|
2015-07-17 09:08:37 +00:00
|
|
|
void setArchInfo() {
|
|
|
|
StringRef ArchName = getTriple().getArchName();
|
|
|
|
|
2015-10-08 16:43:26 +00:00
|
|
|
ArchISA = llvm::ARM::parseArchISA(ArchName);
|
|
|
|
CPU = llvm::ARM::getDefaultCPU(ArchName);
|
|
|
|
unsigned AK = llvm::ARM::parseArch(ArchName);
|
|
|
|
if (AK != llvm::ARM::AK_INVALID)
|
|
|
|
ArchKind = AK;
|
2015-08-19 14:50:18 +00:00
|
|
|
setArchInfo(ArchKind);
|
2015-07-17 09:08:37 +00:00
|
|
|
}
|
|
|
|
|
2015-08-19 14:50:18 +00:00
|
|
|
void setArchInfo(unsigned Kind) {
|
2015-07-17 09:08:37 +00:00
|
|
|
StringRef SubArch;
|
|
|
|
|
|
|
|
// cache TargetParser info
|
2015-08-19 14:50:18 +00:00
|
|
|
ArchKind = Kind;
|
2015-08-30 02:16:36 +00:00
|
|
|
SubArch = llvm::ARM::getSubArch(ArchKind);
|
|
|
|
ArchProfile = llvm::ARM::parseArchProfile(SubArch);
|
|
|
|
ArchVersion = llvm::ARM::parseArchVersion(SubArch);
|
2015-07-17 09:08:37 +00:00
|
|
|
|
|
|
|
// cache CPU related strings
|
|
|
|
CPUAttr = getCPUAttr();
|
|
|
|
CPUProfile = getCPUProfile();
|
|
|
|
}
|
|
|
|
|
|
|
|
void setAtomic() {
|
2015-10-09 18:39:59 +00:00
|
|
|
// when triple does not specify a sub arch,
|
2015-07-17 09:08:37 +00:00
|
|
|
// then we are not using inline atomics
|
2015-10-08 16:43:26 +00:00
|
|
|
bool ShouldUseInlineAtomic =
|
2015-07-17 09:08:37 +00:00
|
|
|
(ArchISA == llvm::ARM::IK_ARM && ArchVersion >= 6) ||
|
|
|
|
(ArchISA == llvm::ARM::IK_THUMB && ArchVersion >= 7);
|
2015-10-09 18:39:59 +00:00
|
|
|
// Cortex M does not support 8 byte atomics, while general Thumb2 does.
|
2015-07-17 09:08:37 +00:00
|
|
|
if (ArchProfile == llvm::ARM::PK_M) {
|
|
|
|
MaxAtomicPromoteWidth = 32;
|
|
|
|
if (ShouldUseInlineAtomic)
|
|
|
|
MaxAtomicInlineWidth = 32;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
MaxAtomicPromoteWidth = 64;
|
|
|
|
if (ShouldUseInlineAtomic)
|
|
|
|
MaxAtomicInlineWidth = 64;
|
2015-10-09 18:39:59 +00:00
|
|
|
}
|
2015-07-17 09:08:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool isThumb() const {
|
|
|
|
return (ArchISA == llvm::ARM::IK_THUMB);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool supportsThumb() const {
|
|
|
|
return CPUAttr.count('T') || ArchVersion >= 6;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool supportsThumb2() const {
|
|
|
|
return CPUAttr.equals("6T2") || ArchVersion >= 7;
|
|
|
|
}
|
|
|
|
|
|
|
|
StringRef getCPUAttr() const {
|
|
|
|
// For most sub-arches, the build attribute CPU name is enough.
|
|
|
|
// For Cortex variants, it's slightly different.
|
|
|
|
switch(ArchKind) {
|
|
|
|
default:
|
2015-08-30 07:51:18 +00:00
|
|
|
return llvm::ARM::getCPUAttr(ArchKind);
|
2015-07-17 09:08:37 +00:00
|
|
|
case llvm::ARM::AK_ARMV6M:
|
|
|
|
return "6M";
|
2015-07-21 21:47:33 +00:00
|
|
|
case llvm::ARM::AK_ARMV7S:
|
|
|
|
return "7S";
|
2015-07-17 09:08:37 +00:00
|
|
|
case llvm::ARM::AK_ARMV7A:
|
|
|
|
return "7A";
|
|
|
|
case llvm::ARM::AK_ARMV7R:
|
|
|
|
return "7R";
|
|
|
|
case llvm::ARM::AK_ARMV7M:
|
|
|
|
return "7M";
|
|
|
|
case llvm::ARM::AK_ARMV7EM:
|
|
|
|
return "7EM";
|
|
|
|
case llvm::ARM::AK_ARMV8A:
|
|
|
|
return "8A";
|
|
|
|
case llvm::ARM::AK_ARMV8_1A:
|
|
|
|
return "8_1A";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
StringRef getCPUProfile() const {
|
|
|
|
switch(ArchProfile) {
|
|
|
|
case llvm::ARM::PK_A:
|
|
|
|
return "A";
|
|
|
|
case llvm::ARM::PK_R:
|
|
|
|
return "R";
|
|
|
|
case llvm::ARM::PK_M:
|
|
|
|
return "M";
|
|
|
|
default:
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-04-21 18:56:49 +00:00
|
|
|
public:
|
2014-03-28 14:40:46 +00:00
|
|
|
ARMTargetInfo(const llvm::Triple &Triple, bool IsBigEndian)
|
2015-10-08 16:43:26 +00:00
|
|
|
: TargetInfo(Triple), FPMath(FP_Default),
|
2015-09-03 14:40:57 +00:00
|
|
|
IsAAPCS(true), LDREX(0), HW_FP(0) {
|
2014-03-28 14:40:46 +00:00
|
|
|
BigEndian = IsBigEndian;
|
|
|
|
|
2013-11-30 00:38:16 +00:00
|
|
|
switch (getTriple().getOS()) {
|
|
|
|
case llvm::Triple::NetBSD:
|
2013-12-02 16:09:34 +00:00
|
|
|
PtrDiffType = SignedLong;
|
2013-11-30 00:38:16 +00:00
|
|
|
break;
|
|
|
|
default:
|
2013-12-02 16:09:34 +00:00
|
|
|
PtrDiffType = SignedInt;
|
2013-11-30 00:38:16 +00:00
|
|
|
break;
|
|
|
|
}
|
2015-07-24 17:39:13 +00:00
|
|
|
|
2015-10-08 16:43:26 +00:00
|
|
|
// Cache arch related info.
|
2015-07-17 09:08:37 +00:00
|
|
|
setArchInfo();
|
2015-07-24 17:39:13 +00:00
|
|
|
|
2010-04-23 16:29:58 +00:00
|
|
|
// {} in inline assembly are neon specifiers, not assembly variant
|
|
|
|
// specifiers.
|
|
|
|
NoAsmVariants = true;
|
2010-10-21 03:16:25 +00:00
|
|
|
|
2014-12-05 01:06:59 +00:00
|
|
|
// FIXME: This duplicates code from the driver that sets the -target-abi
|
|
|
|
// option - this code is used if -target-abi isn't passed and should
|
|
|
|
// be unified in some way.
|
|
|
|
if (Triple.isOSBinFormatMachO()) {
|
|
|
|
// The backend is hardwired to assume AAPCS for M-class processors, ensure
|
|
|
|
// the frontend matches that.
|
|
|
|
if (Triple.getEnvironment() == llvm::Triple::EABI ||
|
|
|
|
Triple.getOS() == llvm::Triple::UnknownOS ||
|
|
|
|
StringRef(CPU).startswith("cortex-m")) {
|
|
|
|
setABI("aapcs");
|
2016-01-27 19:32:40 +00:00
|
|
|
} else if (Triple.isWatchABI()) {
|
2015-10-30 16:30:45 +00:00
|
|
|
setABI("aapcs16");
|
2014-12-05 01:06:59 +00:00
|
|
|
} else {
|
|
|
|
setABI("apcs-gnu");
|
|
|
|
}
|
|
|
|
} else if (Triple.isOSWindows()) {
|
|
|
|
// FIXME: this is invalid for WindowsCE
|
|
|
|
setABI("aapcs");
|
|
|
|
} else {
|
|
|
|
// Select the default based on the platform.
|
|
|
|
switch (Triple.getEnvironment()) {
|
|
|
|
case llvm::Triple::Android:
|
|
|
|
case llvm::Triple::GNUEABI:
|
|
|
|
case llvm::Triple::GNUEABIHF:
|
|
|
|
setABI("aapcs-linux");
|
|
|
|
break;
|
|
|
|
case llvm::Triple::EABIHF:
|
|
|
|
case llvm::Triple::EABI:
|
|
|
|
setABI("aapcs");
|
|
|
|
break;
|
2014-12-18 02:08:55 +00:00
|
|
|
case llvm::Triple::GNU:
|
2015-10-08 16:43:26 +00:00
|
|
|
setABI("apcs-gnu");
|
|
|
|
break;
|
2014-12-05 01:06:59 +00:00
|
|
|
default:
|
|
|
|
if (Triple.getOS() == llvm::Triple::NetBSD)
|
|
|
|
setABI("apcs-gnu");
|
|
|
|
else
|
|
|
|
setABI("aapcs");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2010-08-21 22:46:04 +00:00
|
|
|
|
|
|
|
// ARM targets default to using the ARM C++ ABI.
|
2013-01-25 22:30:49 +00:00
|
|
|
TheCXXABI.set(TargetCXXABI::GenericARM);
|
2011-10-14 20:59:01 +00:00
|
|
|
|
2015-07-03 16:41:13 +00:00
|
|
|
// ARM has atomics up to 8 bytes
|
2015-07-17 09:08:37 +00:00
|
|
|
setAtomic();
|
2015-07-02 15:14:10 +00:00
|
|
|
|
2012-03-12 09:14:10 +00:00
|
|
|
// Do force alignment of members that follow zero length bitfields. If
|
2014-11-18 22:36:15 +00:00
|
|
|
// 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
|
2012-03-12 09:14:10 +00:00
|
|
|
// zero length bitfield.
|
|
|
|
UseZeroLengthBitfieldAlignment = true;
|
2008-05-20 14:21:01 +00:00
|
|
|
}
|
2015-07-02 13:21:34 +00:00
|
|
|
|
2014-06-07 23:30:42 +00:00
|
|
|
StringRef getABI() const override { return ABI; }
|
2015-07-02 13:21:34 +00:00
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
bool setABI(const std::string &Name) override {
|
2009-09-14 00:35:03 +00:00
|
|
|
ABI = Name;
|
|
|
|
|
2009-09-14 00:02:24 +00: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.
|
2015-10-30 16:30:36 +00:00
|
|
|
if (Name == "apcs-gnu" || Name == "aapcs16") {
|
2015-10-30 16:30:45 +00:00
|
|
|
setABIAPCS(Name == "aapcs16");
|
2013-12-18 19:47:32 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") {
|
|
|
|
setABIAAPCS();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
2009-09-14 00:02:24 +00:00
|
|
|
}
|
2009-12-19 04:15:38 +00:00
|
|
|
|
2015-05-27 13:33:00 +00:00
|
|
|
// FIXME: This should be based on Arch attributes, not CPU names.
|
2015-10-09 18:39:55 +00:00
|
|
|
bool
|
|
|
|
initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
|
|
|
|
StringRef CPU,
|
|
|
|
const std::vector<std::string> &FeaturesVec) const override {
|
|
|
|
|
2015-09-06 16:15:45 +00:00
|
|
|
std::vector<const char*> TargetFeatures;
|
2015-11-16 11:16:36 +00:00
|
|
|
unsigned Arch = llvm::ARM::parseArch(getTriple().getArchName());
|
2015-09-06 16:15:45 +00:00
|
|
|
|
|
|
|
// get default FPU features
|
2015-11-16 11:16:36 +00:00
|
|
|
unsigned FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
|
2015-09-06 16:15:45 +00:00
|
|
|
llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);
|
|
|
|
|
|
|
|
// get default Extension features
|
2015-11-16 11:16:36 +00:00
|
|
|
unsigned Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch);
|
2015-09-06 16:15:45 +00:00
|
|
|
llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures);
|
|
|
|
|
|
|
|
for (const char *Feature : TargetFeatures)
|
|
|
|
if (Feature[0] == '+')
|
2015-10-09 18:39:59 +00:00
|
|
|
Features[Feature+1] = true;
|
2015-09-03 14:40:57 +00:00
|
|
|
|
2015-08-28 22:32:01 +00:00
|
|
|
return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
|
2009-12-21 23:28:17 +00:00
|
|
|
}
|
2010-10-21 03:16:25 +00:00
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
bool handleTargetFeatures(std::vector<std::string> &Features,
|
|
|
|
DiagnosticsEngine &Diags) override {
|
2012-09-29 23:52:52 +00:00
|
|
|
FPU = 0;
|
2013-10-29 09:47:51 +00:00
|
|
|
CRC = 0;
|
2014-02-03 17:28:04 +00:00
|
|
|
Crypto = 0;
|
2015-09-24 17:34:05 +00:00
|
|
|
DSP = 0;
|
2015-09-03 14:40:57 +00:00
|
|
|
Unaligned = 1;
|
2009-12-19 04:15:38 +00:00
|
|
|
SoftFloat = SoftFloatABI = false;
|
2013-10-21 10:54:53 +00:00
|
|
|
HWDiv = 0;
|
2014-09-17 14:50:23 +00:00
|
|
|
|
2015-06-24 23:39:25 +00:00
|
|
|
// This does not diagnose illegal cases like having both
|
|
|
|
// "+vfpv2" and "+vfpv3" or having "+neon" and "+fp-only-sp".
|
|
|
|
uint32_t HW_FP_remove = 0;
|
2014-09-17 14:50:23 +00:00
|
|
|
for (const auto &Feature : Features) {
|
2014-09-17 14:50:27 +00:00
|
|
|
if (Feature == "+soft-float") {
|
2009-12-19 04:15:38 +00:00
|
|
|
SoftFloat = true;
|
2014-09-17 14:50:27 +00:00
|
|
|
} else if (Feature == "+soft-float-abi") {
|
2009-12-19 04:15:38 +00:00
|
|
|
SoftFloatABI = true;
|
2014-09-17 14:50:27 +00:00
|
|
|
} else if (Feature == "+vfp2") {
|
2012-09-29 23:52:52 +00:00
|
|
|
FPU |= VFP2FPU;
|
2015-06-24 23:39:25 +00:00
|
|
|
HW_FP |= HW_FP_SP | HW_FP_DP;
|
2014-09-17 14:50:27 +00:00
|
|
|
} else if (Feature == "+vfp3") {
|
2012-09-29 23:52:52 +00:00
|
|
|
FPU |= VFP3FPU;
|
2015-06-24 23:39:25 +00:00
|
|
|
HW_FP |= HW_FP_SP | HW_FP_DP;
|
2014-09-17 14:50:27 +00:00
|
|
|
} else if (Feature == "+vfp4") {
|
2012-09-29 23:52:52 +00:00
|
|
|
FPU |= VFP4FPU;
|
2015-06-24 23:39:25 +00:00
|
|
|
HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP;
|
2014-09-17 14:50:27 +00:00
|
|
|
} else if (Feature == "+fp-armv8") {
|
2013-10-24 18:32:51 +00:00
|
|
|
FPU |= FPARMV8;
|
2015-06-24 23:39:25 +00:00
|
|
|
HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP;
|
2014-09-17 14:50:27 +00:00
|
|
|
} else if (Feature == "+neon") {
|
2012-09-29 23:52:52 +00:00
|
|
|
FPU |= NeonFPU;
|
2015-06-24 23:39:25 +00:00
|
|
|
HW_FP |= HW_FP_SP | HW_FP_DP;
|
2014-09-17 14:50:27 +00:00
|
|
|
} else if (Feature == "+hwdiv") {
|
2013-10-21 10:54:53 +00:00
|
|
|
HWDiv |= HWDivThumb;
|
2014-09-17 14:50:27 +00:00
|
|
|
} else if (Feature == "+hwdiv-arm") {
|
2013-10-21 10:54:53 +00:00
|
|
|
HWDiv |= HWDivARM;
|
2014-09-17 14:50:27 +00:00
|
|
|
} else if (Feature == "+crc") {
|
2013-10-29 09:47:51 +00:00
|
|
|
CRC = 1;
|
2014-09-17 14:50:27 +00:00
|
|
|
} else if (Feature == "+crypto") {
|
2014-02-03 17:28:04 +00:00
|
|
|
Crypto = 1;
|
2015-10-23 17:19:02 +00:00
|
|
|
} else if (Feature == "+dsp") {
|
2015-09-24 17:34:05 +00:00
|
|
|
DSP = 1;
|
2014-09-17 14:50:27 +00:00
|
|
|
} else if (Feature == "+fp-only-sp") {
|
2015-10-21 10:03:55 +00:00
|
|
|
HW_FP_remove |= HW_FP_DP;
|
2015-09-03 14:40:57 +00:00
|
|
|
} else if (Feature == "+strict-align") {
|
|
|
|
Unaligned = 0;
|
|
|
|
} else if (Feature == "+fp16") {
|
|
|
|
HW_FP |= HW_FP_HP;
|
2014-09-17 14:50:27 +00:00
|
|
|
}
|
2009-12-19 04:15:38 +00:00
|
|
|
}
|
2015-06-24 23:39:25 +00:00
|
|
|
HW_FP &= ~HW_FP_remove;
|
2009-12-19 04:15:38 +00:00
|
|
|
|
2015-09-03 14:40:57 +00:00
|
|
|
switch (ArchVersion) {
|
|
|
|
case 6:
|
|
|
|
if (ArchProfile == llvm::ARM::PK_M)
|
|
|
|
LDREX = 0;
|
|
|
|
else if (ArchKind == llvm::ARM::AK_ARMV6K)
|
|
|
|
LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B ;
|
|
|
|
else
|
|
|
|
LDREX = LDREX_W;
|
|
|
|
break;
|
|
|
|
case 7:
|
|
|
|
if (ArchProfile == llvm::ARM::PK_M)
|
|
|
|
LDREX = LDREX_W | LDREX_H | LDREX_B ;
|
|
|
|
else
|
|
|
|
LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B ;
|
|
|
|
break;
|
|
|
|
case 8:
|
|
|
|
LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B ;
|
|
|
|
}
|
|
|
|
|
2013-08-21 21:59:03 +00: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 04:15:38 +00:00
|
|
|
// Remove front-end specific options which the backend handles differently.
|
2015-05-12 01:26:21 +00:00
|
|
|
auto Feature =
|
|
|
|
std::find(Features.begin(), Features.end(), "+soft-float-abi");
|
|
|
|
if (Feature != Features.end())
|
|
|
|
Features.erase(Feature);
|
2014-09-17 14:50:23 +00:00
|
|
|
|
2013-08-21 21:59:03 +00:00
|
|
|
return true;
|
2009-12-19 04:15:38 +00:00
|
|
|
}
|
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
bool hasFeature(StringRef Feature) const override {
|
2012-01-30 06:38:25 +00:00
|
|
|
return llvm::StringSwitch<bool>(Feature)
|
|
|
|
.Case("arm", true)
|
2015-08-07 01:59:56 +00:00
|
|
|
.Case("aarch32", true)
|
2012-01-30 06:38:25 +00:00
|
|
|
.Case("softfloat", SoftFloat)
|
2015-07-17 09:08:37 +00:00
|
|
|
.Case("thumb", isThumb())
|
2013-09-16 18:07:35 +00:00
|
|
|
.Case("neon", (FPU & NeonFPU) && !SoftFloat)
|
2013-10-21 10:54:53 +00:00
|
|
|
.Case("hwdiv", HWDiv & HWDivThumb)
|
|
|
|
.Case("hwdiv-arm", HWDiv & HWDivARM)
|
2012-01-30 06:38:25 +00:00
|
|
|
.Default(false);
|
|
|
|
}
|
2015-07-03 16:41:13 +00:00
|
|
|
|
2015-07-17 09:08:37 +00:00
|
|
|
bool setCPU(const std::string &Name) override {
|
2015-08-19 14:50:18 +00:00
|
|
|
if (Name != "generic")
|
2015-08-30 02:16:36 +00:00
|
|
|
setArchInfo(llvm::ARM::parseCPUArch(Name));
|
2015-08-19 14:50:18 +00:00
|
|
|
|
2015-07-03 16:41:13 +00:00
|
|
|
if (ArchKind == llvm::ARM::AK_INVALID)
|
2009-12-18 18:42:37 +00:00
|
|
|
return false;
|
2015-07-17 09:08:37 +00:00
|
|
|
setAtomic();
|
2009-12-18 18:42:37 +00:00
|
|
|
CPU = Name;
|
|
|
|
return true;
|
|
|
|
}
|
2015-07-17 09:08:37 +00:00
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
bool setFPMath(StringRef Name) override;
|
2015-07-17 09:08:37 +00:00
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
2009-03-02 22:27:17 +00:00
|
|
|
// Target identification.
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("__arm");
|
|
|
|
Builder.defineMacro("__arm__");
|
2009-05-03 13:42:53 +00:00
|
|
|
|
2009-03-02 22:27:17 +00:00
|
|
|
// Target properties.
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("__REGISTER_PREFIX__", "");
|
2015-10-30 16:30:45 +00:00
|
|
|
|
|
|
|
// Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU
|
|
|
|
// happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__.
|
2016-01-27 19:32:40 +00:00
|
|
|
if (getTriple().isWatchABI())
|
2015-10-30 16:30:45 +00:00
|
|
|
Builder.defineMacro("__ARM_ARCH_7K__", "2");
|
|
|
|
|
2015-07-17 09:08:37 +00:00
|
|
|
if (!CPUAttr.empty())
|
|
|
|
Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__");
|
2014-06-15 18:35:07 +00:00
|
|
|
|
|
|
|
// ACLE 6.4.1 ARM/Thumb instruction set architecture
|
|
|
|
// __ARM_ARCH is defined as an integer value indicating the current ARM ISA
|
2015-12-24 10:07:37 +00:00
|
|
|
Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion));
|
2015-09-03 14:40:57 +00:00
|
|
|
|
2015-07-17 09:08:37 +00:00
|
|
|
if (ArchVersion >= 8) {
|
2015-09-03 14:40:57 +00:00
|
|
|
// ACLE 6.5.7 Crypto Extension
|
|
|
|
if (Crypto)
|
|
|
|
Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
|
|
|
|
// ACLE 6.5.8 CRC32 Extension
|
|
|
|
if (CRC)
|
|
|
|
Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
|
|
|
|
// ACLE 6.5.10 Numeric Maximum and Minimum
|
|
|
|
Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
|
|
|
|
// ACLE 6.5.9 Directed Rounding
|
|
|
|
Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
|
2014-09-15 11:25:38 +00:00
|
|
|
}
|
2014-06-15 18:35:07 +00:00
|
|
|
|
|
|
|
// __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA. It
|
|
|
|
// is not defined for the M-profile.
|
|
|
|
// NOTE that the deffault profile is assumed to be 'A'
|
|
|
|
if (CPUProfile.empty() || CPUProfile != "M")
|
|
|
|
Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1");
|
|
|
|
|
|
|
|
// __ARM_ARCH_ISA_THUMB is defined to 1 if the core supporst the original
|
|
|
|
// Thumb ISA (including v6-M). It is set to 2 if the core supports the
|
|
|
|
// Thumb-2 ISA as found in the v6T2 architecture and all v7 architecture.
|
2015-07-17 09:08:37 +00:00
|
|
|
if (supportsThumb2())
|
2014-06-15 18:35:07 +00:00
|
|
|
Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
|
2015-07-17 09:08:37 +00:00
|
|
|
else if (supportsThumb())
|
2014-06-15 18:35:07 +00:00
|
|
|
Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
|
|
|
|
|
|
|
|
// __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
|
|
|
|
// instruction set such as ARM or Thumb.
|
|
|
|
Builder.defineMacro("__ARM_32BIT_STATE", "1");
|
|
|
|
|
|
|
|
// ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
|
|
|
|
|
|
|
|
// __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
|
2012-09-08 08:08:27 +00:00
|
|
|
if (!CPUProfile.empty())
|
2014-06-15 18:35:07 +00:00
|
|
|
Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
|
2014-01-22 18:42:13 +00:00
|
|
|
|
2015-09-03 14:40:57 +00:00
|
|
|
// ACLE 6.4.3 Unaligned access supported in hardware
|
2015-10-09 18:39:59 +00:00
|
|
|
if (Unaligned)
|
2015-09-03 14:40:57 +00:00
|
|
|
Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
|
2015-10-09 18:39:59 +00:00
|
|
|
|
2015-09-03 14:40:57 +00:00
|
|
|
// ACLE 6.4.4 LDREX/STREX
|
|
|
|
if (LDREX)
|
|
|
|
Builder.defineMacro("__ARM_FEATURE_LDREX", "0x" + llvm::utohexstr(LDREX));
|
|
|
|
|
|
|
|
// ACLE 6.4.5 CLZ
|
2015-10-09 18:39:59 +00:00
|
|
|
if (ArchVersion == 5 ||
|
|
|
|
(ArchVersion == 6 && CPUProfile != "M") ||
|
|
|
|
ArchVersion > 6)
|
2015-09-03 14:40:57 +00:00
|
|
|
Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
|
|
|
|
|
2014-09-17 14:50:27 +00:00
|
|
|
// ACLE 6.5.1 Hardware Floating Point
|
|
|
|
if (HW_FP)
|
2014-09-18 02:13:33 +00:00
|
|
|
Builder.defineMacro("__ARM_FP", "0x" + llvm::utohexstr(HW_FP));
|
2014-09-17 14:50:27 +00:00
|
|
|
|
2014-06-27 21:25:42 +00:00
|
|
|
// ACLE predefines.
|
|
|
|
Builder.defineMacro("__ARM_ACLE", "200");
|
|
|
|
|
2015-09-03 12:40:58 +00:00
|
|
|
// FP16 support (we currently only support IEEE format).
|
|
|
|
Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
|
|
|
|
Builder.defineMacro("__ARM_FP16_ARGS", "1");
|
|
|
|
|
2015-09-03 14:40:57 +00:00
|
|
|
// ACLE 6.5.3 Fused multiply-accumulate (FMA)
|
|
|
|
if (ArchVersion >= 7 && (CPUProfile != "M" || CPUAttr == "7EM"))
|
|
|
|
Builder.defineMacro("__ARM_FEATURE_FMA", "1");
|
|
|
|
|
2009-04-08 02:07:04 +00:00
|
|
|
// Subtarget options.
|
2009-12-18 18:42:37 +00:00
|
|
|
|
|
|
|
// FIXME: It's more complicated than this and we don't really support
|
|
|
|
// interworking.
|
2014-04-04 20:31:19 +00:00
|
|
|
// Windows on ARM does not "support" interworking
|
2015-07-17 09:08:37 +00:00
|
|
|
if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows())
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("__THUMB_INTERWORK__");
|
2009-12-18 18:42:37 +00:00
|
|
|
|
2012-10-25 13:33:01 +00:00
|
|
|
if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
|
2013-11-11 19:11:22 +00:00
|
|
|
// Embedded targets on Darwin follow AAPCS, but not EABI.
|
2014-04-04 20:31:19 +00:00
|
|
|
// Windows on ARM follows AAPCS VFP, but does not conform to EABI.
|
|
|
|
if (!getTriple().isOSDarwin() && !getTriple().isOSWindows())
|
2012-10-22 18:51:13 +00:00
|
|
|
Builder.defineMacro("__ARM_EABI__");
|
2012-09-08 08:08:27 +00:00
|
|
|
Builder.defineMacro("__ARM_PCS", "1");
|
|
|
|
|
2012-10-25 13:33:01 +00:00
|
|
|
if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp")
|
2012-09-08 08:08:27 +00:00
|
|
|
Builder.defineMacro("__ARM_PCS_VFP", "1");
|
|
|
|
}
|
2009-12-18 18:42:37 +00:00
|
|
|
|
2009-12-19 04:15:38 +00:00
|
|
|
if (SoftFloat)
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("__SOFTFP__");
|
2009-09-17 16:21:10 +00:00
|
|
|
|
2009-12-18 18:42:37 +00:00
|
|
|
if (CPU == "xscale")
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("__XSCALE__");
|
2009-09-17 16:21:10 +00:00
|
|
|
|
2015-07-17 09:08:37 +00:00
|
|
|
if (isThumb()) {
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("__THUMBEL__");
|
|
|
|
Builder.defineMacro("__thumb__");
|
2015-07-17 09:08:37 +00:00
|
|
|
if (supportsThumb2())
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("__thumb2__");
|
2009-09-17 16:21:10 +00:00
|
|
|
}
|
2015-09-03 14:40:57 +00:00
|
|
|
|
|
|
|
// ACLE 6.4.9 32-bit SIMD instructions
|
|
|
|
if (ArchVersion >= 6 && (CPUProfile != "M" || CPUAttr == "7EM"))
|
|
|
|
Builder.defineMacro("__ARM_FEATURE_SIMD32", "1");
|
|
|
|
|
|
|
|
// ACLE 6.4.10 Hardware Integer Divide
|
2015-10-09 18:39:59 +00:00
|
|
|
if (((HWDiv & HWDivThumb) && isThumb()) ||
|
|
|
|
((HWDiv & HWDivARM) && !isThumb())) {
|
2015-09-03 14:40:57 +00:00
|
|
|
Builder.defineMacro("__ARM_FEATURE_IDIV", "1");
|
2013-10-21 10:54:53 +00:00
|
|
|
Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
|
2015-09-03 14:40:57 +00:00
|
|
|
}
|
2009-09-17 16:21:10 +00:00
|
|
|
|
|
|
|
// Note, this is always on in gcc, even though it doesn't make sense.
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("__APCS_32__");
|
2009-12-21 23:28:17 +00:00
|
|
|
|
2012-09-29 23:52:52 +00:00
|
|
|
if (FPUModeIsVFP((FPUMode) FPU)) {
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("__VFP_FP__");
|
2012-09-29 23:52:52 +00:00
|
|
|
if (FPU & VFP2FPU)
|
|
|
|
Builder.defineMacro("__ARM_VFPV2__");
|
|
|
|
if (FPU & VFP3FPU)
|
|
|
|
Builder.defineMacro("__ARM_VFPV3__");
|
|
|
|
if (FPU & VFP4FPU)
|
|
|
|
Builder.defineMacro("__ARM_VFPV4__");
|
|
|
|
}
|
2014-01-22 18:42:13 +00:00
|
|
|
|
2009-12-21 23:28:17 +00: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.
|
2015-07-17 09:08:37 +00:00
|
|
|
if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
|
2015-09-03 14:40:57 +00:00
|
|
|
Builder.defineMacro("__ARM_NEON", "1");
|
2010-01-09 17:55:51 +00:00
|
|
|
Builder.defineMacro("__ARM_NEON__");
|
2015-09-03 14:40:57 +00:00
|
|
|
// current AArch32 NEON implementations do not support double-precision
|
|
|
|
// floating-point even when it is present in VFP.
|
2015-10-09 18:39:59 +00:00
|
|
|
Builder.defineMacro("__ARM_NEON_FP",
|
|
|
|
"0x" + llvm::utohexstr(HW_FP & ~HW_FP_DP));
|
2013-11-21 12:36:34 +00:00
|
|
|
}
|
2013-09-18 10:07:09 +00:00
|
|
|
|
2014-01-20 10:52:00 +00:00
|
|
|
Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
|
|
|
|
Opts.ShortWChar ? "2" : "4");
|
|
|
|
|
|
|
|
Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM",
|
|
|
|
Opts.ShortEnums ? "1" : "4");
|
|
|
|
|
2015-07-17 09:08:37 +00:00
|
|
|
if (ArchVersion >= 6 && CPUAttr != "6M") {
|
2013-09-30 22:51:32 +00: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");
|
|
|
|
}
|
2014-11-25 08:57:36 +00:00
|
|
|
|
2015-09-03 14:40:57 +00:00
|
|
|
// ACLE 6.4.7 DSP instructions
|
2015-09-24 17:34:05 +00:00
|
|
|
if (DSP) {
|
2015-09-03 14:40:57 +00:00
|
|
|
Builder.defineMacro("__ARM_FEATURE_DSP", "1");
|
|
|
|
}
|
|
|
|
|
|
|
|
// ACLE 6.4.8 Saturation instructions
|
2015-09-24 17:34:05 +00:00
|
|
|
bool SAT = false;
|
2015-09-03 14:40:57 +00:00
|
|
|
if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6 ) {
|
|
|
|
Builder.defineMacro("__ARM_FEATURE_SAT", "1");
|
2015-09-24 17:34:05 +00:00
|
|
|
SAT = true;
|
2015-09-03 14:40:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// ACLE 6.4.6 Q (saturation) flag
|
2015-09-24 17:34:05 +00:00
|
|
|
if (DSP || SAT)
|
2015-09-03 14:40:57 +00:00
|
|
|
Builder.defineMacro("__ARM_FEATURE_QBIT", "1");
|
2015-10-02 14:56:37 +00:00
|
|
|
|
|
|
|
if (Opts.UnsafeFPMath)
|
|
|
|
Builder.defineMacro("__ARM_FP_FAST", "1");
|
2015-11-29 10:43:59 +00:00
|
|
|
|
|
|
|
if (ArchKind == llvm::ARM::AK_ARMV8_1A)
|
|
|
|
Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
|
2008-04-21 18:56:49 +00:00
|
|
|
}
|
2015-07-17 09:08:37 +00:00
|
|
|
|
2015-10-19 04:51:35 +00:00
|
|
|
ArrayRef<Builtin::Info> getTargetBuiltins() const override {
|
|
|
|
return llvm::makeArrayRef(BuiltinInfo,
|
|
|
|
clang::ARM::LastTSBuiltin-Builtin::FirstTSBuiltin);
|
2008-04-21 18:56:49 +00:00
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
bool isCLZForZeroUndef() const override { return false; }
|
|
|
|
BuiltinVaListKind getBuiltinVaListKind() const override {
|
2015-10-30 16:30:45 +00:00
|
|
|
return IsAAPCS
|
|
|
|
? AAPCSABIBuiltinVaList
|
2016-01-27 19:32:40 +00:00
|
|
|
: (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
|
|
|
|
: TargetInfo::VoidPtrBuiltinVaList);
|
2008-04-21 18:56:49 +00:00
|
|
|
}
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<const char *> getGCCRegNames() const override;
|
|
|
|
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
|
2014-03-11 03:39:26 +00:00
|
|
|
bool validateAsmConstraint(const char *&Name,
|
|
|
|
TargetInfo::ConstraintInfo &Info) const override {
|
2009-02-28 17:11:49 +00:00
|
|
|
switch (*Name) {
|
2012-08-16 23:50:41 +00:00
|
|
|
default: break;
|
2008-04-22 05:03:19 +00: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 07:16:29 +00:00
|
|
|
Info.setAllowsRegister();
|
2008-04-22 05:03:19 +00:00
|
|
|
return true;
|
2015-01-06 04:26:34 +00:00
|
|
|
case 'I':
|
|
|
|
case 'J':
|
|
|
|
case 'K':
|
|
|
|
case 'L':
|
|
|
|
case 'M':
|
|
|
|
// FIXME
|
|
|
|
return true;
|
2011-07-29 21:20:35 +00:00
|
|
|
case 'Q': // A memory address that is a single base register.
|
|
|
|
Info.setAllowsMemory();
|
|
|
|
return true;
|
2011-06-07 23:45:05 +00: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 01:40:49 +00:00
|
|
|
case 't': // address valid for load/store opaque types wider
|
2012-11-14 22:08:59 +00:00
|
|
|
// than 128-bits
|
2011-06-17 01:40:49 +00: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-14 22:08:59 +00:00
|
|
|
// values in four ARM registers
|
2011-06-07 23:45:05 +00:00
|
|
|
Info.setAllowsMemory();
|
|
|
|
Name++;
|
|
|
|
return true;
|
|
|
|
}
|
2008-04-22 05:03:19 +00:00
|
|
|
}
|
2008-04-21 18:56:49 +00:00
|
|
|
return false;
|
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
std::string convertConstraint(const char *&Constraint) const override {
|
2011-06-07 23:45:05 +00:00
|
|
|
std::string R;
|
|
|
|
switch (*Constraint) {
|
|
|
|
case 'U': // Two-character constraint; add "^" hint for later parsing.
|
2011-06-08 16:06:31 +00:00
|
|
|
R = std::string("^") + std::string(Constraint, 2);
|
2011-06-07 23:45:05 +00:00
|
|
|
Constraint++;
|
|
|
|
break;
|
2011-06-17 00:40:18 +00:00
|
|
|
case 'p': // 'p' should be translated to 'r' by default.
|
|
|
|
R = std::string("r");
|
|
|
|
break;
|
2011-06-07 23:45:05 +00:00
|
|
|
default:
|
|
|
|
return std::string(1, *Constraint);
|
|
|
|
}
|
|
|
|
return R;
|
|
|
|
}
|
2014-08-22 06:05:21 +00:00
|
|
|
bool
|
2014-08-22 13:26:37 +00:00
|
|
|
validateConstraintModifier(StringRef Constraint, char Modifier, unsigned Size,
|
2014-08-22 06:05:21 +00:00
|
|
|
std::string &SuggestedModifier) const override {
|
2012-11-30 23:18:12 +00:00
|
|
|
bool isOutput = (Constraint[0] == '=');
|
2012-11-30 23:46:56 +00:00
|
|
|
bool isInOut = (Constraint[0] == '+');
|
2012-11-30 23:18:12 +00:00
|
|
|
|
2012-10-25 23:28:48 +00: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 15:24:55 +00:00
|
|
|
return (isInOut || isOutput || Size <= 64);
|
2012-10-25 23:28:48 +00:00
|
|
|
case 'q':
|
|
|
|
// A register of size 32 cannot fit a vector type.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
const char *getClobbers() const override {
|
2008-08-20 07:44:10 +00:00
|
|
|
// FIXME: Is this really right?
|
2008-04-21 18:56:49 +00:00
|
|
|
return "";
|
|
|
|
}
|
2012-10-02 14:26:08 +00:00
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
|
2012-10-02 14:26:08 +00:00
|
|
|
return (CC == CC_AAPCS || CC == CC_AAPCS_VFP) ? CCCR_OK : CCCR_Warning;
|
|
|
|
}
|
2013-02-23 04:24:36 +00:00
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
int getEHDataRegisterNumber(unsigned RegNo) const override {
|
2013-02-23 04:24:36 +00:00
|
|
|
if (RegNo == 0) return 0;
|
|
|
|
if (RegNo == 1) return 1;
|
|
|
|
return -1;
|
|
|
|
}
|
2015-07-17 00:15:22 +00:00
|
|
|
|
|
|
|
bool hasSjLjLowering() const override {
|
|
|
|
return true;
|
|
|
|
}
|
2008-04-21 18:56:49 +00:00
|
|
|
};
|
2009-09-17 07:03:19 +00:00
|
|
|
|
2013-08-21 21:59:03 +00: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 07:03:19 +00:00
|
|
|
const char * const ARMTargetInfo::GCCRegNames[] = {
|
2010-08-11 02:17:20 +00:00
|
|
|
// Integer registers
|
2009-09-17 07:03:19 +00:00
|
|
|
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
2010-08-11 02:17:20 +00: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-27 23:34:42 +00:00
|
|
|
"s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
|
2010-08-11 02:17:20 +00:00
|
|
|
|
2010-10-27 23:34:42 +00:00
|
|
|
// Double registers
|
|
|
|
"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
|
|
|
|
"d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15",
|
2010-10-28 01:05:37 +00:00
|
|
|
"d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23",
|
|
|
|
"d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
|
2010-10-27 23:34:42 +00:00
|
|
|
|
|
|
|
// Quad registers
|
2010-10-28 01:05:37 +00:00
|
|
|
"q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7",
|
|
|
|
"q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
|
2009-09-17 07:03:19 +00:00
|
|
|
};
|
|
|
|
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {
|
|
|
|
return llvm::makeArrayRef(GCCRegNames);
|
2009-09-17 07:03:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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 02:17:11 +00:00
|
|
|
{ { "r13" }, "sp" },
|
|
|
|
{ { "r14" }, "lr" },
|
|
|
|
{ { "r15" }, "pc" },
|
2010-10-27 23:34:42 +00: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 07:03:19 +00:00
|
|
|
};
|
|
|
|
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
|
|
|
|
return llvm::makeArrayRef(GCCRegAliases);
|
2009-09-17 07:03:19 +00:00
|
|
|
}
|
2010-03-03 19:03:45 +00:00
|
|
|
|
|
|
|
const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
|
2015-08-07 05:14:44 +00:00
|
|
|
#define BUILTIN(ID, TYPE, ATTRS) \
|
2015-09-18 21:26:24 +00:00
|
|
|
{ #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },
|
2015-08-07 05:14:44 +00:00
|
|
|
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
|
|
|
|
{ #ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr },
|
2014-03-29 15:09:45 +00:00
|
|
|
#include "clang/Basic/BuiltinsNEON.def"
|
2014-01-30 14:47:51 +00:00
|
|
|
|
2015-08-07 05:14:44 +00:00
|
|
|
#define BUILTIN(ID, TYPE, ATTRS) \
|
2015-09-18 21:26:24 +00:00
|
|
|
{ #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },
|
2015-08-07 05:14:44 +00:00
|
|
|
#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
|
2015-09-18 21:26:24 +00:00
|
|
|
{ #ID, TYPE, ATTRS, nullptr, LANG, nullptr },
|
2015-08-07 05:14:44 +00:00
|
|
|
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
|
|
|
|
{ #ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr },
|
2010-03-03 19:03:45 +00:00
|
|
|
#include "clang/Basic/BuiltinsARM.def"
|
|
|
|
};
|
2014-03-28 14:40:46 +00:00
|
|
|
|
|
|
|
class ARMleTargetInfo : public ARMTargetInfo {
|
|
|
|
public:
|
|
|
|
ARMleTargetInfo(const llvm::Triple &Triple)
|
|
|
|
: ARMTargetInfo(Triple, false) { }
|
2015-04-11 02:00:23 +00:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
2014-03-28 14:40:46 +00:00
|
|
|
Builder.defineMacro("__ARMEL__");
|
|
|
|
ARMTargetInfo::getTargetDefines(Opts, Builder);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class ARMbeTargetInfo : public ARMTargetInfo {
|
|
|
|
public:
|
|
|
|
ARMbeTargetInfo(const llvm::Triple &Triple)
|
|
|
|
: ARMTargetInfo(Triple, true) { }
|
2015-04-11 02:00:23 +00:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
2014-03-28 14:40:46 +00:00
|
|
|
Builder.defineMacro("__ARMEB__");
|
|
|
|
Builder.defineMacro("__ARM_BIG_ENDIAN");
|
|
|
|
ARMTargetInfo::getTargetDefines(Opts, Builder);
|
|
|
|
}
|
|
|
|
};
|
2008-04-21 18:56:49 +00:00
|
|
|
|
2014-04-04 20:31:19 +00:00
|
|
|
class WindowsARMTargetInfo : public WindowsTargetInfo<ARMleTargetInfo> {
|
|
|
|
const llvm::Triple Triple;
|
|
|
|
public:
|
|
|
|
WindowsARMTargetInfo(const llvm::Triple &Triple)
|
|
|
|
: WindowsTargetInfo<ARMleTargetInfo>(Triple), Triple(Triple) {
|
|
|
|
TLSSupported = false;
|
|
|
|
WCharType = UnsignedShort;
|
|
|
|
SizeType = UnsignedInt;
|
2016-01-27 01:04:51 +00:00
|
|
|
UserLabelPrefix = "";
|
2014-04-04 20:31:19 +00:00
|
|
|
}
|
|
|
|
void getVisualStudioDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const {
|
|
|
|
WindowsTargetInfo<ARMleTargetInfo>::getVisualStudioDefines(Opts, Builder);
|
|
|
|
|
|
|
|
// FIXME: this is invalid for WindowsCE
|
|
|
|
Builder.defineMacro("_M_ARM_NT", "1");
|
|
|
|
Builder.defineMacro("_M_ARMT", "_M_ARM");
|
|
|
|
Builder.defineMacro("_M_THUMB", "_M_ARM");
|
|
|
|
|
|
|
|
assert((Triple.getArch() == llvm::Triple::arm ||
|
|
|
|
Triple.getArch() == llvm::Triple::thumb) &&
|
|
|
|
"invalid architecture for Windows ARM target info");
|
|
|
|
unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
|
|
|
|
Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
|
|
|
|
|
|
|
|
// TODO map the complete set of values
|
|
|
|
// 31: VFPv3 40: VFPv4
|
|
|
|
Builder.defineMacro("_M_ARM_FP", "31");
|
|
|
|
}
|
2014-06-29 23:05:41 +00:00
|
|
|
BuiltinVaListKind getBuiltinVaListKind() const override {
|
|
|
|
return TargetInfo::CharPtrBuiltinVaList;
|
|
|
|
}
|
2015-08-14 18:00:09 +00:00
|
|
|
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
|
|
|
|
switch (CC) {
|
|
|
|
case CC_X86StdCall:
|
|
|
|
case CC_X86ThisCall:
|
|
|
|
case CC_X86FastCall:
|
|
|
|
case CC_X86VectorCall:
|
|
|
|
return CCCR_Ignore;
|
|
|
|
case CC_C:
|
|
|
|
return CCCR_OK;
|
|
|
|
default:
|
|
|
|
return CCCR_Warning;
|
|
|
|
}
|
|
|
|
}
|
2014-04-04 20:31:19 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// Windows ARM + Itanium C++ ABI Target
|
|
|
|
class ItaniumWindowsARMleTargetInfo : public WindowsARMTargetInfo {
|
|
|
|
public:
|
|
|
|
ItaniumWindowsARMleTargetInfo(const llvm::Triple &Triple)
|
|
|
|
: WindowsARMTargetInfo(Triple) {
|
|
|
|
TheCXXABI.set(TargetCXXABI::GenericARM);
|
|
|
|
}
|
|
|
|
|
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
|
|
|
WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
|
|
|
|
|
|
|
|
if (Opts.MSVCCompat)
|
|
|
|
WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Windows ARM, MS (C++) ABI
|
|
|
|
class MicrosoftARMleTargetInfo : public WindowsARMTargetInfo {
|
|
|
|
public:
|
|
|
|
MicrosoftARMleTargetInfo(const llvm::Triple &Triple)
|
|
|
|
: WindowsARMTargetInfo(Triple) {
|
|
|
|
TheCXXABI.set(TargetCXXABI::Microsoft);
|
|
|
|
}
|
|
|
|
|
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
|
|
|
WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
|
|
|
|
WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-07-15 13:32:23 +00:00
|
|
|
// ARM MinGW target
|
|
|
|
class MinGWARMTargetInfo : public WindowsARMTargetInfo {
|
|
|
|
public:
|
|
|
|
MinGWARMTargetInfo(const llvm::Triple &Triple)
|
|
|
|
: WindowsARMTargetInfo(Triple) {
|
|
|
|
TheCXXABI.set(TargetCXXABI::GenericARM);
|
|
|
|
}
|
|
|
|
|
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
|
|
|
WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
|
|
|
|
DefineStd(Builder, "WIN32", Opts);
|
|
|
|
DefineStd(Builder, "WINNT", Opts);
|
|
|
|
Builder.defineMacro("_ARM_");
|
|
|
|
addMinGWDefines(Opts, Builder);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// ARM Cygwin target
|
|
|
|
class CygwinARMTargetInfo : public ARMleTargetInfo {
|
|
|
|
public:
|
|
|
|
CygwinARMTargetInfo(const llvm::Triple &Triple) : ARMleTargetInfo(Triple) {
|
|
|
|
TLSSupported = false;
|
|
|
|
WCharType = UnsignedShort;
|
|
|
|
DoubleAlign = LongLongAlign = 64;
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64";
|
2015-07-15 13:32:23 +00:00
|
|
|
}
|
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
|
|
|
ARMleTargetInfo::getTargetDefines(Opts, Builder);
|
|
|
|
Builder.defineMacro("_ARM_");
|
|
|
|
Builder.defineMacro("__CYGWIN__");
|
|
|
|
Builder.defineMacro("__CYGWIN32__");
|
|
|
|
DefineStd(Builder, "unix", Opts);
|
|
|
|
if (Opts.CPlusPlus)
|
|
|
|
Builder.defineMacro("_GNU_SOURCE");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2009-09-09 15:08:12 +00:00
|
|
|
class DarwinARMTargetInfo :
|
2014-03-28 14:40:46 +00:00
|
|
|
public DarwinTargetInfo<ARMleTargetInfo> {
|
2009-06-30 17:10:35 +00:00
|
|
|
protected:
|
2014-03-11 03:39:26 +00:00
|
|
|
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
|
|
|
MacroBuilder &Builder) const override {
|
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 00:50:03 +00:00
|
|
|
getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
|
2008-08-20 07:44:10 +00:00
|
|
|
}
|
|
|
|
|
2009-03-23 16:09:04 +00:00
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
DarwinARMTargetInfo(const llvm::Triple &Triple)
|
2014-03-28 14:40:46 +00:00
|
|
|
: DarwinTargetInfo<ARMleTargetInfo>(Triple) {
|
2010-05-27 07:00:26 +00:00
|
|
|
HasAlignMac68kSupport = true;
|
2011-10-14 20:59:01 +00:00
|
|
|
// iOS always has 64-bit atomic instructions.
|
2014-11-18 22:36:15 +00:00
|
|
|
// FIXME: This should be based off of the target features in
|
|
|
|
// ARMleTargetInfo.
|
2011-10-14 20:59:01 +00:00
|
|
|
MaxAtomicInlineWidth = 64;
|
2013-01-25 22:30:49 +00:00
|
|
|
|
2016-01-27 19:32:40 +00:00
|
|
|
if (Triple.isWatchABI()) {
|
2015-10-30 16:30:45 +00:00
|
|
|
// Darwin on iOS uses a variant of the ARM C++ ABI.
|
|
|
|
TheCXXABI.set(TargetCXXABI::WatchOS);
|
|
|
|
|
|
|
|
// The 32-bit ABI is silent on what ptrdiff_t should be, but given that
|
|
|
|
// size_t is long, it's a bit weird for it to be int.
|
|
|
|
PtrDiffType = SignedLong;
|
|
|
|
|
|
|
|
// BOOL should be a real boolean on the new ABI
|
|
|
|
UseSignedCharForObjCBool = false;
|
|
|
|
} else
|
|
|
|
TheCXXABI.set(TargetCXXABI::iOS);
|
2010-05-27 07:00:26 +00:00
|
|
|
}
|
2009-03-23 16:09:04 +00:00
|
|
|
};
|
2011-12-12 21:14:55 +00:00
|
|
|
|
2014-05-24 12:52:07 +00:00
|
|
|
class AArch64TargetInfo : public TargetInfo {
|
2015-08-05 23:48:05 +00:00
|
|
|
virtual void setDataLayoutString() = 0;
|
2014-03-29 15:09:45 +00:00
|
|
|
static const TargetInfo::GCCRegAlias GCCRegAliases[];
|
|
|
|
static const char *const GCCRegNames[];
|
|
|
|
|
2014-04-16 15:33:48 +00:00
|
|
|
enum FPUModeEnum {
|
|
|
|
FPUMode,
|
|
|
|
NeonMode
|
|
|
|
};
|
|
|
|
|
|
|
|
unsigned FPU;
|
2014-05-02 15:17:51 +00:00
|
|
|
unsigned CRC;
|
2014-04-16 15:33:48 +00:00
|
|
|
unsigned Crypto;
|
2015-09-03 14:40:57 +00:00
|
|
|
unsigned Unaligned;
|
2015-11-29 10:43:59 +00:00
|
|
|
unsigned V8_1A;
|
2014-04-16 15:33:48 +00:00
|
|
|
|
2014-03-29 15:09:45 +00:00
|
|
|
static const Builtin::Info BuiltinInfo[];
|
|
|
|
|
|
|
|
std::string ABI;
|
|
|
|
|
|
|
|
public:
|
2014-05-24 12:52:07 +00:00
|
|
|
AArch64TargetInfo(const llvm::Triple &Triple)
|
2014-03-29 15:09:45 +00:00
|
|
|
: TargetInfo(Triple), ABI("aapcs") {
|
2014-05-24 12:51:25 +00:00
|
|
|
|
|
|
|
if (getTriple().getOS() == llvm::Triple::NetBSD) {
|
|
|
|
WCharType = SignedInt;
|
|
|
|
|
|
|
|
// NetBSD apparently prefers consistency across ARM targets to consistency
|
|
|
|
// across 64-bit targets.
|
|
|
|
Int64Type = SignedLongLong;
|
|
|
|
IntMaxType = SignedLongLong;
|
|
|
|
} else {
|
|
|
|
WCharType = UnsignedInt;
|
|
|
|
Int64Type = SignedLong;
|
|
|
|
IntMaxType = SignedLong;
|
|
|
|
}
|
|
|
|
|
2014-03-29 15:09:45 +00:00
|
|
|
LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
|
|
|
|
MaxVectorAlign = 128;
|
|
|
|
MaxAtomicInlineWidth = 128;
|
|
|
|
MaxAtomicPromoteWidth = 128;
|
|
|
|
|
2015-02-06 01:25:07 +00:00
|
|
|
LongDoubleWidth = LongDoubleAlign = SuitableAlign = 128;
|
2014-03-29 15:09:45 +00:00
|
|
|
LongDoubleFormat = &llvm::APFloat::IEEEquad;
|
|
|
|
|
|
|
|
// {} in inline assembly are neon specifiers, not assembly variant
|
|
|
|
// specifiers.
|
|
|
|
NoAsmVariants = true;
|
|
|
|
|
2015-01-16 18:44:04 +00:00
|
|
|
// AAPCS gives rules for bitfields. 7.1.7 says: "The container type
|
|
|
|
// contributes to the alignment of the containing aggregate in the same way
|
|
|
|
// a plain (non bit-field) member of that type would, without exception for
|
|
|
|
// zero-sized or anonymous bit-fields."
|
2015-10-30 16:30:45 +00:00
|
|
|
assert(UseBitFieldTypeAlignment && "bitfields affect type alignment");
|
2015-01-16 18:44:04 +00:00
|
|
|
UseZeroLengthBitfieldAlignment = true;
|
|
|
|
|
2014-05-24 12:52:07 +00:00
|
|
|
// AArch64 targets default to using the ARM C++ ABI.
|
2014-03-29 15:09:45 +00:00
|
|
|
TheCXXABI.set(TargetCXXABI::GenericAArch64);
|
|
|
|
}
|
|
|
|
|
2014-06-07 23:30:42 +00:00
|
|
|
StringRef getABI() const override { return ABI; }
|
2014-11-14 19:09:44 +00:00
|
|
|
bool setABI(const std::string &Name) override {
|
2014-03-29 15:09:45 +00:00
|
|
|
if (Name != "aapcs" && Name != "darwinpcs")
|
|
|
|
return false;
|
|
|
|
|
|
|
|
ABI = Name;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-11-14 19:09:44 +00:00
|
|
|
bool setCPU(const std::string &Name) override {
|
2014-03-29 15:09:45 +00:00
|
|
|
bool CPUKnown = llvm::StringSwitch<bool>(Name)
|
2014-04-16 15:06:20 +00:00
|
|
|
.Case("generic", true)
|
2016-01-05 12:53:24 +00:00
|
|
|
.Cases("cortex-a53", "cortex-a57", "cortex-a72",
|
|
|
|
"cortex-a35", "exynos-m1", true)
|
2014-03-29 15:09:45 +00:00
|
|
|
.Case("cyclone", true)
|
|
|
|
.Default(false);
|
|
|
|
return CPUKnown;
|
|
|
|
}
|
|
|
|
|
2015-04-11 02:00:23 +00:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
2014-03-29 15:09:45 +00:00
|
|
|
// Target identification.
|
|
|
|
Builder.defineMacro("__aarch64__");
|
|
|
|
|
|
|
|
// Target properties.
|
|
|
|
Builder.defineMacro("_LP64");
|
|
|
|
Builder.defineMacro("__LP64__");
|
|
|
|
|
|
|
|
// ACLE predefines. Many can only have one possible value on v8 AArch64.
|
|
|
|
Builder.defineMacro("__ARM_ACLE", "200");
|
|
|
|
Builder.defineMacro("__ARM_ARCH", "8");
|
|
|
|
Builder.defineMacro("__ARM_ARCH_PROFILE", "'A'");
|
|
|
|
|
2015-09-03 14:40:57 +00:00
|
|
|
Builder.defineMacro("__ARM_64BIT_STATE", "1");
|
2015-10-02 14:56:37 +00:00
|
|
|
Builder.defineMacro("__ARM_PCS_AAPCS64", "1");
|
2015-09-03 14:40:57 +00:00
|
|
|
Builder.defineMacro("__ARM_ARCH_ISA_A64", "1");
|
2014-03-29 15:09:45 +00:00
|
|
|
|
2015-09-03 14:40:57 +00:00
|
|
|
Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
|
|
|
|
Builder.defineMacro("__ARM_FEATURE_FMA", "1");
|
|
|
|
Builder.defineMacro("__ARM_FEATURE_LDREX", "0xF");
|
|
|
|
Builder.defineMacro("__ARM_FEATURE_IDIV", "1"); // As specified in ACLE
|
2014-09-15 11:25:38 +00:00
|
|
|
Builder.defineMacro("__ARM_FEATURE_DIV"); // For backwards compatibility
|
2015-09-03 14:40:57 +00:00
|
|
|
Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
|
|
|
|
Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
|
2014-03-29 15:09:45 +00:00
|
|
|
|
|
|
|
Builder.defineMacro("__ARM_ALIGN_MAX_STACK_PWR", "4");
|
|
|
|
|
|
|
|
// 0xe implies support for half, single and double precision operations.
|
2015-09-03 14:40:57 +00:00
|
|
|
Builder.defineMacro("__ARM_FP", "0xE");
|
2014-03-29 15:09:45 +00:00
|
|
|
|
|
|
|
// PCS specifies this for SysV variants, which is all we support. Other ABIs
|
|
|
|
// may choose __ARM_FP16_FORMAT_ALTERNATIVE.
|
2015-09-03 14:40:57 +00:00
|
|
|
Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
|
|
|
|
Builder.defineMacro("__ARM_FP16_ARGS", "1");
|
2014-03-29 15:09:45 +00:00
|
|
|
|
2015-10-02 14:56:37 +00:00
|
|
|
if (Opts.UnsafeFPMath)
|
|
|
|
Builder.defineMacro("__ARM_FP_FAST", "1");
|
2014-03-29 15:09:45 +00:00
|
|
|
|
|
|
|
Builder.defineMacro("__ARM_SIZEOF_WCHAR_T", Opts.ShortWChar ? "2" : "4");
|
|
|
|
|
|
|
|
Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM",
|
|
|
|
Opts.ShortEnums ? "1" : "4");
|
|
|
|
|
2014-04-16 15:33:48 +00:00
|
|
|
if (FPU == NeonMode) {
|
2015-09-03 14:40:57 +00:00
|
|
|
Builder.defineMacro("__ARM_NEON", "1");
|
2014-04-16 15:33:48 +00:00
|
|
|
// 64-bit NEON supports half, single and double precision operations.
|
2015-09-03 14:40:57 +00:00
|
|
|
Builder.defineMacro("__ARM_NEON_FP", "0xE");
|
2014-04-16 15:33:48 +00:00
|
|
|
}
|
2014-03-29 15:09:45 +00:00
|
|
|
|
2014-05-02 15:17:51 +00:00
|
|
|
if (CRC)
|
2015-09-03 14:40:57 +00:00
|
|
|
Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
|
2014-05-02 15:17:51 +00:00
|
|
|
|
2014-04-16 15:33:48 +00:00
|
|
|
if (Crypto)
|
2015-09-03 14:40:57 +00:00
|
|
|
Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
|
|
|
|
|
|
|
|
if (Unaligned)
|
|
|
|
Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
|
2015-05-06 15:31:46 +00:00
|
|
|
|
2015-11-29 10:43:59 +00:00
|
|
|
if (V8_1A)
|
|
|
|
Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
|
|
|
|
|
2015-05-06 15:31:46 +00:00
|
|
|
// All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8) builtins work.
|
|
|
|
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");
|
2014-03-29 15:09:45 +00:00
|
|
|
}
|
|
|
|
|
2015-10-19 04:51:35 +00:00
|
|
|
ArrayRef<Builtin::Info> getTargetBuiltins() const override {
|
|
|
|
return llvm::makeArrayRef(BuiltinInfo,
|
|
|
|
clang::AArch64::LastTSBuiltin - Builtin::FirstTSBuiltin);
|
2014-03-29 15:09:45 +00:00
|
|
|
}
|
|
|
|
|
2014-11-14 19:09:44 +00:00
|
|
|
bool hasFeature(StringRef Feature) const override {
|
2014-04-16 15:33:48 +00:00
|
|
|
return Feature == "aarch64" ||
|
|
|
|
Feature == "arm64" ||
|
2015-08-07 01:59:56 +00:00
|
|
|
Feature == "arm" ||
|
2014-04-16 15:33:48 +00:00
|
|
|
(Feature == "neon" && FPU == NeonMode);
|
2014-03-29 15:09:45 +00:00
|
|
|
}
|
|
|
|
|
2014-04-16 15:06:20 +00:00
|
|
|
bool handleTargetFeatures(std::vector<std::string> &Features,
|
|
|
|
DiagnosticsEngine &Diags) override {
|
2014-04-16 15:33:48 +00:00
|
|
|
FPU = FPUMode;
|
2014-05-02 15:17:51 +00:00
|
|
|
CRC = 0;
|
2014-04-16 15:33:48 +00:00
|
|
|
Crypto = 0;
|
2015-09-03 14:40:57 +00:00
|
|
|
Unaligned = 1;
|
2015-11-29 10:43:59 +00:00
|
|
|
V8_1A = 0;
|
2015-09-03 14:40:57 +00:00
|
|
|
|
2015-08-26 08:21:55 +00:00
|
|
|
for (const auto &Feature : Features) {
|
|
|
|
if (Feature == "+neon")
|
2014-04-16 15:33:48 +00:00
|
|
|
FPU = NeonMode;
|
2015-08-26 08:21:55 +00:00
|
|
|
if (Feature == "+crc")
|
2014-05-02 15:17:51 +00:00
|
|
|
CRC = 1;
|
2015-08-26 08:21:55 +00:00
|
|
|
if (Feature == "+crypto")
|
2014-04-16 15:33:48 +00:00
|
|
|
Crypto = 1;
|
2015-09-03 14:40:57 +00:00
|
|
|
if (Feature == "+strict-align")
|
|
|
|
Unaligned = 0;
|
2015-11-29 10:43:59 +00:00
|
|
|
if (Feature == "+v8.1a")
|
|
|
|
V8_1A = 1;
|
2014-04-16 15:33:48 +00:00
|
|
|
}
|
|
|
|
|
2015-08-05 23:48:05 +00:00
|
|
|
setDataLayoutString();
|
2014-04-16 15:06:20 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-11-14 19:09:44 +00:00
|
|
|
bool isCLZForZeroUndef() const override { return false; }
|
2014-03-29 15:09:45 +00:00
|
|
|
|
2014-11-14 19:09:44 +00:00
|
|
|
BuiltinVaListKind getBuiltinVaListKind() const override {
|
2014-03-29 15:09:45 +00:00
|
|
|
return TargetInfo::AArch64ABIBuiltinVaList;
|
|
|
|
}
|
|
|
|
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<const char *> getGCCRegNames() const override;
|
|
|
|
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
|
2014-03-29 15:09:45 +00:00
|
|
|
|
2015-04-11 02:00:23 +00:00
|
|
|
bool validateAsmConstraint(const char *&Name,
|
|
|
|
TargetInfo::ConstraintInfo &Info) const override {
|
2014-03-29 15:09:45 +00:00
|
|
|
switch (*Name) {
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
case 'w': // Floating point and SIMD registers (V0-V31)
|
|
|
|
Info.setAllowsRegister();
|
|
|
|
return true;
|
2014-04-23 10:26:19 +00:00
|
|
|
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':
|
2014-11-18 22:36:15 +00:00
|
|
|
// Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes.
|
|
|
|
// Utf: A memory address suitable for ldp/stp in TF mode.
|
|
|
|
// Usa: An absolute symbolic address.
|
|
|
|
// Ush: The high part (bits 32:12) of a pc-relative symbolic address.
|
|
|
|
llvm_unreachable("FIXME: Unimplemented support for U* constraints.");
|
2014-03-29 15:09:45 +00:00
|
|
|
case 'z': // Zero register, wzr or xzr
|
|
|
|
Info.setAllowsRegister();
|
|
|
|
return true;
|
|
|
|
case 'x': // Floating point and SIMD registers (V0-V15)
|
|
|
|
Info.setAllowsRegister();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-08-22 06:05:21 +00:00
|
|
|
bool
|
2014-08-22 13:26:37 +00:00
|
|
|
validateConstraintModifier(StringRef Constraint, char Modifier, unsigned Size,
|
2014-08-22 06:05:21 +00:00
|
|
|
std::string &SuggestedModifier) const override {
|
2014-07-25 10:19:47 +00:00
|
|
|
// Strip off constraint modifiers.
|
|
|
|
while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
|
|
|
|
Constraint = Constraint.substr(1);
|
|
|
|
|
|
|
|
switch (Constraint[0]) {
|
|
|
|
default:
|
|
|
|
return true;
|
|
|
|
case 'z':
|
|
|
|
case 'r': {
|
|
|
|
switch (Modifier) {
|
|
|
|
case 'x':
|
|
|
|
case 'w':
|
|
|
|
// For now assume that the person knows what they're
|
|
|
|
// doing with the modifier.
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
// By default an 'r' constraint will be in the 'x'
|
|
|
|
// registers.
|
2014-08-22 06:05:21 +00:00
|
|
|
if (Size == 64)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
SuggestedModifier = "w";
|
|
|
|
return false;
|
2014-07-25 10:19:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-14 19:09:44 +00:00
|
|
|
const char *getClobbers() const override { return ""; }
|
2014-03-29 15:09:45 +00:00
|
|
|
|
2014-10-01 16:56:40 +00:00
|
|
|
int getEHDataRegisterNumber(unsigned RegNo) const override {
|
2014-03-29 15:09:45 +00:00
|
|
|
if (RegNo == 0)
|
|
|
|
return 0;
|
|
|
|
if (RegNo == 1)
|
|
|
|
return 1;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2014-05-24 12:52:07 +00:00
|
|
|
const char *const AArch64TargetInfo::GCCRegNames[] = {
|
2014-03-29 15:09:45 +00:00
|
|
|
// 32-bit Integer registers
|
|
|
|
"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",
|
|
|
|
|
|
|
|
// 64-bit Integer registers
|
|
|
|
"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", "fp", "lr", "sp",
|
|
|
|
|
|
|
|
// 32-bit floating point regsisters
|
|
|
|
"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",
|
|
|
|
|
|
|
|
// 64-bit floating point regsisters
|
|
|
|
"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",
|
|
|
|
|
|
|
|
// Vector registers
|
|
|
|
"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"
|
|
|
|
};
|
|
|
|
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<const char *> AArch64TargetInfo::getGCCRegNames() const {
|
|
|
|
return llvm::makeArrayRef(GCCRegNames);
|
2014-03-29 15:09:45 +00:00
|
|
|
}
|
|
|
|
|
2014-05-24 12:52:07 +00:00
|
|
|
const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = {
|
2014-03-29 15:09:45 +00:00
|
|
|
{ { "w31" }, "wsp" },
|
|
|
|
{ { "x29" }, "fp" },
|
|
|
|
{ { "x30" }, "lr" },
|
|
|
|
{ { "x31" }, "sp" },
|
|
|
|
// The S/D/Q and W/X registers overlap, but aren't really aliases; we
|
|
|
|
// don't want to substitute one of these for a different-sized one.
|
|
|
|
};
|
|
|
|
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<TargetInfo::GCCRegAlias> AArch64TargetInfo::getGCCRegAliases() const {
|
|
|
|
return llvm::makeArrayRef(GCCRegAliases);
|
2014-03-29 15:09:45 +00:00
|
|
|
}
|
|
|
|
|
2014-05-24 12:52:07 +00:00
|
|
|
const Builtin::Info AArch64TargetInfo::BuiltinInfo[] = {
|
2014-03-29 15:09:45 +00:00
|
|
|
#define BUILTIN(ID, TYPE, ATTRS) \
|
2015-08-07 05:14:44 +00:00
|
|
|
{ #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },
|
2014-03-29 15:09:45 +00:00
|
|
|
#include "clang/Basic/BuiltinsNEON.def"
|
|
|
|
|
|
|
|
#define BUILTIN(ID, TYPE, ATTRS) \
|
2015-08-07 05:14:44 +00:00
|
|
|
{ #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },
|
2014-05-24 12:52:07 +00:00
|
|
|
#include "clang/Basic/BuiltinsAArch64.def"
|
2014-03-29 15:09:45 +00:00
|
|
|
};
|
2014-04-16 15:06:20 +00:00
|
|
|
|
2014-05-24 12:52:07 +00:00
|
|
|
class AArch64leTargetInfo : public AArch64TargetInfo {
|
2015-08-05 23:48:05 +00:00
|
|
|
void setDataLayoutString() override {
|
2014-04-16 15:06:20 +00:00
|
|
|
if (getTriple().isOSBinFormatMachO())
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = "e-m:o-i64:64-i128:128-n32:64-S128";
|
2014-04-16 15:06:20 +00:00
|
|
|
else
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = "e-m:e-i64:64-i128:128-n32:64-S128";
|
2014-04-16 15:06:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
2014-05-24 12:52:07 +00:00
|
|
|
AArch64leTargetInfo(const llvm::Triple &Triple)
|
|
|
|
: AArch64TargetInfo(Triple) {
|
2014-04-16 15:06:20 +00:00
|
|
|
BigEndian = false;
|
|
|
|
}
|
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
|
|
|
Builder.defineMacro("__AARCH64EL__");
|
2014-05-24 12:52:07 +00:00
|
|
|
AArch64TargetInfo::getTargetDefines(Opts, Builder);
|
2014-04-16 15:06:20 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2014-05-24 12:52:07 +00:00
|
|
|
class AArch64beTargetInfo : public AArch64TargetInfo {
|
2015-08-05 23:48:05 +00:00
|
|
|
void setDataLayoutString() override {
|
2014-04-16 15:06:20 +00:00
|
|
|
assert(!getTriple().isOSBinFormatMachO());
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = "E-m:e-i64:64-i128:128-n32:64-S128";
|
2014-04-16 15:06:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
2014-05-24 12:52:07 +00:00
|
|
|
AArch64beTargetInfo(const llvm::Triple &Triple)
|
|
|
|
: AArch64TargetInfo(Triple) { }
|
2014-04-16 15:06:20 +00:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
|
|
|
Builder.defineMacro("__AARCH64EB__");
|
|
|
|
Builder.defineMacro("__AARCH_BIG_ENDIAN");
|
|
|
|
Builder.defineMacro("__ARM_BIG_ENDIAN");
|
2014-05-24 12:52:07 +00:00
|
|
|
AArch64TargetInfo::getTargetDefines(Opts, Builder);
|
2014-04-16 15:06:20 +00:00
|
|
|
}
|
|
|
|
};
|
2014-03-29 15:09:45 +00:00
|
|
|
|
2014-05-24 12:52:07 +00:00
|
|
|
class DarwinAArch64TargetInfo : public DarwinTargetInfo<AArch64leTargetInfo> {
|
2014-04-16 15:06:20 +00:00
|
|
|
protected:
|
|
|
|
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
|
|
|
MacroBuilder &Builder) const override {
|
|
|
|
Builder.defineMacro("__AARCH64_SIMD__");
|
|
|
|
Builder.defineMacro("__ARM64_ARCH_8__");
|
|
|
|
Builder.defineMacro("__ARM_NEON__");
|
|
|
|
Builder.defineMacro("__LITTLE_ENDIAN__");
|
|
|
|
Builder.defineMacro("__REGISTER_PREFIX__", "");
|
|
|
|
Builder.defineMacro("__arm64", "1");
|
|
|
|
Builder.defineMacro("__arm64__", "1");
|
|
|
|
|
|
|
|
getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
|
|
|
|
}
|
|
|
|
|
2014-03-29 15:09:45 +00:00
|
|
|
public:
|
2014-05-24 12:52:07 +00:00
|
|
|
DarwinAArch64TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: DarwinTargetInfo<AArch64leTargetInfo>(Triple) {
|
2014-03-29 15:09:45 +00:00
|
|
|
Int64Type = SignedLongLong;
|
|
|
|
WCharType = SignedInt;
|
|
|
|
UseSignedCharForObjCBool = false;
|
|
|
|
|
2015-02-06 01:25:07 +00:00
|
|
|
LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64;
|
2014-03-29 15:09:45 +00:00
|
|
|
LongDoubleFormat = &llvm::APFloat::IEEEdouble;
|
|
|
|
|
|
|
|
TheCXXABI.set(TargetCXXABI::iOS64);
|
|
|
|
}
|
|
|
|
|
2014-11-14 19:09:44 +00:00
|
|
|
BuiltinVaListKind getBuiltinVaListKind() const override {
|
2014-03-29 15:09:45 +00:00
|
|
|
return TargetInfo::CharPtrBuiltinVaList;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2011-12-12 21:14:55 +00:00
|
|
|
// 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;
|
2015-12-14 15:03:57 +00:00
|
|
|
bool HasHVX, HasHVXDouble;
|
|
|
|
|
2011-12-12 21:14:55 +00:00
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
HexagonTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
|
2011-12-22 03:51:45 +00:00
|
|
|
BigEndian = false;
|
2015-12-14 15:03:57 +00:00
|
|
|
DataLayoutString = "e-m:e-p:32:32:32-"
|
|
|
|
"i64:64:64-i32:32:32-i16:16:16-i1:8:8-"
|
|
|
|
"f64:64:64-f32:32:32-v64:64:64-v32:32:32-a:0-n16:32";
|
|
|
|
SizeType = UnsignedInt;
|
|
|
|
PtrDiffType = SignedInt;
|
|
|
|
IntPtrType = SignedInt;
|
2011-12-12 21:14:55 +00:00
|
|
|
|
|
|
|
// {} in inline assembly are packet specifiers, not assembly variant
|
|
|
|
// specifiers.
|
|
|
|
NoAsmVariants = true;
|
2015-12-14 15:03:57 +00:00
|
|
|
|
|
|
|
LargeArrayMinWidth = 64;
|
|
|
|
LargeArrayAlign = 64;
|
|
|
|
UseBitFieldTypeAlignment = true;
|
|
|
|
ZeroLengthBitfieldBoundary = 32;
|
|
|
|
HasHVX = HasHVXDouble = false;
|
2011-12-12 21:14:55 +00:00
|
|
|
}
|
|
|
|
|
2015-10-19 04:51:35 +00:00
|
|
|
ArrayRef<Builtin::Info> getTargetBuiltins() const override {
|
|
|
|
return llvm::makeArrayRef(BuiltinInfo,
|
|
|
|
clang::Hexagon::LastTSBuiltin-Builtin::FirstTSBuiltin);
|
2011-12-12 21:14:55 +00:00
|
|
|
}
|
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
bool validateAsmConstraint(const char *&Name,
|
|
|
|
TargetInfo::ConstraintInfo &Info) const override {
|
2011-12-12 21:14:55 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override;
|
2011-12-12 21:14:55 +00:00
|
|
|
|
2015-12-14 15:03:57 +00:00
|
|
|
bool isCLZForZeroUndef() const override { return false; }
|
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
bool hasFeature(StringRef Feature) const override {
|
2015-12-14 15:03:57 +00:00
|
|
|
return llvm::StringSwitch<bool>(Feature)
|
|
|
|
.Case("hexagon", true)
|
|
|
|
.Case("hvx", HasHVX)
|
|
|
|
.Case("hvx-double", HasHVXDouble)
|
|
|
|
.Default(false);
|
2012-01-30 06:38:25 +00:00
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
|
2015-12-14 15:03:57 +00:00
|
|
|
bool initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
|
|
|
|
StringRef CPU, const std::vector<std::string> &FeaturesVec)
|
|
|
|
const override;
|
|
|
|
|
|
|
|
bool handleTargetFeatures(std::vector<std::string> &Features,
|
|
|
|
DiagnosticsEngine &Diags) override;
|
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
BuiltinVaListKind getBuiltinVaListKind() const override {
|
2012-06-16 03:34:49 +00:00
|
|
|
return TargetInfo::CharPtrBuiltinVaList;
|
2011-12-12 21:14:55 +00:00
|
|
|
}
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<const char *> getGCCRegNames() const override;
|
|
|
|
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
|
2014-03-11 03:39:26 +00:00
|
|
|
const char *getClobbers() const override {
|
2011-12-12 21:14:55 +00:00
|
|
|
return "";
|
|
|
|
}
|
2012-01-13 20:37:10 +00:00
|
|
|
|
|
|
|
static const char *getHexagonCPUSuffix(StringRef Name) {
|
|
|
|
return llvm::StringSwitch<const char*>(Name)
|
|
|
|
.Case("hexagonv4", "4")
|
2012-05-10 20:19:54 +00:00
|
|
|
.Case("hexagonv5", "5")
|
2015-12-14 15:03:57 +00:00
|
|
|
.Case("hexagonv55", "55")
|
|
|
|
.Case("hexagonv60", "60")
|
2014-05-08 06:41:40 +00:00
|
|
|
.Default(nullptr);
|
2012-01-13 20:37:10 +00:00
|
|
|
}
|
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
bool setCPU(const std::string &Name) override {
|
2012-01-13 20:37:10 +00:00
|
|
|
if (!getHexagonCPUSuffix(Name))
|
|
|
|
return false;
|
2011-12-12 21:14:55 +00:00
|
|
|
CPU = Name;
|
|
|
|
return true;
|
|
|
|
}
|
2015-12-14 15:03:57 +00:00
|
|
|
|
|
|
|
int getEHDataRegisterNumber(unsigned RegNo) const override {
|
|
|
|
return RegNo < 2 ? RegNo : -1;
|
|
|
|
}
|
2011-12-12 21:14:55 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts,
|
2015-12-14 15:03:57 +00:00
|
|
|
MacroBuilder &Builder) const {
|
2011-12-12 21:14:55 +00:00
|
|
|
Builder.defineMacro("__qdsp6__", "1");
|
|
|
|
Builder.defineMacro("__hexagon__", "1");
|
|
|
|
|
2015-12-14 15:03:57 +00:00
|
|
|
if (CPU == "hexagonv4") {
|
2011-12-12 21:14:55 +00:00
|
|
|
Builder.defineMacro("__HEXAGON_V4__");
|
|
|
|
Builder.defineMacro("__HEXAGON_ARCH__", "4");
|
2015-12-14 15:03:57 +00:00
|
|
|
if (Opts.HexagonQdsp6Compat) {
|
2011-12-12 21:14:55 +00:00
|
|
|
Builder.defineMacro("__QDSP6_V4__");
|
|
|
|
Builder.defineMacro("__QDSP6_ARCH__", "4");
|
|
|
|
}
|
2015-12-14 15:03:57 +00:00
|
|
|
} else if (CPU == "hexagonv5") {
|
2012-05-10 20:19:54 +00:00
|
|
|
Builder.defineMacro("__HEXAGON_V5__");
|
|
|
|
Builder.defineMacro("__HEXAGON_ARCH__", "5");
|
|
|
|
if(Opts.HexagonQdsp6Compat) {
|
|
|
|
Builder.defineMacro("__QDSP6_V5__");
|
|
|
|
Builder.defineMacro("__QDSP6_ARCH__", "5");
|
|
|
|
}
|
2015-12-14 15:03:57 +00:00
|
|
|
} else if (CPU == "hexagonv60") {
|
|
|
|
Builder.defineMacro("__HEXAGON_V60__");
|
|
|
|
Builder.defineMacro("__HEXAGON_ARCH__", "60");
|
|
|
|
Builder.defineMacro("__QDSP6_V60__");
|
|
|
|
Builder.defineMacro("__QDSP6_ARCH__", "60");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
|
|
|
|
DiagnosticsEngine &Diags) {
|
|
|
|
for (auto &F : Features) {
|
|
|
|
if (F == "+hvx")
|
|
|
|
HasHVX = true;
|
|
|
|
else if (F == "-hvx")
|
|
|
|
HasHVX = HasHVXDouble = false;
|
|
|
|
else if (F == "+hvx-double")
|
|
|
|
HasHVX = HasHVXDouble = true;
|
|
|
|
else if (F == "-hvx-double")
|
|
|
|
HasHVXDouble = false;
|
2012-05-10 20:19:54 +00:00
|
|
|
}
|
2015-12-14 15:03:57 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool HexagonTargetInfo::initFeatureMap(llvm::StringMap<bool> &Features,
|
|
|
|
DiagnosticsEngine &Diags, StringRef CPU,
|
|
|
|
const std::vector<std::string> &FeaturesVec) const {
|
|
|
|
// Default for v60: -hvx, -hvx-double.
|
|
|
|
Features["hvx"] = false;
|
|
|
|
Features["hvx-double"] = false;
|
|
|
|
|
|
|
|
return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
|
2011-12-12 21:14:55 +00:00
|
|
|
}
|
|
|
|
|
2015-12-14 15:03:57 +00:00
|
|
|
|
|
|
|
const char *const HexagonTargetInfo::GCCRegNames[] = {
|
2011-12-12 21:14:55 +00: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",
|
|
|
|
"p0", "p1", "p2", "p3",
|
|
|
|
"sa0", "lc0", "sa1", "lc1", "m0", "m1", "usr", "ugp"
|
|
|
|
};
|
|
|
|
|
2015-12-14 15:03:57 +00:00
|
|
|
ArrayRef<const char*> HexagonTargetInfo::getGCCRegNames() const {
|
2015-10-19 03:52:27 +00:00
|
|
|
return llvm::makeArrayRef(GCCRegNames);
|
2011-12-12 21:14:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = {
|
|
|
|
{ { "sp" }, "r29" },
|
|
|
|
{ { "fp" }, "r30" },
|
|
|
|
{ { "lr" }, "r31" },
|
2015-12-14 15:03:57 +00:00
|
|
|
};
|
2011-12-12 21:14:55 +00:00
|
|
|
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<TargetInfo::GCCRegAlias> HexagonTargetInfo::getGCCRegAliases() const {
|
|
|
|
return llvm::makeArrayRef(GCCRegAliases);
|
2011-12-12 21:14:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const Builtin::Info HexagonTargetInfo::BuiltinInfo[] = {
|
2015-08-07 05:14:44 +00:00
|
|
|
#define BUILTIN(ID, TYPE, ATTRS) \
|
|
|
|
{ #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },
|
|
|
|
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
|
|
|
|
{ #ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr },
|
2011-12-12 21:14:55 +00:00
|
|
|
#include "clang/Basic/BuiltinsHexagon.def"
|
|
|
|
};
|
|
|
|
|
2013-04-16 15:17:49 +00:00
|
|
|
// Shared base class for SPARC v8 (32-bit) and SPARC v9 (64-bit).
|
|
|
|
class SparcTargetInfo : public TargetInfo {
|
2009-01-27 01:58:38 +00:00
|
|
|
static const TargetInfo::GCCRegAlias GCCRegAliases[];
|
|
|
|
static const char * const GCCRegNames[];
|
2010-11-09 17:21:19 +00:00
|
|
|
bool SoftFloat;
|
2008-02-21 16:29:08 +00:00
|
|
|
public:
|
2015-05-12 00:04:20 +00:00
|
|
|
SparcTargetInfo(const llvm::Triple &Triple)
|
2016-01-27 01:04:51 +00:00
|
|
|
: TargetInfo(Triple), SoftFloat(false) {}
|
2013-04-16 15:17:49 +00:00
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
bool handleTargetFeatures(std::vector<std::string> &Features,
|
|
|
|
DiagnosticsEngine &Diags) override {
|
2015-05-12 00:04:20 +00:00
|
|
|
// The backend doesn't actually handle soft float yet, but in case someone
|
|
|
|
// is using the support for the front end continue to support it.
|
2015-04-29 23:32:17 +00:00
|
|
|
auto Feature = std::find(Features.begin(), Features.end(), "+soft-float");
|
|
|
|
if (Feature != Features.end()) {
|
|
|
|
SoftFloat = true;
|
|
|
|
Features.erase(Feature);
|
|
|
|
}
|
2013-08-21 21:59:03 +00:00
|
|
|
return true;
|
2010-11-09 17:21:19 +00:00
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
2010-01-09 17:55:51 +00:00
|
|
|
DefineStd(Builder, "sparc", Opts);
|
|
|
|
Builder.defineMacro("__REGISTER_PREFIX__", "");
|
2010-11-09 17:21:19 +00:00
|
|
|
|
|
|
|
if (SoftFloat)
|
|
|
|
Builder.defineMacro("SOFT_FLOAT", "1");
|
2008-02-21 16:29:08 +00:00
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
|
|
|
|
bool hasFeature(StringRef Feature) const override {
|
2012-01-30 06:38:25 +00:00
|
|
|
return llvm::StringSwitch<bool>(Feature)
|
|
|
|
.Case("softfloat", SoftFloat)
|
|
|
|
.Case("sparc", true)
|
|
|
|
.Default(false);
|
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
|
2015-10-19 04:51:35 +00:00
|
|
|
ArrayRef<Builtin::Info> getTargetBuiltins() const override {
|
2008-08-20 07:28:14 +00:00
|
|
|
// FIXME: Implement!
|
2015-10-19 04:51:35 +00:00
|
|
|
return None;
|
2008-02-21 16:29:08 +00:00
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
BuiltinVaListKind getBuiltinVaListKind() const override {
|
2012-06-16 03:34:49 +00:00
|
|
|
return TargetInfo::VoidPtrBuiltinVaList;
|
2008-02-21 16:29:08 +00:00
|
|
|
}
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<const char *> getGCCRegNames() const override;
|
|
|
|
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
|
2014-03-11 03:39:26 +00:00
|
|
|
bool validateAsmConstraint(const char *&Name,
|
|
|
|
TargetInfo::ConstraintInfo &info) const override {
|
2008-08-20 07:28:14 +00:00
|
|
|
// FIXME: Implement!
|
2015-01-06 04:26:34 +00:00
|
|
|
switch (*Name) {
|
|
|
|
case 'I': // Signed 13-bit constant
|
|
|
|
case 'J': // Zero
|
|
|
|
case 'K': // 32-bit constant with the low 12 bits clear
|
|
|
|
case 'L': // A constant in the range supported by movcc (11-bit signed imm)
|
|
|
|
case 'M': // A constant in the range supported by movrcc (19-bit signed imm)
|
|
|
|
case 'N': // Same as 'K' but zext (required for SIMode)
|
|
|
|
case 'O': // The constant 4096
|
|
|
|
return true;
|
|
|
|
}
|
2008-08-20 07:28:14 +00:00
|
|
|
return false;
|
2008-02-21 16:29:08 +00:00
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
const char *getClobbers() const override {
|
2008-08-20 07:28:14 +00:00
|
|
|
// FIXME: Implement!
|
|
|
|
return "";
|
2008-02-21 16:29:08 +00:00
|
|
|
}
|
2015-11-09 23:39:45 +00:00
|
|
|
|
|
|
|
// No Sparc V7 for now, the backend doesn't support it anyway.
|
|
|
|
enum CPUKind {
|
|
|
|
CK_GENERIC,
|
|
|
|
CK_V8,
|
|
|
|
CK_SUPERSPARC,
|
|
|
|
CK_SPARCLITE,
|
|
|
|
CK_F934,
|
|
|
|
CK_HYPERSPARC,
|
|
|
|
CK_SPARCLITE86X,
|
|
|
|
CK_SPARCLET,
|
|
|
|
CK_TSC701,
|
|
|
|
CK_V9,
|
|
|
|
CK_ULTRASPARC,
|
|
|
|
CK_ULTRASPARC3,
|
|
|
|
CK_NIAGARA,
|
|
|
|
CK_NIAGARA2,
|
|
|
|
CK_NIAGARA3,
|
|
|
|
CK_NIAGARA4
|
|
|
|
} CPU = CK_GENERIC;
|
|
|
|
|
|
|
|
enum CPUGeneration {
|
|
|
|
CG_V8,
|
|
|
|
CG_V9,
|
|
|
|
};
|
|
|
|
|
|
|
|
CPUGeneration getCPUGeneration(CPUKind Kind) const {
|
|
|
|
switch (Kind) {
|
|
|
|
case CK_GENERIC:
|
|
|
|
case CK_V8:
|
|
|
|
case CK_SUPERSPARC:
|
|
|
|
case CK_SPARCLITE:
|
|
|
|
case CK_F934:
|
|
|
|
case CK_HYPERSPARC:
|
|
|
|
case CK_SPARCLITE86X:
|
|
|
|
case CK_SPARCLET:
|
|
|
|
case CK_TSC701:
|
|
|
|
return CG_V8;
|
|
|
|
case CK_V9:
|
|
|
|
case CK_ULTRASPARC:
|
|
|
|
case CK_ULTRASPARC3:
|
|
|
|
case CK_NIAGARA:
|
|
|
|
case CK_NIAGARA2:
|
|
|
|
case CK_NIAGARA3:
|
|
|
|
case CK_NIAGARA4:
|
|
|
|
return CG_V9;
|
|
|
|
}
|
2015-11-11 13:42:02 +00:00
|
|
|
llvm_unreachable("Unexpected CPU kind");
|
2015-11-09 23:39:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CPUKind getCPUKind(StringRef Name) const {
|
|
|
|
return llvm::StringSwitch<CPUKind>(Name)
|
|
|
|
.Case("v8", CK_V8)
|
|
|
|
.Case("supersparc", CK_SUPERSPARC)
|
|
|
|
.Case("sparclite", CK_SPARCLITE)
|
|
|
|
.Case("f934", CK_F934)
|
|
|
|
.Case("hypersparc", CK_HYPERSPARC)
|
|
|
|
.Case("sparclite86x", CK_SPARCLITE86X)
|
|
|
|
.Case("sparclet", CK_SPARCLET)
|
|
|
|
.Case("tsc701", CK_TSC701)
|
|
|
|
.Case("v9", CK_V9)
|
|
|
|
.Case("ultrasparc", CK_ULTRASPARC)
|
|
|
|
.Case("ultrasparc3", CK_ULTRASPARC3)
|
|
|
|
.Case("niagara", CK_NIAGARA)
|
|
|
|
.Case("niagara2", CK_NIAGARA2)
|
|
|
|
.Case("niagara3", CK_NIAGARA3)
|
|
|
|
.Case("niagara4", CK_NIAGARA4)
|
|
|
|
.Default(CK_GENERIC);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool setCPU(const std::string &Name) override {
|
|
|
|
CPU = getCPUKind(Name);
|
|
|
|
return CPU != CK_GENERIC;
|
|
|
|
}
|
2008-02-21 16:29:08 +00:00
|
|
|
};
|
|
|
|
|
2013-04-16 15:17:49 +00:00
|
|
|
const char * const SparcTargetInfo::GCCRegNames[] = {
|
2009-01-27 01:58:38 +00: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"
|
|
|
|
};
|
|
|
|
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<const char *> SparcTargetInfo::getGCCRegNames() const {
|
|
|
|
return llvm::makeArrayRef(GCCRegNames);
|
2009-01-27 01:58:38 +00:00
|
|
|
}
|
|
|
|
|
2013-04-16 15:17:49 +00:00
|
|
|
const TargetInfo::GCCRegAlias SparcTargetInfo::GCCRegAliases[] = {
|
2009-05-03 13:42:53 +00: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 01:58:38 +00:00
|
|
|
};
|
|
|
|
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<TargetInfo::GCCRegAlias> SparcTargetInfo::getGCCRegAliases() const {
|
|
|
|
return llvm::makeArrayRef(GCCRegAliases);
|
2009-01-27 01:58:38 +00:00
|
|
|
}
|
2013-04-16 15:17:49 +00:00
|
|
|
|
|
|
|
// SPARC v8 is the 32-bit mode selected by Triple::sparc.
|
|
|
|
class SparcV8TargetInfo : public SparcTargetInfo {
|
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
SparcV8TargetInfo(const llvm::Triple &Triple) : SparcTargetInfo(Triple) {
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = "E-m:e-p:32:32-i64:64-f128:64-n32-S64";
|
2015-08-13 21:45:57 +00:00
|
|
|
// NetBSD / OpenBSD use long (same as llvm default); everyone else uses int.
|
|
|
|
switch (getTriple().getOS()) {
|
|
|
|
default:
|
2015-06-04 15:36:29 +00:00
|
|
|
SizeType = UnsignedInt;
|
|
|
|
IntPtrType = SignedInt;
|
|
|
|
PtrDiffType = SignedInt;
|
2015-08-13 21:45:57 +00:00
|
|
|
break;
|
|
|
|
case llvm::Triple::NetBSD:
|
|
|
|
case llvm::Triple::OpenBSD:
|
|
|
|
SizeType = UnsignedLong;
|
|
|
|
IntPtrType = SignedLong;
|
|
|
|
PtrDiffType = SignedLong;
|
|
|
|
break;
|
2015-08-13 22:00:53 +00:00
|
|
|
}
|
2013-04-16 15:17:49 +00:00
|
|
|
}
|
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
2013-04-16 15:17:49 +00:00
|
|
|
SparcTargetInfo::getTargetDefines(Opts, Builder);
|
2015-11-09 23:39:45 +00:00
|
|
|
switch (getCPUGeneration(CPU)) {
|
|
|
|
case CG_V8:
|
|
|
|
Builder.defineMacro("__sparcv8");
|
|
|
|
if (getTriple().getOS() != llvm::Triple::Solaris)
|
|
|
|
Builder.defineMacro("__sparcv8__");
|
|
|
|
break;
|
|
|
|
case CG_V9:
|
|
|
|
Builder.defineMacro("__sparcv9");
|
2015-11-10 19:28:17 +00:00
|
|
|
if (getTriple().getOS() != llvm::Triple::Solaris) {
|
2015-11-09 23:39:45 +00:00
|
|
|
Builder.defineMacro("__sparcv9__");
|
2015-11-10 19:28:17 +00:00
|
|
|
Builder.defineMacro("__sparc_v9__");
|
|
|
|
}
|
2015-11-09 23:39:45 +00:00
|
|
|
break;
|
|
|
|
}
|
2013-04-16 15:17:49 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-05-11 15:21:44 +00:00
|
|
|
// SPARCV8el is the 32-bit little-endian mode selected by Triple::sparcel.
|
|
|
|
class SparcV8elTargetInfo : public SparcV8TargetInfo {
|
|
|
|
public:
|
|
|
|
SparcV8elTargetInfo(const llvm::Triple &Triple) : SparcV8TargetInfo(Triple) {
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = "e-m:e-p:32:32-i64:64-f128:64-n32-S64";
|
2015-05-11 15:21:44 +00:00
|
|
|
BigEndian = false;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2013-04-16 15:17:49 +00:00
|
|
|
// SPARC v9 is the 64-bit mode selected by Triple::sparcv9.
|
|
|
|
class SparcV9TargetInfo : public SparcTargetInfo {
|
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
SparcV9TargetInfo(const llvm::Triple &Triple) : SparcTargetInfo(Triple) {
|
2013-04-16 15:17:49 +00:00
|
|
|
// FIXME: Support Sparc quad-precision long double?
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = "E-m:e-i64:64-n32:64-S128";
|
2013-05-15 03:22:33 +00:00
|
|
|
// This is an LP64 platform.
|
|
|
|
LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
|
2013-05-19 17:53:37 +00:00
|
|
|
|
|
|
|
// OpenBSD uses long long for int64_t and intmax_t.
|
2014-07-14 21:00:38 +00:00
|
|
|
if (getTriple().getOS() == llvm::Triple::OpenBSD)
|
2013-05-19 17:53:37 +00:00
|
|
|
IntMaxType = SignedLongLong;
|
2014-07-14 21:00:38 +00:00
|
|
|
else
|
2013-05-19 17:53:37 +00:00
|
|
|
IntMaxType = SignedLong;
|
|
|
|
Int64Type = IntMaxType;
|
2014-01-16 16:43:19 +00:00
|
|
|
|
|
|
|
// The SPARCv8 System V ABI has long double 128-bits in size, but 64-bit
|
|
|
|
// aligned. The SPARCv9 SCD 2.4.1 says 16-byte aligned.
|
|
|
|
LongDoubleWidth = 128;
|
|
|
|
LongDoubleAlign = 128;
|
|
|
|
LongDoubleFormat = &llvm::APFloat::IEEEquad;
|
2014-01-30 04:48:04 +00:00
|
|
|
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
|
2013-04-16 15:17:49 +00:00
|
|
|
}
|
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
2013-04-16 15:17:49 +00:00
|
|
|
SparcTargetInfo::getTargetDefines(Opts, Builder);
|
|
|
|
Builder.defineMacro("__sparcv9");
|
2013-04-24 04:36:38 +00:00
|
|
|
Builder.defineMacro("__arch64__");
|
2014-08-14 15:14:51 +00:00
|
|
|
// Solaris doesn't need these variants, but the BSDs do.
|
|
|
|
if (getTriple().getOS() != llvm::Triple::Solaris) {
|
2013-04-24 04:36:38 +00:00
|
|
|
Builder.defineMacro("__sparc64__");
|
|
|
|
Builder.defineMacro("__sparc_v9__");
|
|
|
|
Builder.defineMacro("__sparcv9__");
|
|
|
|
}
|
2013-04-16 15:17:49 +00:00
|
|
|
}
|
2014-02-25 18:35:30 +00:00
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
bool setCPU(const std::string &Name) override {
|
2015-11-09 23:39:45 +00:00
|
|
|
if (!SparcTargetInfo::setCPU(Name))
|
|
|
|
return false;
|
|
|
|
return getCPUGeneration(CPU) == CG_V9;
|
2014-02-25 18:35:30 +00:00
|
|
|
}
|
2013-04-16 15:17:49 +00:00
|
|
|
};
|
|
|
|
|
2014-04-10 09:56:24 +00:00
|
|
|
class SystemZTargetInfo : public TargetInfo {
|
2015-04-01 12:54:25 +00:00
|
|
|
static const Builtin::Info BuiltinInfo[];
|
2014-04-10 09:56:24 +00:00
|
|
|
static const char *const GCCRegNames[];
|
2015-04-01 12:54:25 +00:00
|
|
|
std::string CPU;
|
|
|
|
bool HasTransactionalExecution;
|
2015-05-05 19:35:52 +00:00
|
|
|
bool HasVector;
|
2013-05-06 16:26:41 +00:00
|
|
|
|
2014-04-10 09:56:24 +00:00
|
|
|
public:
|
2015-04-01 12:54:25 +00:00
|
|
|
SystemZTargetInfo(const llvm::Triple &Triple)
|
2015-10-09 18:39:59 +00:00
|
|
|
: TargetInfo(Triple), CPU("z10"), HasTransactionalExecution(false),
|
|
|
|
HasVector(false) {
|
2015-03-30 13:50:21 +00:00
|
|
|
IntMaxType = SignedLong;
|
|
|
|
Int64Type = SignedLong;
|
2014-04-10 09:56:24 +00:00
|
|
|
TLSSupported = true;
|
|
|
|
IntWidth = IntAlign = 32;
|
|
|
|
LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64;
|
|
|
|
PointerWidth = PointerAlign = 64;
|
|
|
|
LongDoubleWidth = 128;
|
|
|
|
LongDoubleAlign = 64;
|
|
|
|
LongDoubleFormat = &llvm::APFloat::IEEEquad;
|
Implement target-specific __attribute__((aligned)) value
The GCC construct __attribute__((aligned)) is defined to set alignment
to "the default alignment for the target architecture" according to
the GCC documentation:
The default alignment is sufficient for all scalar types, but may not be
enough for all vector types on a target that supports vector operations.
The default alignment is fixed for a particular target ABI.
clang currently hard-coded an alignment of 16 bytes for that construct,
which is correct on some platforms (including X86), but wrong on others
(including SystemZ). Since this value is ABI-relevant, it is important
to get correct for compatibility purposes.
This patch adds a new TargetInfo member "DefaultAlignForAttributeAligned"
that targets can set to the appropriate default __attribute__((aligned))
value.
Note that I'm deliberately *not* using the existing "SuitableAlign"
value, which is used to set the pre-defined macro __BIGGEST_ALIGNMENT__,
since those two values may not be the same on all platforms. In fact,
on X86, __attribute__((aligned)) always uses 16-byte alignment, while
__BIGGEST_ALIGNMENT__ may be larger if AVX-2 or AVX-512 are supported.
(This is actually not yet correctly implemented in clang either.)
The patch provides a value for DefaultAlignForAttributeAligned only for
SystemZ, and leaves the default for all other targets at 16, which means
no visible change in behavior on all other targets. (The value is still
wrong for some other targets, but I'd prefer to leave it to the target
maintainers for those platforms to fix.)
llvm-svn: 235397
2015-04-21 17:29:35 +00:00
|
|
|
DefaultAlignForAttributeAligned = 64;
|
2014-04-10 09:56:24 +00:00
|
|
|
MinGlobalAlign = 16;
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64";
|
2014-04-10 09:56:24 +00:00
|
|
|
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
|
|
|
|
}
|
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
|
|
|
Builder.defineMacro("__s390__");
|
|
|
|
Builder.defineMacro("__s390x__");
|
|
|
|
Builder.defineMacro("__zarch__");
|
|
|
|
Builder.defineMacro("__LONG_DOUBLE_128__");
|
2015-04-01 12:54:25 +00:00
|
|
|
if (HasTransactionalExecution)
|
|
|
|
Builder.defineMacro("__HTM__");
|
2015-07-30 14:08:36 +00:00
|
|
|
if (Opts.ZVector)
|
|
|
|
Builder.defineMacro("__VEC__", "10301");
|
2014-04-10 09:56:24 +00:00
|
|
|
}
|
2015-10-19 04:51:35 +00:00
|
|
|
ArrayRef<Builtin::Info> getTargetBuiltins() const override {
|
|
|
|
return llvm::makeArrayRef(BuiltinInfo,
|
|
|
|
clang::SystemZ::LastTSBuiltin-Builtin::FirstTSBuiltin);
|
2014-04-10 09:56:24 +00:00
|
|
|
}
|
2013-05-06 16:26:41 +00:00
|
|
|
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<const char *> getGCCRegNames() const override;
|
|
|
|
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
|
2014-04-10 09:56:24 +00:00
|
|
|
// No aliases.
|
2015-10-19 03:52:27 +00:00
|
|
|
return None;
|
2014-04-10 09:56:24 +00:00
|
|
|
}
|
|
|
|
bool validateAsmConstraint(const char *&Name,
|
|
|
|
TargetInfo::ConstraintInfo &info) const override;
|
|
|
|
const char *getClobbers() const override {
|
|
|
|
// FIXME: Is this really right?
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
BuiltinVaListKind getBuiltinVaListKind() const override {
|
|
|
|
return TargetInfo::SystemZBuiltinVaList;
|
|
|
|
}
|
|
|
|
bool setCPU(const std::string &Name) override {
|
2015-04-01 12:54:25 +00:00
|
|
|
CPU = Name;
|
2014-04-10 09:56:24 +00:00
|
|
|
bool CPUKnown = llvm::StringSwitch<bool>(Name)
|
|
|
|
.Case("z10", true)
|
|
|
|
.Case("z196", true)
|
|
|
|
.Case("zEC12", true)
|
2015-05-05 19:35:52 +00:00
|
|
|
.Case("z13", true)
|
2014-04-10 09:56:24 +00:00
|
|
|
.Default(false);
|
2013-07-19 16:51:51 +00:00
|
|
|
|
2014-04-10 09:56:24 +00:00
|
|
|
return CPUKnown;
|
|
|
|
}
|
2015-10-09 18:39:55 +00:00
|
|
|
bool
|
|
|
|
initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
|
|
|
|
StringRef CPU,
|
|
|
|
const std::vector<std::string> &FeaturesVec) const override {
|
2015-04-01 12:54:25 +00:00
|
|
|
if (CPU == "zEC12")
|
|
|
|
Features["transactional-execution"] = true;
|
2015-05-05 19:35:52 +00:00
|
|
|
if (CPU == "z13") {
|
|
|
|
Features["transactional-execution"] = true;
|
|
|
|
Features["vector"] = true;
|
|
|
|
}
|
2015-08-28 22:32:01 +00:00
|
|
|
return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
|
2015-04-01 12:54:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool handleTargetFeatures(std::vector<std::string> &Features,
|
|
|
|
DiagnosticsEngine &Diags) override {
|
|
|
|
HasTransactionalExecution = false;
|
2015-08-26 08:21:55 +00:00
|
|
|
for (const auto &Feature : Features) {
|
|
|
|
if (Feature == "+transactional-execution")
|
2015-04-01 12:54:25 +00:00
|
|
|
HasTransactionalExecution = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
else if (Feature == "+vector")
|
2015-05-05 19:35:52 +00:00
|
|
|
HasVector = true;
|
|
|
|
}
|
|
|
|
// If we use the vector ABI, vector types are 64-bit aligned.
|
|
|
|
if (HasVector) {
|
|
|
|
MaxVectorAlign = 64;
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64"
|
|
|
|
"-v128:64-a:8:16-n32:64";
|
2015-04-01 12:54:25 +00:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool hasFeature(StringRef Feature) const override {
|
|
|
|
return llvm::StringSwitch<bool>(Feature)
|
2015-04-01 14:15:35 +00:00
|
|
|
.Case("systemz", true)
|
|
|
|
.Case("htm", HasTransactionalExecution)
|
2015-05-05 19:35:52 +00:00
|
|
|
.Case("vx", HasVector)
|
2015-04-01 12:54:25 +00:00
|
|
|
.Default(false);
|
|
|
|
}
|
2015-05-05 19:35:52 +00:00
|
|
|
|
|
|
|
StringRef getABI() const override {
|
|
|
|
if (HasVector)
|
|
|
|
return "vector";
|
|
|
|
return "";
|
|
|
|
}
|
2015-06-16 15:21:47 +00:00
|
|
|
|
|
|
|
bool useFloat128ManglingForLongDouble() const override {
|
|
|
|
return true;
|
|
|
|
}
|
2015-04-01 12:54:25 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
const Builtin::Info SystemZTargetInfo::BuiltinInfo[] = {
|
|
|
|
#define BUILTIN(ID, TYPE, ATTRS) \
|
2015-08-07 05:14:44 +00:00
|
|
|
{ #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },
|
2015-04-01 12:54:25 +00:00
|
|
|
#include "clang/Basic/BuiltinsSystemZ.def"
|
2014-04-10 09:56:24 +00:00
|
|
|
};
|
2013-05-06 16:26:41 +00:00
|
|
|
|
2014-04-10 09:56:24 +00: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"
|
|
|
|
};
|
2013-05-06 16:26:41 +00:00
|
|
|
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<const char *> SystemZTargetInfo::getGCCRegNames() const {
|
|
|
|
return llvm::makeArrayRef(GCCRegNames);
|
2014-04-10 09:56:24 +00:00
|
|
|
}
|
2013-05-06 16:26:41 +00:00
|
|
|
|
2014-04-10 09:56:24 +00:00
|
|
|
bool SystemZTargetInfo::
|
|
|
|
validateAsmConstraint(const char *&Name,
|
|
|
|
TargetInfo::ConstraintInfo &Info) const {
|
|
|
|
switch (*Name) {
|
|
|
|
default:
|
|
|
|
return false;
|
2013-05-06 16:26:41 +00:00
|
|
|
|
2014-04-10 09:56:24 +00:00
|
|
|
case 'a': // Address register
|
|
|
|
case 'd': // Data register (equivalent to 'r')
|
|
|
|
case 'f': // Floating-point register
|
|
|
|
Info.setAllowsRegister();
|
|
|
|
return true;
|
2013-05-06 16:26:41 +00:00
|
|
|
|
2014-04-10 09:56:24 +00:00
|
|
|
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;
|
2013-05-06 16:26:41 +00:00
|
|
|
|
2014-04-10 09:56:24 +00:00
|
|
|
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;
|
2013-05-06 16:26:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-18 21:26:24 +00:00
|
|
|
class MSP430TargetInfo : public TargetInfo {
|
|
|
|
static const char *const GCCRegNames[];
|
|
|
|
|
|
|
|
public:
|
|
|
|
MSP430TargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
|
|
|
|
BigEndian = false;
|
|
|
|
TLSSupported = false;
|
|
|
|
IntWidth = 16;
|
|
|
|
IntAlign = 16;
|
|
|
|
LongWidth = 32;
|
|
|
|
LongLongWidth = 64;
|
|
|
|
LongAlign = LongLongAlign = 16;
|
|
|
|
PointerWidth = 16;
|
|
|
|
PointerAlign = 16;
|
|
|
|
SuitableAlign = 16;
|
|
|
|
SizeType = UnsignedInt;
|
|
|
|
IntMaxType = SignedLongLong;
|
|
|
|
IntPtrType = SignedInt;
|
|
|
|
PtrDiffType = SignedInt;
|
|
|
|
SigAtomicType = SignedLong;
|
|
|
|
DataLayoutString = "e-m:e-p:16:16-i32:16:32-a:16-n8:16";
|
|
|
|
}
|
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
|
|
|
Builder.defineMacro("MSP430");
|
|
|
|
Builder.defineMacro("__MSP430__");
|
|
|
|
// FIXME: defines for different 'flavours' of MCU
|
|
|
|
}
|
2015-10-19 04:51:35 +00:00
|
|
|
ArrayRef<Builtin::Info> getTargetBuiltins() const override {
|
2015-09-18 21:26:24 +00:00
|
|
|
// FIXME: Implement.
|
2015-10-19 04:51:35 +00:00
|
|
|
return None;
|
2015-09-18 21:26:24 +00:00
|
|
|
}
|
|
|
|
bool hasFeature(StringRef Feature) const override {
|
|
|
|
return Feature == "msp430";
|
|
|
|
}
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<const char *> getGCCRegNames() const override;
|
|
|
|
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
|
2015-09-18 21:26:24 +00:00
|
|
|
// No aliases.
|
2015-10-19 03:52:27 +00:00
|
|
|
return None;
|
2015-09-18 21:26:24 +00:00
|
|
|
}
|
|
|
|
bool validateAsmConstraint(const char *&Name,
|
|
|
|
TargetInfo::ConstraintInfo &info) const override {
|
|
|
|
// FIXME: implement
|
|
|
|
switch (*Name) {
|
|
|
|
case 'K': // the constant 1
|
|
|
|
case 'L': // constant -1^20 .. 1^19
|
|
|
|
case 'M': // constant 1-4:
|
|
|
|
return true;
|
2009-05-03 13:43:08 +00:00
|
|
|
}
|
2015-09-18 21:26:24 +00:00
|
|
|
// No target constraints for now.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
const char *getClobbers() const override {
|
|
|
|
// FIXME: Is this really right?
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
BuiltinVaListKind getBuiltinVaListKind() const override {
|
|
|
|
// FIXME: implement
|
|
|
|
return TargetInfo::CharPtrBuiltinVaList;
|
|
|
|
}
|
|
|
|
};
|
2009-05-03 13:43:08 +00:00
|
|
|
|
2015-09-18 21:26:24 +00:00
|
|
|
const char *const MSP430TargetInfo::GCCRegNames[] = {
|
|
|
|
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
|
|
|
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"};
|
2009-05-03 13:43:08 +00:00
|
|
|
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<const char *> MSP430TargetInfo::getGCCRegNames() const {
|
|
|
|
return llvm::makeArrayRef(GCCRegNames);
|
2015-09-18 21:26:24 +00:00
|
|
|
}
|
2009-08-19 20:47:07 +00:00
|
|
|
|
2015-09-18 21:26:24 +00: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
|
|
|
|
// type and alignment information.
|
|
|
|
//
|
|
|
|
// TCE uses the llvm bitcode as input and uses it for generating customized
|
|
|
|
// target processor and program binary. TCE co-design environment is
|
|
|
|
// publicly available in http://tce.cs.tut.fi
|
|
|
|
|
|
|
|
static const unsigned TCEOpenCLAddrSpaceMap[] = {
|
|
|
|
3, // opencl_global
|
|
|
|
4, // opencl_local
|
|
|
|
5, // opencl_constant
|
|
|
|
// FIXME: generic has to be added to the target
|
|
|
|
0, // opencl_generic
|
|
|
|
0, // cuda_device
|
|
|
|
0, // cuda_constant
|
|
|
|
0 // cuda_shared
|
|
|
|
};
|
2011-10-07 19:51:42 +00:00
|
|
|
|
2015-09-18 21:26:24 +00:00
|
|
|
class TCETargetInfo : public TargetInfo {
|
|
|
|
public:
|
|
|
|
TCETargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
|
|
|
|
TLSSupported = false;
|
|
|
|
IntWidth = 32;
|
|
|
|
LongWidth = LongLongWidth = 32;
|
|
|
|
PointerWidth = 32;
|
|
|
|
IntAlign = 32;
|
|
|
|
LongAlign = LongLongAlign = 32;
|
|
|
|
PointerAlign = 32;
|
|
|
|
SuitableAlign = 32;
|
|
|
|
SizeType = UnsignedInt;
|
|
|
|
IntMaxType = SignedLong;
|
|
|
|
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;
|
|
|
|
DataLayoutString = "E-p:32:32-i8:8:32-i16:16:32-i64:32"
|
|
|
|
"-f64:32-v64:32-v128:32-a:0:32-n32";
|
|
|
|
AddrSpaceMap = &TCEOpenCLAddrSpaceMap;
|
|
|
|
UseAddrSpaceMapMangling = true;
|
|
|
|
}
|
2009-08-19 20:47:07 +00:00
|
|
|
|
2015-09-18 21:26:24 +00:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
|
|
|
DefineStd(Builder, "tce", Opts);
|
|
|
|
Builder.defineMacro("__TCE__");
|
|
|
|
Builder.defineMacro("__TCE_V1__");
|
|
|
|
}
|
|
|
|
bool hasFeature(StringRef Feature) const override { return Feature == "tce"; }
|
2014-03-11 03:39:26 +00:00
|
|
|
|
2015-10-19 04:51:35 +00:00
|
|
|
ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; }
|
2015-09-18 21:26:24 +00:00
|
|
|
const char *getClobbers() const override { return ""; }
|
|
|
|
BuiltinVaListKind getBuiltinVaListKind() const override {
|
|
|
|
return TargetInfo::VoidPtrBuiltinVaList;
|
|
|
|
}
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<const char *> getGCCRegNames() const override { return None; }
|
2015-09-18 21:26:24 +00:00
|
|
|
bool validateAsmConstraint(const char *&Name,
|
|
|
|
TargetInfo::ConstraintInfo &info) const override {
|
|
|
|
return true;
|
|
|
|
}
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
|
|
|
|
return None;
|
|
|
|
}
|
2015-09-18 21:26:24 +00:00
|
|
|
};
|
2009-08-19 20:47:07 +00:00
|
|
|
|
2015-06-10 22:59:13 +00:00
|
|
|
class BPFTargetInfo : public TargetInfo {
|
|
|
|
public:
|
|
|
|
BPFTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
|
|
|
|
LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
|
|
|
|
SizeType = UnsignedLong;
|
|
|
|
PtrDiffType = SignedLong;
|
|
|
|
IntPtrType = SignedLong;
|
|
|
|
IntMaxType = SignedLong;
|
|
|
|
Int64Type = SignedLong;
|
|
|
|
RegParmMax = 5;
|
|
|
|
if (Triple.getArch() == llvm::Triple::bpfeb) {
|
|
|
|
BigEndian = true;
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = "E-m:e-p:64:64-i64:64-n32:64-S128";
|
2015-06-10 22:59:13 +00:00
|
|
|
} else {
|
|
|
|
BigEndian = false;
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = "e-m:e-p:64:64-i64:64-n32:64-S128";
|
2015-06-10 22:59:13 +00:00
|
|
|
}
|
|
|
|
MaxAtomicPromoteWidth = 64;
|
|
|
|
MaxAtomicInlineWidth = 64;
|
|
|
|
TLSSupported = false;
|
|
|
|
}
|
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
|
|
|
DefineStd(Builder, "bpf", Opts);
|
|
|
|
Builder.defineMacro("__BPF__");
|
|
|
|
}
|
|
|
|
bool hasFeature(StringRef Feature) const override {
|
|
|
|
return Feature == "bpf";
|
|
|
|
}
|
|
|
|
|
2015-10-19 04:51:35 +00:00
|
|
|
ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; }
|
2015-06-10 22:59:13 +00:00
|
|
|
const char *getClobbers() const override {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
BuiltinVaListKind getBuiltinVaListKind() const override {
|
|
|
|
return TargetInfo::VoidPtrBuiltinVaList;
|
|
|
|
}
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<const char *> getGCCRegNames() const override {
|
|
|
|
return None;
|
2015-06-10 22:59:13 +00:00
|
|
|
}
|
|
|
|
bool validateAsmConstraint(const char *&Name,
|
|
|
|
TargetInfo::ConstraintInfo &info) const override {
|
|
|
|
return true;
|
|
|
|
}
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
|
|
|
|
return None;
|
2015-06-10 22:59:13 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2011-09-20 19:00:23 +00:00
|
|
|
class MipsTargetInfoBase : public TargetInfo {
|
2015-08-05 23:48:05 +00:00
|
|
|
virtual void setDataLayoutString() = 0;
|
2013-10-29 18:30:33 +00:00
|
|
|
|
2012-06-28 18:23:16 +00:00
|
|
|
static const Builtin::Info BuiltinInfo[];
|
2011-09-20 19:00:23 +00:00
|
|
|
std::string CPU;
|
2012-07-05 16:06:06 +00:00
|
|
|
bool IsMips16;
|
2013-04-14 14:07:51 +00:00
|
|
|
bool IsMicromips;
|
2013-09-24 09:09:16 +00:00
|
|
|
bool IsNan2008;
|
2013-04-14 14:07:30 +00:00
|
|
|
bool IsSingleFloat;
|
2012-07-05 15:32:46 +00:00
|
|
|
enum MipsFloatABI {
|
2013-04-14 14:07:30 +00:00
|
|
|
HardFloat, SoftFloat
|
2012-07-05 15:32:46 +00:00
|
|
|
} FloatABI;
|
2012-07-05 20:16:22 +00:00
|
|
|
enum DspRevEnum {
|
|
|
|
NoDSP, DSP1, DSP2
|
|
|
|
} DspRev;
|
2013-08-12 17:20:29 +00:00
|
|
|
bool HasMSA;
|
2012-03-23 23:07:09 +00:00
|
|
|
|
2011-09-20 19:00:23 +00:00
|
|
|
protected:
|
2013-10-29 19:00:35 +00:00
|
|
|
bool HasFP64;
|
2011-09-20 19:00:23 +00:00
|
|
|
std::string ABI;
|
2012-03-23 23:07:09 +00:00
|
|
|
|
2009-11-15 10:22:07 +00:00
|
|
|
public:
|
2013-06-29 16:37:14 +00: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 09:09:16 +00:00
|
|
|
IsNan2008(false), IsSingleFloat(false), FloatABI(HardFloat),
|
2015-02-18 15:21:35 +00:00
|
|
|
DspRev(NoDSP), HasMSA(false), HasFP64(false), ABI(ABIStr) {
|
|
|
|
TheCXXABI.set(TargetCXXABI::GenericMIPS);
|
|
|
|
}
|
2012-03-23 23:07:09 +00:00
|
|
|
|
2014-07-09 13:56:23 +00:00
|
|
|
bool isNaN2008Default() const {
|
|
|
|
return CPU == "mips32r6" || CPU == "mips64r6";
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isFP64Default() const {
|
|
|
|
return CPU == "mips32r6" || ABI == "n32" || ABI == "n64" || ABI == "64";
|
|
|
|
}
|
|
|
|
|
2015-02-26 18:19:22 +00:00
|
|
|
bool isNan2008() const override {
|
|
|
|
return IsNan2008;
|
|
|
|
}
|
|
|
|
|
2014-06-07 23:30:42 +00:00
|
|
|
StringRef getABI() const override { return ABI; }
|
2014-03-11 03:39:26 +00:00
|
|
|
bool setCPU(const std::string &Name) override {
|
2014-07-03 08:31:23 +00:00
|
|
|
bool IsMips32 = getTriple().getArch() == llvm::Triple::mips ||
|
|
|
|
getTriple().getArch() == llvm::Triple::mipsel;
|
2010-03-02 02:41:08 +00:00
|
|
|
CPU = Name;
|
2014-07-03 08:31:23 +00:00
|
|
|
return llvm::StringSwitch<bool>(Name)
|
2014-07-04 12:36:56 +00:00
|
|
|
.Case("mips1", IsMips32)
|
|
|
|
.Case("mips2", IsMips32)
|
|
|
|
.Case("mips3", true)
|
|
|
|
.Case("mips4", true)
|
|
|
|
.Case("mips5", true)
|
2014-07-03 08:31:23 +00:00
|
|
|
.Case("mips32", IsMips32)
|
|
|
|
.Case("mips32r2", IsMips32)
|
2015-02-20 23:37:40 +00:00
|
|
|
.Case("mips32r3", IsMips32)
|
|
|
|
.Case("mips32r5", IsMips32)
|
2014-07-03 08:31:23 +00:00
|
|
|
.Case("mips32r6", IsMips32)
|
|
|
|
.Case("mips64", true)
|
|
|
|
.Case("mips64r2", true)
|
2015-02-20 23:37:40 +00:00
|
|
|
.Case("mips64r3", true)
|
|
|
|
.Case("mips64r5", true)
|
2014-07-03 08:31:23 +00:00
|
|
|
.Case("mips64r6", true)
|
2014-07-04 12:37:04 +00:00
|
|
|
.Case("octeon", true)
|
2015-10-05 12:24:30 +00:00
|
|
|
.Case("p5600", true)
|
2014-07-03 08:31:23 +00:00
|
|
|
.Default(false);
|
2010-03-02 02:41:08 +00:00
|
|
|
}
|
2014-06-05 14:59:18 +00:00
|
|
|
const std::string& getCPU() const { return CPU; }
|
2015-10-09 18:39:55 +00:00
|
|
|
bool
|
|
|
|
initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
|
|
|
|
StringRef CPU,
|
|
|
|
const std::vector<std::string> &FeaturesVec) const override {
|
2014-07-04 12:37:04 +00:00
|
|
|
if (CPU == "octeon")
|
|
|
|
Features["mips64r2"] = Features["cnmips"] = true;
|
|
|
|
else
|
|
|
|
Features[CPU] = true;
|
2015-08-28 22:32:01 +00:00
|
|
|
return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
|
2010-03-02 02:41:08 +00:00
|
|
|
}
|
2012-03-23 23:07:09 +00:00
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
2014-01-27 13:59:11 +00:00
|
|
|
Builder.defineMacro("__mips__");
|
2012-08-29 19:14:58 +00:00
|
|
|
Builder.defineMacro("_mips");
|
2014-01-27 13:59:11 +00:00
|
|
|
if (Opts.GNUMode)
|
|
|
|
Builder.defineMacro("mips");
|
|
|
|
|
2012-08-29 19:14:58 +00:00
|
|
|
Builder.defineMacro("__REGISTER_PREFIX__", "");
|
|
|
|
|
2012-07-05 15:32:46 +00: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 13:06:56 +00:00
|
|
|
}
|
2012-04-05 19:28:31 +00:00
|
|
|
|
2013-04-14 14:07:30 +00:00
|
|
|
if (IsSingleFloat)
|
|
|
|
Builder.defineMacro("__mips_single_float", Twine(1));
|
|
|
|
|
2013-10-18 13:13:53 +00:00
|
|
|
Builder.defineMacro("__mips_fpr", HasFP64 ? Twine(64) : Twine(32));
|
|
|
|
Builder.defineMacro("_MIPS_FPSET",
|
|
|
|
Twine(32 / (HasFP64 || IsSingleFloat ? 1 : 2)));
|
|
|
|
|
2012-07-05 16:06:06 +00:00
|
|
|
if (IsMips16)
|
|
|
|
Builder.defineMacro("__mips16", Twine(1));
|
|
|
|
|
2013-04-14 14:07:51 +00:00
|
|
|
if (IsMicromips)
|
|
|
|
Builder.defineMacro("__mips_micromips", Twine(1));
|
|
|
|
|
2013-09-24 09:09:16 +00:00
|
|
|
if (IsNan2008)
|
|
|
|
Builder.defineMacro("__mips_nan2008", Twine(1));
|
|
|
|
|
2012-07-05 20:16:22 +00: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-12 17:20:29 +00:00
|
|
|
if (HasMSA)
|
|
|
|
Builder.defineMacro("__mips_msa", Twine(1));
|
|
|
|
|
2012-04-05 19:28:31 +00:00
|
|
|
Builder.defineMacro("_MIPS_SZPTR", Twine(getPointerWidth(0)));
|
|
|
|
Builder.defineMacro("_MIPS_SZINT", Twine(getIntWidth()));
|
|
|
|
Builder.defineMacro("_MIPS_SZLONG", Twine(getLongWidth()));
|
2012-08-29 15:17:29 +00:00
|
|
|
|
|
|
|
Builder.defineMacro("_MIPS_ARCH", "\"" + CPU + "\"");
|
|
|
|
Builder.defineMacro("_MIPS_ARCH_" + StringRef(CPU).upper());
|
2015-12-22 12:59:30 +00:00
|
|
|
|
|
|
|
// These shouldn't be defined for MIPS-I but there's no need to check
|
|
|
|
// for that since MIPS-I isn't supported.
|
|
|
|
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");
|
2012-03-23 23:07:09 +00:00
|
|
|
}
|
|
|
|
|
2015-10-19 04:51:35 +00:00
|
|
|
ArrayRef<Builtin::Info> getTargetBuiltins() const override {
|
|
|
|
return llvm::makeArrayRef(BuiltinInfo,
|
|
|
|
clang::Mips::LastTSBuiltin - Builtin::FirstTSBuiltin);
|
2009-11-15 10:22:07 +00:00
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
bool hasFeature(StringRef Feature) const override {
|
2013-10-29 19:00:35 +00:00
|
|
|
return llvm::StringSwitch<bool>(Feature)
|
|
|
|
.Case("mips", true)
|
|
|
|
.Case("fp64", HasFP64)
|
|
|
|
.Default(false);
|
2012-01-30 06:38:25 +00:00
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
BuiltinVaListKind getBuiltinVaListKind() const override {
|
2012-06-16 03:34:49 +00:00
|
|
|
return TargetInfo::VoidPtrBuiltinVaList;
|
2009-11-15 10:22:07 +00:00
|
|
|
}
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<const char *> getGCCRegNames() const override {
|
2013-11-12 12:56:01 +00:00
|
|
|
static const char *const GCCRegNames[] = {
|
2012-03-27 19:56:11 +00:00
|
|
|
// CPU register names
|
|
|
|
// Must match second column of GCCRegAliases
|
2011-09-20 19:00:23 +00: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-27 19:56:11 +00:00
|
|
|
"$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31",
|
|
|
|
// Floating point register names
|
2011-09-20 19:00:23 +00: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-27 19:56:11 +00:00
|
|
|
// Hi/lo and condition register names
|
2011-09-20 19:00:23 +00:00
|
|
|
"hi", "lo", "", "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
|
2013-11-12 12:56:01 +00: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-20 19:00:23 +00:00
|
|
|
};
|
2015-10-19 03:52:27 +00:00
|
|
|
return llvm::makeArrayRef(GCCRegNames);
|
2011-09-20 19:00:23 +00:00
|
|
|
}
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override = 0;
|
2014-03-11 03:39:26 +00:00
|
|
|
bool validateAsmConstraint(const char *&Name,
|
|
|
|
TargetInfo::ConstraintInfo &Info) const override {
|
2009-11-15 10:22:07 +00:00
|
|
|
switch (*Name) {
|
|
|
|
default:
|
2011-11-02 20:52:01 +00:00
|
|
|
return false;
|
2009-11-15 10:22:07 +00:00
|
|
|
case 'r': // CPU registers.
|
|
|
|
case 'd': // Equivalent to "r" unless generating MIPS16 code.
|
2014-07-14 19:42:55 +00:00
|
|
|
case 'y': // Equivalent to "r", backward compatibility only.
|
2009-11-15 10:22:07 +00:00
|
|
|
case 'f': // floating-point registers.
|
2012-04-03 01:16:32 +00:00
|
|
|
case 'c': // $25 for indirect jumps
|
|
|
|
case 'l': // lo register
|
|
|
|
case 'x': // hilo register pair
|
2009-11-15 10:22:07 +00:00
|
|
|
Info.setAllowsRegister();
|
|
|
|
return true;
|
2015-01-06 04:26:34 +00:00
|
|
|
case 'I': // Signed 16-bit constant
|
|
|
|
case 'J': // Integer 0
|
|
|
|
case 'K': // Unsigned 16-bit constant
|
|
|
|
case 'L': // Signed 32-bit constant, lower 16-bit zeros (for lui)
|
|
|
|
case 'M': // Constants not loadable via lui, addiu, or ori
|
|
|
|
case 'N': // Constant -1 to -65535
|
|
|
|
case 'O': // A signed 15-bit constant
|
|
|
|
case 'P': // A constant between 1 go 65535
|
|
|
|
return true;
|
2013-03-05 19:10:54 +00:00
|
|
|
case 'R': // An address that can be used in a non-macro load or store
|
2013-03-04 21:36:11 +00:00
|
|
|
Info.setAllowsMemory();
|
|
|
|
return true;
|
2015-03-30 13:47:23 +00:00
|
|
|
case 'Z':
|
|
|
|
if (Name[1] == 'C') { // An address usable by ll, and sc.
|
|
|
|
Info.setAllowsMemory();
|
|
|
|
Name++; // Skip over 'Z'.
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string convertConstraint(const char *&Constraint) const override {
|
|
|
|
std::string R;
|
|
|
|
switch (*Constraint) {
|
|
|
|
case 'Z': // Two-character constraint; add "^" hint for later parsing.
|
|
|
|
if (Constraint[1] == 'C') {
|
|
|
|
R = std::string("^") + std::string(Constraint, 2);
|
|
|
|
Constraint++;
|
|
|
|
return R;
|
|
|
|
}
|
|
|
|
break;
|
2009-11-15 10:22:07 +00:00
|
|
|
}
|
2015-03-30 13:47:23 +00:00
|
|
|
return TargetInfo::convertConstraint(Constraint);
|
2009-11-15 10:22:07 +00:00
|
|
|
}
|
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
const char *getClobbers() const override {
|
2015-01-12 14:41:30 +00:00
|
|
|
// In GCC, $1 is not widely used in generated code (it's used only in a few
|
|
|
|
// specific situations), so there is no real need for users to add it to
|
|
|
|
// the clobbers list if they want to use it in their inline assembly code.
|
|
|
|
//
|
|
|
|
// In LLVM, $1 is treated as a normal GPR and is always allocatable during
|
|
|
|
// code generation, so using it in inline assembly without adding it to the
|
|
|
|
// clobbers list can cause conflicts between the inline assembly code and
|
|
|
|
// the surrounding generated code.
|
|
|
|
//
|
|
|
|
// Another problem is that LLVM is allowed to choose $1 for inline assembly
|
|
|
|
// operands, which will conflict with the ".set at" assembler option (which
|
|
|
|
// we use only for inline assembly, in order to maintain compatibility with
|
|
|
|
// GCC) and will also conflict with the user's usage of $1.
|
|
|
|
//
|
|
|
|
// The easiest way to avoid these conflicts and keep $1 as an allocatable
|
|
|
|
// register for generated code is to automatically clobber $1 for all inline
|
|
|
|
// assembly code.
|
|
|
|
//
|
|
|
|
// FIXME: We should automatically clobber $1 only for inline assembly code
|
|
|
|
// which actually uses it. This would allow LLVM to use $1 for inline
|
|
|
|
// assembly operands if the user's assembly code doesn't use it.
|
2014-12-17 12:02:58 +00:00
|
|
|
return "~{$1}";
|
2009-11-15 10:22:07 +00:00
|
|
|
}
|
2012-03-23 23:07:09 +00:00
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
bool handleTargetFeatures(std::vector<std::string> &Features,
|
|
|
|
DiagnosticsEngine &Diags) override {
|
2012-07-05 16:06:06 +00:00
|
|
|
IsMips16 = false;
|
2013-04-14 14:07:51 +00:00
|
|
|
IsMicromips = false;
|
2014-07-09 13:56:23 +00:00
|
|
|
IsNan2008 = isNaN2008Default();
|
2013-04-14 14:07:30 +00:00
|
|
|
IsSingleFloat = false;
|
2012-07-05 15:32:46 +00:00
|
|
|
FloatABI = HardFloat;
|
2012-07-05 20:16:22 +00:00
|
|
|
DspRev = NoDSP;
|
2014-07-09 13:56:23 +00:00
|
|
|
HasFP64 = isFP64Default();
|
2012-03-23 23:07:09 +00:00
|
|
|
|
2015-08-26 08:21:55 +00:00
|
|
|
for (const auto &Feature : Features) {
|
|
|
|
if (Feature == "+single-float")
|
2013-04-14 14:07:30 +00:00
|
|
|
IsSingleFloat = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
else if (Feature == "+soft-float")
|
2012-07-05 15:32:46 +00:00
|
|
|
FloatABI = SoftFloat;
|
2015-08-26 08:21:55 +00:00
|
|
|
else if (Feature == "+mips16")
|
2012-07-05 16:06:06 +00:00
|
|
|
IsMips16 = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
else if (Feature == "+micromips")
|
2013-04-14 14:07:51 +00:00
|
|
|
IsMicromips = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
else if (Feature == "+dsp")
|
2012-07-05 20:16:22 +00:00
|
|
|
DspRev = std::max(DspRev, DSP1);
|
2015-08-26 08:21:55 +00:00
|
|
|
else if (Feature == "+dspr2")
|
2012-07-05 20:16:22 +00:00
|
|
|
DspRev = std::max(DspRev, DSP2);
|
2015-08-26 08:21:55 +00:00
|
|
|
else if (Feature == "+msa")
|
2013-08-12 17:20:29 +00:00
|
|
|
HasMSA = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
else if (Feature == "+fp64")
|
2013-10-18 13:13:53 +00:00
|
|
|
HasFP64 = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
else if (Feature == "-fp64")
|
2013-10-18 13:13:53 +00:00
|
|
|
HasFP64 = false;
|
2015-08-26 08:21:55 +00:00
|
|
|
else if (Feature == "+nan2008")
|
2013-09-24 09:09:16 +00:00
|
|
|
IsNan2008 = true;
|
2015-08-26 08:21:55 +00:00
|
|
|
else if (Feature == "-nan2008")
|
2014-07-09 13:56:23 +00:00
|
|
|
IsNan2008 = false;
|
2012-03-23 23:07:09 +00:00
|
|
|
}
|
2012-07-05 15:32:46 +00:00
|
|
|
|
2015-08-05 23:48:05 +00:00
|
|
|
setDataLayoutString();
|
2013-10-29 18:30:33 +00:00
|
|
|
|
2013-08-21 21:59:03 +00:00
|
|
|
return true;
|
2012-03-23 23:07:09 +00:00
|
|
|
}
|
2013-02-23 04:24:36 +00:00
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
int getEHDataRegisterNumber(unsigned RegNo) const override {
|
2013-02-23 04:24:36 +00:00
|
|
|
if (RegNo == 0) return 4;
|
|
|
|
if (RegNo == 1) return 5;
|
|
|
|
return -1;
|
|
|
|
}
|
2014-07-09 13:43:19 +00:00
|
|
|
|
|
|
|
bool isCLZForZeroUndef() const override { return false; }
|
2009-11-15 10:22:07 +00:00
|
|
|
};
|
|
|
|
|
2012-06-28 18:23:16 +00:00
|
|
|
const Builtin::Info MipsTargetInfoBase::BuiltinInfo[] = {
|
2015-08-07 05:14:44 +00:00
|
|
|
#define BUILTIN(ID, TYPE, ATTRS) \
|
|
|
|
{ #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },
|
|
|
|
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
|
|
|
|
{ #ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr },
|
2012-06-28 18:23:16 +00:00
|
|
|
#include "clang/Basic/BuiltinsMips.def"
|
|
|
|
};
|
|
|
|
|
2011-09-20 19:00:23 +00:00
|
|
|
class Mips32TargetInfoBase : public MipsTargetInfoBase {
|
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
Mips32TargetInfoBase(const llvm::Triple &Triple)
|
2014-01-27 13:59:04 +00:00
|
|
|
: MipsTargetInfoBase(Triple, "o32", "mips32r2") {
|
2011-11-05 01:48:34 +00:00
|
|
|
SizeType = UnsignedInt;
|
|
|
|
PtrDiffType = SignedInt;
|
2015-01-22 23:16:48 +00:00
|
|
|
Int64Type = SignedLongLong;
|
|
|
|
IntMaxType = Int64Type;
|
2013-01-18 21:58:11 +00:00
|
|
|
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32;
|
2011-11-05 01:48:34 +00:00
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
bool setABI(const std::string &Name) override {
|
2014-06-28 15:56:03 +00:00
|
|
|
if (Name == "o32" || Name == "eabi") {
|
2011-09-20 19:00:23 +00:00
|
|
|
ABI = Name;
|
|
|
|
return true;
|
2014-06-28 15:56:08 +00:00
|
|
|
}
|
|
|
|
return false;
|
2011-09-20 19:00:23 +00:00
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
2012-08-29 19:59:32 +00:00
|
|
|
MipsTargetInfoBase::getTargetDefines(Opts, Builder);
|
2012-03-23 23:07:09 +00:00
|
|
|
|
2014-01-27 13:59:11 +00:00
|
|
|
Builder.defineMacro("__mips", "32");
|
2014-06-05 14:59:18 +00:00
|
|
|
Builder.defineMacro("_MIPS_ISA", "_MIPS_ISA_MIPS32");
|
|
|
|
|
|
|
|
const std::string& CPUStr = getCPU();
|
|
|
|
if (CPUStr == "mips32")
|
|
|
|
Builder.defineMacro("__mips_isa_rev", "1");
|
|
|
|
else if (CPUStr == "mips32r2")
|
|
|
|
Builder.defineMacro("__mips_isa_rev", "2");
|
2015-02-20 23:37:40 +00:00
|
|
|
else if (CPUStr == "mips32r3")
|
|
|
|
Builder.defineMacro("__mips_isa_rev", "3");
|
|
|
|
else if (CPUStr == "mips32r5")
|
|
|
|
Builder.defineMacro("__mips_isa_rev", "5");
|
2015-01-15 07:04:48 +00:00
|
|
|
else if (CPUStr == "mips32r6")
|
|
|
|
Builder.defineMacro("__mips_isa_rev", "6");
|
2014-01-27 13:59:11 +00:00
|
|
|
|
2011-09-20 19:00:23 +00: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 05:06:16 +00:00
|
|
|
llvm_unreachable("Invalid ABI for Mips32.");
|
2011-09-20 19:00:23 +00:00
|
|
|
}
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
|
2011-09-20 19:00:23 +00:00
|
|
|
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-27 19:56:11 +00:00
|
|
|
{ { "sp","$sp" }, "$29" },
|
|
|
|
{ { "fp","$fp" }, "$30" },
|
2011-09-20 19:00:23 +00:00
|
|
|
{ { "ra" }, "$31" }
|
|
|
|
};
|
2015-10-19 03:52:27 +00:00
|
|
|
return llvm::makeArrayRef(GCCRegAliases);
|
2011-09-20 19:00:23 +00:00
|
|
|
}
|
2009-11-15 10:22:07 +00:00
|
|
|
};
|
|
|
|
|
2011-09-20 19:00:23 +00:00
|
|
|
class Mips32EBTargetInfo : public Mips32TargetInfoBase {
|
2015-08-05 23:48:05 +00:00
|
|
|
void setDataLayoutString() override {
|
|
|
|
DataLayoutString = "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64";
|
2013-10-29 18:30:33 +00:00
|
|
|
}
|
|
|
|
|
2011-09-20 19:00:23 +00:00
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
Mips32EBTargetInfo(const llvm::Triple &Triple)
|
|
|
|
: Mips32TargetInfoBase(Triple) {
|
2011-09-20 19:00:23 +00:00
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
2011-09-20 19:00:23 +00:00
|
|
|
DefineStd(Builder, "MIPSEB", Opts);
|
|
|
|
Builder.defineMacro("_MIPSEB");
|
2012-08-29 19:59:32 +00:00
|
|
|
Mips32TargetInfoBase::getTargetDefines(Opts, Builder);
|
2011-09-20 19:00:23 +00:00
|
|
|
}
|
2009-11-15 10:22:07 +00:00
|
|
|
};
|
|
|
|
|
2011-09-20 19:00:23 +00:00
|
|
|
class Mips32ELTargetInfo : public Mips32TargetInfoBase {
|
2015-08-05 23:48:05 +00:00
|
|
|
void setDataLayoutString() override {
|
|
|
|
DataLayoutString = "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64";
|
2013-10-29 18:30:33 +00:00
|
|
|
}
|
|
|
|
|
2009-11-15 10:22:07 +00:00
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
Mips32ELTargetInfo(const llvm::Triple &Triple)
|
|
|
|
: Mips32TargetInfoBase(Triple) {
|
2011-12-22 03:51:45 +00:00
|
|
|
BigEndian = false;
|
2009-11-15 10:22:07 +00:00
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
2011-09-20 19:00:23 +00:00
|
|
|
DefineStd(Builder, "MIPSEL", Opts);
|
|
|
|
Builder.defineMacro("_MIPSEL");
|
2012-08-29 19:59:32 +00:00
|
|
|
Mips32TargetInfoBase::getTargetDefines(Opts, Builder);
|
2011-09-20 19:00:23 +00:00
|
|
|
}
|
2009-11-15 10:22:07 +00:00
|
|
|
};
|
2011-09-20 19:21:49 +00:00
|
|
|
|
|
|
|
class Mips64TargetInfoBase : public MipsTargetInfoBase {
|
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
Mips64TargetInfoBase(const llvm::Triple &Triple)
|
2014-01-27 13:59:04 +00:00
|
|
|
: MipsTargetInfoBase(Triple, "n64", "mips64r2") {
|
2011-10-22 00:07:27 +00:00
|
|
|
LongDoubleWidth = LongDoubleAlign = 128;
|
|
|
|
LongDoubleFormat = &llvm::APFloat::IEEEquad;
|
2012-12-08 09:06:08 +00:00
|
|
|
if (getTriple().getOS() == llvm::Triple::FreeBSD) {
|
|
|
|
LongDoubleWidth = LongDoubleAlign = 64;
|
|
|
|
LongDoubleFormat = &llvm::APFloat::IEEEdouble;
|
|
|
|
}
|
2014-04-24 09:58:52 +00:00
|
|
|
setN64ABITypes();
|
2011-12-16 22:34:14 +00:00
|
|
|
SuitableAlign = 128;
|
2013-01-18 21:58:11 +00:00
|
|
|
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
|
2011-10-22 00:07:27 +00:00
|
|
|
}
|
2014-04-24 09:58:52 +00:00
|
|
|
|
|
|
|
void setN64ABITypes() {
|
|
|
|
LongWidth = LongAlign = 64;
|
|
|
|
PointerWidth = PointerAlign = 64;
|
|
|
|
SizeType = UnsignedLong;
|
|
|
|
PtrDiffType = SignedLong;
|
2015-01-22 23:16:48 +00:00
|
|
|
Int64Type = SignedLong;
|
|
|
|
IntMaxType = Int64Type;
|
2014-04-24 09:58:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void setN32ABITypes() {
|
|
|
|
LongWidth = LongAlign = 32;
|
|
|
|
PointerWidth = PointerAlign = 32;
|
|
|
|
SizeType = UnsignedInt;
|
|
|
|
PtrDiffType = SignedInt;
|
2015-01-22 23:16:48 +00:00
|
|
|
Int64Type = SignedLongLong;
|
|
|
|
IntMaxType = Int64Type;
|
2014-04-24 09:58:52 +00:00
|
|
|
}
|
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
bool setABI(const std::string &Name) override {
|
2011-10-22 00:07:27 +00:00
|
|
|
if (Name == "n32") {
|
2014-04-24 09:58:52 +00:00
|
|
|
setN32ABITypes();
|
2013-02-27 14:55:49 +00:00
|
|
|
ABI = Name;
|
|
|
|
return true;
|
2014-06-28 15:56:08 +00:00
|
|
|
}
|
2014-07-01 10:59:09 +00:00
|
|
|
if (Name == "n64") {
|
2014-04-24 09:58:52 +00:00
|
|
|
setN64ABITypes();
|
2014-07-01 10:59:09 +00:00
|
|
|
ABI = Name;
|
2013-02-27 14:55:49 +00:00
|
|
|
return true;
|
2014-04-24 09:58:52 +00:00
|
|
|
}
|
|
|
|
return false;
|
2011-09-20 19:21:49 +00:00
|
|
|
}
|
2014-04-24 09:58:52 +00:00
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
2012-08-29 19:59:32 +00:00
|
|
|
MipsTargetInfoBase::getTargetDefines(Opts, Builder);
|
2012-03-23 23:07:09 +00:00
|
|
|
|
2014-01-27 13:59:11 +00:00
|
|
|
Builder.defineMacro("__mips", "64");
|
2012-08-29 20:50:11 +00:00
|
|
|
Builder.defineMacro("__mips64");
|
|
|
|
Builder.defineMacro("__mips64__");
|
2014-06-05 14:59:18 +00:00
|
|
|
Builder.defineMacro("_MIPS_ISA", "_MIPS_ISA_MIPS64");
|
|
|
|
|
|
|
|
const std::string& CPUStr = getCPU();
|
|
|
|
if (CPUStr == "mips64")
|
|
|
|
Builder.defineMacro("__mips_isa_rev", "1");
|
|
|
|
else if (CPUStr == "mips64r2")
|
|
|
|
Builder.defineMacro("__mips_isa_rev", "2");
|
2015-02-20 23:37:40 +00:00
|
|
|
else if (CPUStr == "mips64r3")
|
|
|
|
Builder.defineMacro("__mips_isa_rev", "3");
|
|
|
|
else if (CPUStr == "mips64r5")
|
|
|
|
Builder.defineMacro("__mips_isa_rev", "5");
|
2015-01-15 07:04:48 +00:00
|
|
|
else if (CPUStr == "mips64r6")
|
|
|
|
Builder.defineMacro("__mips_isa_rev", "6");
|
2012-08-29 20:50:11 +00:00
|
|
|
|
2011-09-20 19:21:49 +00: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 05:06:16 +00:00
|
|
|
llvm_unreachable("Invalid ABI for Mips64.");
|
2015-12-22 12:59:30 +00:00
|
|
|
|
|
|
|
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
|
2011-09-20 19:21:49 +00:00
|
|
|
}
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
|
2011-09-20 19:21:49 +00:00
|
|
|
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-27 19:56:11 +00:00
|
|
|
{ { "sp","$sp" }, "$29" },
|
|
|
|
{ { "fp","$fp" }, "$30" },
|
2011-09-20 19:21:49 +00:00
|
|
|
{ { "ra" }, "$31" }
|
|
|
|
};
|
2015-10-19 03:52:27 +00:00
|
|
|
return llvm::makeArrayRef(GCCRegAliases);
|
2011-09-20 19:21:49 +00:00
|
|
|
}
|
2014-04-24 16:05:26 +00:00
|
|
|
|
|
|
|
bool hasInt128Type() const override { return true; }
|
2011-09-20 19:21:49 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class Mips64EBTargetInfo : public Mips64TargetInfoBase {
|
2015-08-05 23:48:05 +00:00
|
|
|
void setDataLayoutString() override {
|
2013-10-29 18:30:33 +00:00
|
|
|
if (ABI == "n32")
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32:64-S128";
|
2013-10-29 18:30:33 +00:00
|
|
|
else
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = "E-m:m-i8:8:32-i16:16:32-i64:64-n32:64-S128";
|
2013-10-29 18:30:33 +00:00
|
|
|
|
2011-09-20 19:21:49 +00:00
|
|
|
}
|
2013-10-29 18:30:33 +00:00
|
|
|
|
2011-09-20 19:21:49 +00:00
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
Mips64EBTargetInfo(const llvm::Triple &Triple)
|
2013-10-29 18:30:33 +00:00
|
|
|
: Mips64TargetInfoBase(Triple) {}
|
2014-03-11 03:39:26 +00:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
2011-09-20 19:21:49 +00:00
|
|
|
DefineStd(Builder, "MIPSEB", Opts);
|
|
|
|
Builder.defineMacro("_MIPSEB");
|
2012-08-29 19:59:32 +00:00
|
|
|
Mips64TargetInfoBase::getTargetDefines(Opts, Builder);
|
2011-09-20 19:21:49 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class Mips64ELTargetInfo : public Mips64TargetInfoBase {
|
2015-08-05 23:48:05 +00:00
|
|
|
void setDataLayoutString() override {
|
2013-10-29 18:30:33 +00:00
|
|
|
if (ABI == "n32")
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32:64-S128";
|
2013-10-29 18:30:33 +00:00
|
|
|
else
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = "e-m:m-i8:8:32-i16:16:32-i64:64-n32:64-S128";
|
2011-09-20 19:21:49 +00:00
|
|
|
}
|
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
Mips64ELTargetInfo(const llvm::Triple &Triple)
|
|
|
|
: Mips64TargetInfoBase(Triple) {
|
2011-12-22 03:51:45 +00:00
|
|
|
// Default ABI is n64.
|
|
|
|
BigEndian = false;
|
2011-09-20 19:21:49 +00:00
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
2011-09-20 19:21:49 +00:00
|
|
|
DefineStd(Builder, "MIPSEL", Opts);
|
|
|
|
Builder.defineMacro("_MIPSEL");
|
2012-08-29 19:59:32 +00:00
|
|
|
Mips64TargetInfoBase::getTargetDefines(Opts, Builder);
|
2011-09-20 19:21:49 +00:00
|
|
|
}
|
|
|
|
};
|
2009-11-15 10:22:07 +00:00
|
|
|
|
2011-08-24 20:22:22 +00:00
|
|
|
class PNaClTargetInfo : public TargetInfo {
|
|
|
|
public:
|
2013-06-29 16:37:14 +00:00
|
|
|
PNaClTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
|
2011-12-22 03:51:45 +00:00
|
|
|
BigEndian = false;
|
2016-01-27 01:04:51 +00:00
|
|
|
this->UserLabelPrefix = "";
|
2011-08-24 20:22:22 +00:00
|
|
|
this->LongAlign = 32;
|
|
|
|
this->LongWidth = 32;
|
|
|
|
this->PointerAlign = 32;
|
|
|
|
this->PointerWidth = 32;
|
|
|
|
this->IntMaxType = TargetInfo::SignedLongLong;
|
|
|
|
this->Int64Type = TargetInfo::SignedLongLong;
|
2011-08-29 22:39:12 +00:00
|
|
|
this->DoubleAlign = 64;
|
2011-09-20 14:56:54 +00:00
|
|
|
this->LongDoubleWidth = 64;
|
2011-08-29 22:39:12 +00:00
|
|
|
this->LongDoubleAlign = 64;
|
2011-09-20 14:56:54 +00:00
|
|
|
this->SizeType = TargetInfo::UnsignedInt;
|
|
|
|
this->PtrDiffType = TargetInfo::SignedInt;
|
|
|
|
this->IntPtrType = TargetInfo::SignedInt;
|
2013-04-08 21:31:01 +00:00
|
|
|
this->RegParmMax = 0; // Disallow regparm
|
2011-08-24 20:22:22 +00:00
|
|
|
}
|
|
|
|
|
2014-03-11 04:07:52 +00:00
|
|
|
void getArchDefines(const LangOptions &Opts, MacroBuilder &Builder) const {
|
2011-08-24 20:22:22 +00:00
|
|
|
Builder.defineMacro("__le32__");
|
|
|
|
Builder.defineMacro("__pnacl__");
|
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
2011-08-24 20:22:22 +00:00
|
|
|
getArchDefines(Opts, Builder);
|
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
bool hasFeature(StringRef Feature) const override {
|
2012-01-30 06:38:25 +00:00
|
|
|
return Feature == "pnacl";
|
|
|
|
}
|
2015-10-19 04:51:35 +00:00
|
|
|
ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; }
|
2014-03-11 03:39:26 +00:00
|
|
|
BuiltinVaListKind getBuiltinVaListKind() const override {
|
2012-06-16 03:34:49 +00:00
|
|
|
return TargetInfo::PNaClABIBuiltinVaList;
|
2011-08-24 20:22:22 +00:00
|
|
|
}
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<const char *> getGCCRegNames() const override;
|
|
|
|
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
|
2014-03-11 03:39:26 +00:00
|
|
|
bool validateAsmConstraint(const char *&Name,
|
|
|
|
TargetInfo::ConstraintInfo &Info) const override {
|
2011-08-24 20:22:22 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-03-11 03:39:26 +00:00
|
|
|
const char *getClobbers() const override {
|
2011-08-24 20:22:22 +00:00
|
|
|
return "";
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<const char *> PNaClTargetInfo::getGCCRegNames() const {
|
|
|
|
return None;
|
2011-08-24 20:22:22 +00:00
|
|
|
}
|
|
|
|
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<TargetInfo::GCCRegAlias> PNaClTargetInfo::getGCCRegAliases() const {
|
|
|
|
return None;
|
2011-08-24 20:22:22 +00:00
|
|
|
}
|
|
|
|
|
2015-07-08 13:07:31 +00:00
|
|
|
// We attempt to use PNaCl (le32) frontend and Mips32EL backend.
|
|
|
|
class NaClMips32ELTargetInfo : public Mips32ELTargetInfo {
|
|
|
|
public:
|
|
|
|
NaClMips32ELTargetInfo(const llvm::Triple &Triple) :
|
2015-08-11 21:27:39 +00:00
|
|
|
Mips32ELTargetInfo(Triple) {
|
2015-07-08 13:07:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
BuiltinVaListKind getBuiltinVaListKind() const override {
|
|
|
|
return TargetInfo::PNaClABIBuiltinVaList;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2014-09-12 17:52:47 +00:00
|
|
|
class Le64TargetInfo : public TargetInfo {
|
|
|
|
static const Builtin::Info BuiltinInfo[];
|
|
|
|
|
|
|
|
public:
|
|
|
|
Le64TargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
|
|
|
|
BigEndian = false;
|
|
|
|
NoAsmVariants = true;
|
|
|
|
LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
|
|
|
|
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = "e-m:e-v128:32-v16:16-v32:32-v96:32-n8:16:32:64-S128";
|
2014-09-12 17:52:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
|
|
|
DefineStd(Builder, "unix", Opts);
|
|
|
|
defineCPUMacros(Builder, "le64", /*Tuning=*/false);
|
|
|
|
Builder.defineMacro("__ELF__");
|
|
|
|
}
|
2015-10-19 04:51:35 +00:00
|
|
|
ArrayRef<Builtin::Info> getTargetBuiltins() const override {
|
|
|
|
return llvm::makeArrayRef(BuiltinInfo,
|
|
|
|
clang::Le64::LastTSBuiltin - Builtin::FirstTSBuiltin);
|
2014-09-12 17:52:47 +00:00
|
|
|
}
|
|
|
|
BuiltinVaListKind getBuiltinVaListKind() const override {
|
|
|
|
return TargetInfo::PNaClABIBuiltinVaList;
|
|
|
|
}
|
|
|
|
const char *getClobbers() const override { return ""; }
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<const char *> getGCCRegNames() const override {
|
|
|
|
return None;
|
2014-09-12 17:52:47 +00:00
|
|
|
}
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
|
|
|
|
return None;
|
2014-09-12 17:52:47 +00:00
|
|
|
}
|
|
|
|
bool validateAsmConstraint(const char *&Name,
|
|
|
|
TargetInfo::ConstraintInfo &Info) const override {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool hasProtectedVisibility() const override { return false; }
|
|
|
|
};
|
2015-09-03 22:51:53 +00:00
|
|
|
|
|
|
|
class WebAssemblyTargetInfo : public TargetInfo {
|
|
|
|
static const Builtin::Info BuiltinInfo[];
|
|
|
|
|
|
|
|
enum SIMDEnum {
|
|
|
|
NoSIMD,
|
|
|
|
SIMD128,
|
|
|
|
} SIMDLevel;
|
|
|
|
|
|
|
|
public:
|
|
|
|
explicit WebAssemblyTargetInfo(const llvm::Triple &T)
|
|
|
|
: TargetInfo(T), SIMDLevel(NoSIMD) {
|
|
|
|
BigEndian = false;
|
|
|
|
NoAsmVariants = true;
|
|
|
|
SuitableAlign = 128;
|
|
|
|
LargeArrayMinWidth = 128;
|
|
|
|
LargeArrayAlign = 128;
|
|
|
|
SimdDefaultAlign = 128;
|
2015-09-14 21:56:37 +00:00
|
|
|
SigAtomicType = SignedLong;
|
2015-11-10 21:01:46 +00:00
|
|
|
LongDoubleWidth = LongDoubleAlign = 128;
|
|
|
|
LongDoubleFormat = &llvm::APFloat::IEEEquad;
|
2015-09-03 22:51:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
|
|
|
defineCPUMacros(Builder, "wasm", /*Tuning=*/false);
|
|
|
|
if (SIMDLevel >= SIMD128)
|
|
|
|
Builder.defineMacro("__wasm_simd128__");
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2015-10-09 18:39:55 +00:00
|
|
|
bool
|
|
|
|
initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
|
|
|
|
StringRef CPU,
|
|
|
|
const std::vector<std::string> &FeaturesVec) const override {
|
2015-09-03 22:51:53 +00:00
|
|
|
if (CPU == "bleeding-edge")
|
|
|
|
Features["simd128"] = true;
|
|
|
|
return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
|
|
|
|
}
|
2015-09-10 17:07:54 +00:00
|
|
|
bool hasFeature(StringRef Feature) const final {
|
2015-09-03 22:51:53 +00:00
|
|
|
return llvm::StringSwitch<bool>(Feature)
|
|
|
|
.Case("simd128", SIMDLevel >= SIMD128)
|
|
|
|
.Default(false);
|
|
|
|
}
|
|
|
|
bool handleTargetFeatures(std::vector<std::string> &Features,
|
2015-09-10 17:07:54 +00:00
|
|
|
DiagnosticsEngine &Diags) final {
|
2015-09-03 22:51:53 +00:00
|
|
|
for (const auto &Feature : Features) {
|
|
|
|
if (Feature == "+simd128") {
|
|
|
|
SIMDLevel = std::max(SIMDLevel, SIMD128);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (Feature == "-simd128") {
|
|
|
|
SIMDLevel = std::min(SIMDLevel, SIMDEnum(SIMD128 - 1));
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
Diags.Report(diag::err_opt_not_valid_with_opt) << Feature
|
|
|
|
<< "-target-feature";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2015-09-10 17:07:54 +00:00
|
|
|
bool setCPU(const std::string &Name) final {
|
2015-09-03 22:51:53 +00:00
|
|
|
return llvm::StringSwitch<bool>(Name)
|
|
|
|
.Case("mvp", true)
|
|
|
|
.Case("bleeding-edge", true)
|
|
|
|
.Case("generic", true)
|
|
|
|
.Default(false);
|
|
|
|
}
|
2015-10-19 04:51:35 +00:00
|
|
|
ArrayRef<Builtin::Info> getTargetBuiltins() const final {
|
|
|
|
return llvm::makeArrayRef(BuiltinInfo,
|
|
|
|
clang::WebAssembly::LastTSBuiltin - Builtin::FirstTSBuiltin);
|
2015-09-03 22:51:53 +00:00
|
|
|
}
|
2015-09-10 17:07:54 +00:00
|
|
|
BuiltinVaListKind getBuiltinVaListKind() const final {
|
2015-09-03 22:51:53 +00:00
|
|
|
return VoidPtrBuiltinVaList;
|
|
|
|
}
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<const char *> getGCCRegNames() const final {
|
|
|
|
return None;
|
2015-09-03 22:51:53 +00:00
|
|
|
}
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const final {
|
|
|
|
return None;
|
2015-09-03 22:51:53 +00:00
|
|
|
}
|
|
|
|
bool
|
|
|
|
validateAsmConstraint(const char *&Name,
|
2015-09-10 17:07:54 +00:00
|
|
|
TargetInfo::ConstraintInfo &Info) const final {
|
2015-09-03 22:51:53 +00:00
|
|
|
return false;
|
|
|
|
}
|
2015-09-10 17:07:54 +00:00
|
|
|
const char *getClobbers() const final { return ""; }
|
|
|
|
bool isCLZForZeroUndef() const final { return false; }
|
|
|
|
bool hasInt128Type() const final { return true; }
|
2015-09-14 21:49:41 +00:00
|
|
|
IntType getIntTypeByWidth(unsigned BitWidth,
|
|
|
|
bool IsSigned) const final {
|
|
|
|
// WebAssembly prefers long long for explicitly 64-bit integers.
|
|
|
|
return BitWidth == 64 ? (IsSigned ? SignedLongLong : UnsignedLongLong)
|
|
|
|
: TargetInfo::getIntTypeByWidth(BitWidth, IsSigned);
|
|
|
|
}
|
|
|
|
IntType getLeastIntTypeByWidth(unsigned BitWidth,
|
|
|
|
bool IsSigned) const final {
|
|
|
|
// WebAssembly uses long long for int_least64_t and int_fast64_t.
|
|
|
|
return BitWidth == 64
|
|
|
|
? (IsSigned ? SignedLongLong : UnsignedLongLong)
|
|
|
|
: TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned);
|
|
|
|
}
|
2015-09-03 22:51:53 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
const Builtin::Info WebAssemblyTargetInfo::BuiltinInfo[] = {
|
|
|
|
#define BUILTIN(ID, TYPE, ATTRS) \
|
|
|
|
{ #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },
|
|
|
|
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
|
|
|
|
{ #ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr },
|
|
|
|
#include "clang/Basic/BuiltinsWebAssembly.def"
|
|
|
|
};
|
|
|
|
|
|
|
|
class WebAssembly32TargetInfo : public WebAssemblyTargetInfo {
|
|
|
|
public:
|
|
|
|
explicit WebAssembly32TargetInfo(const llvm::Triple &T)
|
|
|
|
: WebAssemblyTargetInfo(T) {
|
2015-09-14 21:56:37 +00:00
|
|
|
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32;
|
2016-01-07 03:20:15 +00:00
|
|
|
DataLayoutString = "e-m:e-p:32:32-i64:64-n32:64-S128";
|
2015-09-03 22:51:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
|
|
|
WebAssemblyTargetInfo::getTargetDefines(Opts, Builder);
|
|
|
|
defineCPUMacros(Builder, "wasm32", /*Tuning=*/false);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class WebAssembly64TargetInfo : public WebAssemblyTargetInfo {
|
|
|
|
public:
|
|
|
|
explicit WebAssembly64TargetInfo(const llvm::Triple &T)
|
|
|
|
: WebAssemblyTargetInfo(T) {
|
|
|
|
LongAlign = LongWidth = 64;
|
|
|
|
PointerAlign = PointerWidth = 64;
|
2015-09-14 21:56:37 +00:00
|
|
|
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
|
2016-01-07 03:20:15 +00:00
|
|
|
DataLayoutString = "e-m:e-p:64:64-i64:64-n32:64-S128";
|
2015-09-03 22:51:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
|
|
|
WebAssemblyTargetInfo::getTargetDefines(Opts, Builder);
|
|
|
|
defineCPUMacros(Builder, "wasm64", /*Tuning=*/false);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2014-09-12 17:52:47 +00:00
|
|
|
const Builtin::Info Le64TargetInfo::BuiltinInfo[] = {
|
|
|
|
#define BUILTIN(ID, TYPE, ATTRS) \
|
2015-08-07 05:14:44 +00:00
|
|
|
{ #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },
|
2014-09-12 17:52:47 +00:00
|
|
|
#include "clang/Basic/BuiltinsLe64.def"
|
|
|
|
};
|
|
|
|
|
2015-09-18 21:26:24 +00:00
|
|
|
static const unsigned SPIRAddrSpaceMap[] = {
|
|
|
|
1, // opencl_global
|
|
|
|
3, // opencl_local
|
|
|
|
2, // opencl_constant
|
|
|
|
4, // opencl_generic
|
|
|
|
0, // cuda_device
|
|
|
|
0, // cuda_constant
|
|
|
|
0 // cuda_shared
|
|
|
|
};
|
|
|
|
class SPIRTargetInfo : public TargetInfo {
|
|
|
|
public:
|
|
|
|
SPIRTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
|
|
|
|
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;
|
|
|
|
UseAddrSpaceMapMangling = true;
|
|
|
|
// Define available target features
|
|
|
|
// These must be defined in sorted order!
|
|
|
|
NoAsmVariants = true;
|
|
|
|
}
|
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
|
|
|
DefineStd(Builder, "SPIR", Opts);
|
|
|
|
}
|
|
|
|
bool hasFeature(StringRef Feature) const override {
|
|
|
|
return Feature == "spir";
|
|
|
|
}
|
2015-01-20 11:20:41 +00:00
|
|
|
|
2015-10-19 04:51:35 +00:00
|
|
|
ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; }
|
2015-09-18 21:26:24 +00:00
|
|
|
const char *getClobbers() const override { return ""; }
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<const char *> getGCCRegNames() const override { return None; }
|
2015-09-18 21:26:24 +00:00
|
|
|
bool validateAsmConstraint(const char *&Name,
|
|
|
|
TargetInfo::ConstraintInfo &info) const override {
|
|
|
|
return true;
|
|
|
|
}
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
|
|
|
|
return None;
|
|
|
|
}
|
2015-09-18 21:26:24 +00:00
|
|
|
BuiltinVaListKind getBuiltinVaListKind() const override {
|
|
|
|
return TargetInfo::VoidPtrBuiltinVaList;
|
|
|
|
}
|
2015-01-20 11:20:41 +00:00
|
|
|
|
2015-09-18 21:26:24 +00:00
|
|
|
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
|
|
|
|
return (CC == CC_SpirFunction || CC == CC_SpirKernel) ? CCCR_OK
|
|
|
|
: CCCR_Warning;
|
|
|
|
}
|
2012-12-11 21:38:14 +00:00
|
|
|
|
2015-09-18 21:26:24 +00:00
|
|
|
CallingConv getDefaultCallingConv(CallingConvMethodType MT) const override {
|
|
|
|
return CC_SpirFunction;
|
|
|
|
}
|
|
|
|
};
|
2012-12-11 21:38:14 +00:00
|
|
|
|
2015-09-18 21:26:24 +00:00
|
|
|
class SPIR32TargetInfo : public SPIRTargetInfo {
|
|
|
|
public:
|
|
|
|
SPIR32TargetInfo(const llvm::Triple &Triple) : SPIRTargetInfo(Triple) {
|
|
|
|
PointerWidth = PointerAlign = 32;
|
|
|
|
SizeType = TargetInfo::UnsignedInt;
|
|
|
|
PtrDiffType = IntPtrType = TargetInfo::SignedInt;
|
|
|
|
DataLayoutString = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-"
|
|
|
|
"v96:128-v192:256-v256:256-v512:512-v1024:1024";
|
|
|
|
}
|
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
|
|
|
DefineStd(Builder, "SPIR32", Opts);
|
|
|
|
}
|
|
|
|
};
|
2012-12-11 21:38:14 +00:00
|
|
|
|
2015-09-18 21:26:24 +00:00
|
|
|
class SPIR64TargetInfo : public SPIRTargetInfo {
|
|
|
|
public:
|
|
|
|
SPIR64TargetInfo(const llvm::Triple &Triple) : SPIRTargetInfo(Triple) {
|
|
|
|
PointerWidth = PointerAlign = 64;
|
|
|
|
SizeType = TargetInfo::UnsignedLong;
|
|
|
|
PtrDiffType = IntPtrType = TargetInfo::SignedLong;
|
|
|
|
DataLayoutString = "e-i64:64-v16:16-v24:32-v32:32-v48:64-"
|
|
|
|
"v96:128-v192:256-v256:256-v512:512-v1024:1024";
|
|
|
|
}
|
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
|
|
|
DefineStd(Builder, "SPIR64", Opts);
|
|
|
|
}
|
|
|
|
};
|
2012-12-11 21:38:14 +00:00
|
|
|
|
2013-08-13 09:43:10 +00:00
|
|
|
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 10:09:30 +00:00
|
|
|
SizeType = UnsignedInt;
|
|
|
|
PtrDiffType = SignedInt;
|
|
|
|
IntPtrType = SignedInt;
|
|
|
|
WCharType = UnsignedChar;
|
|
|
|
WIntType = UnsignedInt;
|
2013-08-13 09:43:10 +00:00
|
|
|
UseZeroLengthBitfieldAlignment = true;
|
2015-08-05 23:48:05 +00:00
|
|
|
DataLayoutString = "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:32"
|
|
|
|
"-f64:32-a:0:32-n32";
|
2013-08-13 09:43:10 +00:00
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override {
|
2013-08-13 09:43:10 +00:00
|
|
|
Builder.defineMacro("__XS1B__");
|
|
|
|
}
|
2015-10-19 04:51:35 +00:00
|
|
|
ArrayRef<Builtin::Info> getTargetBuiltins() const override {
|
|
|
|
return llvm::makeArrayRef(BuiltinInfo,
|
|
|
|
clang::XCore::LastTSBuiltin-Builtin::FirstTSBuiltin);
|
2013-08-13 09:43:10 +00:00
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
BuiltinVaListKind getBuiltinVaListKind() const override {
|
2013-08-13 09:43:10 +00:00
|
|
|
return TargetInfo::VoidPtrBuiltinVaList;
|
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
const char *getClobbers() const override {
|
2013-08-13 09:43:10 +00:00
|
|
|
return "";
|
|
|
|
}
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<const char *> getGCCRegNames() const override {
|
2013-08-13 09:43:10 +00:00
|
|
|
static const char * const GCCRegNames[] = {
|
|
|
|
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
|
|
|
"r8", "r9", "r10", "r11", "cp", "dp", "sp", "lr"
|
|
|
|
};
|
2015-10-19 03:52:27 +00:00
|
|
|
return llvm::makeArrayRef(GCCRegNames);
|
2013-08-13 09:43:10 +00:00
|
|
|
}
|
2015-10-19 03:52:27 +00:00
|
|
|
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
|
|
|
|
return None;
|
2013-08-13 09:43:10 +00:00
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
bool validateAsmConstraint(const char *&Name,
|
|
|
|
TargetInfo::ConstraintInfo &Info) const override {
|
2013-08-13 09:43:10 +00:00
|
|
|
return false;
|
|
|
|
}
|
2014-03-11 03:39:26 +00:00
|
|
|
int getEHDataRegisterNumber(unsigned RegNo) const override {
|
2014-01-27 17:56:25 +00:00
|
|
|
// R0=ExceptionPointerRegister R1=ExceptionSelectorRegister
|
|
|
|
return (RegNo < 2)? RegNo : -1;
|
|
|
|
}
|
2013-08-13 09:43:10 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
const Builtin::Info XCoreTargetInfo::BuiltinInfo[] = {
|
2015-08-07 05:14:44 +00:00
|
|
|
#define BUILTIN(ID, TYPE, ATTRS) \
|
|
|
|
{ #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },
|
|
|
|
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
|
|
|
|
{ #ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr },
|
2013-08-13 09:43:10 +00:00
|
|
|
#include "clang/Basic/BuiltinsXCore.def"
|
|
|
|
};
|
|
|
|
|
2015-03-25 10:38:50 +00:00
|
|
|
// x86_32 Android target
|
|
|
|
class AndroidX86_32TargetInfo : public LinuxTargetInfo<X86_32TargetInfo> {
|
|
|
|
public:
|
|
|
|
AndroidX86_32TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: LinuxTargetInfo<X86_32TargetInfo>(Triple) {
|
|
|
|
SuitableAlign = 32;
|
|
|
|
LongDoubleWidth = 64;
|
|
|
|
LongDoubleFormat = &llvm::APFloat::IEEEdouble;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// x86_64 Android target
|
|
|
|
class AndroidX86_64TargetInfo : public LinuxTargetInfo<X86_64TargetInfo> {
|
|
|
|
public:
|
|
|
|
AndroidX86_64TargetInfo(const llvm::Triple &Triple)
|
|
|
|
: LinuxTargetInfo<X86_64TargetInfo>(Triple) {
|
|
|
|
LongDoubleFormat = &llvm::APFloat::IEEEquad;
|
|
|
|
}
|
2015-07-24 18:12:54 +00:00
|
|
|
|
|
|
|
bool useFloat128ManglingForLongDouble() const override {
|
|
|
|
return true;
|
|
|
|
}
|
2015-03-25 10:38:50 +00:00
|
|
|
};
|
|
|
|
} // end anonymous namespace
|
|
|
|
|
2006-10-14 07:39:34 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Driver code
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2013-06-29 16:37:14 +00:00
|
|
|
static TargetInfo *AllocateTarget(const llvm::Triple &Triple) {
|
2009-08-18 05:47:58 +00:00
|
|
|
llvm::Triple::OSType os = Triple.getOS();
|
2008-05-20 14:21:01 +00:00
|
|
|
|
2009-08-18 05:47:58 +00:00
|
|
|
switch (Triple.getArch()) {
|
|
|
|
default:
|
2014-05-08 06:41:40 +00:00
|
|
|
return nullptr;
|
2008-05-20 14:21:01 +00:00
|
|
|
|
2013-08-13 09:43:10 +00:00
|
|
|
case llvm::Triple::xcore:
|
|
|
|
return new XCoreTargetInfo(Triple);
|
|
|
|
|
2011-12-12 21:14:55 +00:00
|
|
|
case llvm::Triple::hexagon:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new HexagonTargetInfo(Triple);
|
2011-12-12 21:14:55 +00:00
|
|
|
|
2013-01-31 12:13:10 +00:00
|
|
|
case llvm::Triple::aarch64:
|
2014-05-30 14:14:07 +00:00
|
|
|
if (Triple.isOSDarwin())
|
|
|
|
return new DarwinAArch64TargetInfo(Triple);
|
|
|
|
|
2013-01-31 12:13:10 +00:00
|
|
|
switch (os) {
|
2015-10-15 15:07:07 +00:00
|
|
|
case llvm::Triple::CloudABI:
|
|
|
|
return new CloudABITargetInfo<AArch64leTargetInfo>(Triple);
|
2014-11-13 16:55:42 +00:00
|
|
|
case llvm::Triple::FreeBSD:
|
|
|
|
return new FreeBSDTargetInfo<AArch64leTargetInfo>(Triple);
|
2013-01-31 12:13:10 +00:00
|
|
|
case llvm::Triple::Linux:
|
2014-05-24 12:52:07 +00:00
|
|
|
return new LinuxTargetInfo<AArch64leTargetInfo>(Triple);
|
2014-02-25 13:51:00 +00:00
|
|
|
case llvm::Triple::NetBSD:
|
2014-05-24 12:52:07 +00:00
|
|
|
return new NetBSDTargetInfo<AArch64leTargetInfo>(Triple);
|
2014-02-25 13:51:00 +00:00
|
|
|
default:
|
2014-05-24 12:52:07 +00:00
|
|
|
return new AArch64leTargetInfo(Triple);
|
2014-02-25 13:51:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
case llvm::Triple::aarch64_be:
|
|
|
|
switch (os) {
|
2014-11-13 16:55:42 +00:00
|
|
|
case llvm::Triple::FreeBSD:
|
|
|
|
return new FreeBSDTargetInfo<AArch64beTargetInfo>(Triple);
|
2014-02-25 13:51:00 +00:00
|
|
|
case llvm::Triple::Linux:
|
2014-05-24 12:52:07 +00:00
|
|
|
return new LinuxTargetInfo<AArch64beTargetInfo>(Triple);
|
2014-01-13 18:25:15 +00:00
|
|
|
case llvm::Triple::NetBSD:
|
2014-05-24 12:52:07 +00:00
|
|
|
return new NetBSDTargetInfo<AArch64beTargetInfo>(Triple);
|
2013-01-31 12:13:10 +00:00
|
|
|
default:
|
2014-05-24 12:52:07 +00:00
|
|
|
return new AArch64beTargetInfo(Triple);
|
2013-01-31 12:13:10 +00:00
|
|
|
}
|
|
|
|
|
2009-08-18 05:47:58 +00:00
|
|
|
case llvm::Triple::arm:
|
2009-09-11 01:14:50 +00:00
|
|
|
case llvm::Triple::thumb:
|
2014-01-16 08:48:16 +00:00
|
|
|
if (Triple.isOSBinFormatMachO())
|
2013-06-29 16:37:14 +00:00
|
|
|
return new DarwinARMTargetInfo(Triple);
|
2011-04-19 21:43:27 +00:00
|
|
|
|
2009-08-18 05:47:58 +00:00
|
|
|
switch (os) {
|
2010-06-10 00:46:51 +00:00
|
|
|
case llvm::Triple::Linux:
|
2014-03-28 14:40:46 +00:00
|
|
|
return new LinuxTargetInfo<ARMleTargetInfo>(Triple);
|
|
|
|
case llvm::Triple::FreeBSD:
|
|
|
|
return new FreeBSDTargetInfo<ARMleTargetInfo>(Triple);
|
|
|
|
case llvm::Triple::NetBSD:
|
|
|
|
return new NetBSDTargetInfo<ARMleTargetInfo>(Triple);
|
|
|
|
case llvm::Triple::OpenBSD:
|
|
|
|
return new OpenBSDTargetInfo<ARMleTargetInfo>(Triple);
|
|
|
|
case llvm::Triple::Bitrig:
|
|
|
|
return new BitrigTargetInfo<ARMleTargetInfo>(Triple);
|
|
|
|
case llvm::Triple::RTEMS:
|
|
|
|
return new RTEMSTargetInfo<ARMleTargetInfo>(Triple);
|
|
|
|
case llvm::Triple::NaCl:
|
|
|
|
return new NaClTargetInfo<ARMleTargetInfo>(Triple);
|
2014-04-04 20:31:19 +00:00
|
|
|
case llvm::Triple::Win32:
|
|
|
|
switch (Triple.getEnvironment()) {
|
2015-07-15 13:32:23 +00:00
|
|
|
case llvm::Triple::Cygnus:
|
|
|
|
return new CygwinARMTargetInfo(Triple);
|
|
|
|
case llvm::Triple::GNU:
|
|
|
|
return new MinGWARMTargetInfo(Triple);
|
2014-04-04 20:31:19 +00:00
|
|
|
case llvm::Triple::Itanium:
|
|
|
|
return new ItaniumWindowsARMleTargetInfo(Triple);
|
|
|
|
case llvm::Triple::MSVC:
|
2015-07-17 21:26:41 +00:00
|
|
|
default: // Assume MSVC for unknown environments
|
2014-04-04 20:31:19 +00:00
|
|
|
return new MicrosoftARMleTargetInfo(Triple);
|
|
|
|
}
|
2014-03-28 14:40:46 +00:00
|
|
|
default:
|
|
|
|
return new ARMleTargetInfo(Triple);
|
|
|
|
}
|
|
|
|
|
|
|
|
case llvm::Triple::armeb:
|
|
|
|
case llvm::Triple::thumbeb:
|
|
|
|
if (Triple.isOSDarwin())
|
|
|
|
return new DarwinARMTargetInfo(Triple);
|
|
|
|
|
|
|
|
switch (os) {
|
|
|
|
case llvm::Triple::Linux:
|
|
|
|
return new LinuxTargetInfo<ARMbeTargetInfo>(Triple);
|
2009-08-18 05:47:58 +00:00
|
|
|
case llvm::Triple::FreeBSD:
|
2014-03-28 14:40:46 +00:00
|
|
|
return new FreeBSDTargetInfo<ARMbeTargetInfo>(Triple);
|
2011-07-04 21:59:44 +00:00
|
|
|
case llvm::Triple::NetBSD:
|
2014-03-28 14:40:46 +00:00
|
|
|
return new NetBSDTargetInfo<ARMbeTargetInfo>(Triple);
|
2012-08-02 13:45:48 +00:00
|
|
|
case llvm::Triple::OpenBSD:
|
2014-03-28 14:40:46 +00:00
|
|
|
return new OpenBSDTargetInfo<ARMbeTargetInfo>(Triple);
|
2012-08-08 23:57:20 +00:00
|
|
|
case llvm::Triple::Bitrig:
|
2014-03-28 14:40:46 +00:00
|
|
|
return new BitrigTargetInfo<ARMbeTargetInfo>(Triple);
|
2011-07-01 22:41:14 +00:00
|
|
|
case llvm::Triple::RTEMS:
|
2014-03-28 14:40:46 +00:00
|
|
|
return new RTEMSTargetInfo<ARMbeTargetInfo>(Triple);
|
2012-12-04 18:38:10 +00:00
|
|
|
case llvm::Triple::NaCl:
|
2014-03-28 14:40:46 +00:00
|
|
|
return new NaClTargetInfo<ARMbeTargetInfo>(Triple);
|
2009-08-18 05:47:58 +00:00
|
|
|
default:
|
2014-03-28 14:40:46 +00:00
|
|
|
return new ARMbeTargetInfo(Triple);
|
2009-08-18 05:47:58 +00:00
|
|
|
}
|
2008-04-21 18:56:49 +00:00
|
|
|
|
2015-06-10 22:59:13 +00:00
|
|
|
case llvm::Triple::bpfeb:
|
|
|
|
case llvm::Triple::bpfel:
|
|
|
|
return new BPFTargetInfo(Triple);
|
|
|
|
|
2009-08-18 05:47:58 +00:00
|
|
|
case llvm::Triple::msp430:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new MSP430TargetInfo(Triple);
|
2008-05-20 14:21:01 +00:00
|
|
|
|
2009-11-15 10:22:07 +00:00
|
|
|
case llvm::Triple::mips:
|
2011-07-05 18:05:54 +00:00
|
|
|
switch (os) {
|
|
|
|
case llvm::Triple::Linux:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new LinuxTargetInfo<Mips32EBTargetInfo>(Triple);
|
2011-07-05 18:05:54 +00:00
|
|
|
case llvm::Triple::RTEMS:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new RTEMSTargetInfo<Mips32EBTargetInfo>(Triple);
|
2011-07-05 18:05:54 +00:00
|
|
|
case llvm::Triple::FreeBSD:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new FreeBSDTargetInfo<Mips32EBTargetInfo>(Triple);
|
2011-07-05 18:05:54 +00:00
|
|
|
case llvm::Triple::NetBSD:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new NetBSDTargetInfo<Mips32EBTargetInfo>(Triple);
|
2011-07-05 18:05:54 +00:00
|
|
|
default:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new Mips32EBTargetInfo(Triple);
|
2011-07-05 18:05:54 +00:00
|
|
|
}
|
2009-11-15 10:22:07 +00:00
|
|
|
|
|
|
|
case llvm::Triple::mipsel:
|
2011-07-05 18:24:04 +00:00
|
|
|
switch (os) {
|
|
|
|
case llvm::Triple::Linux:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new LinuxTargetInfo<Mips32ELTargetInfo>(Triple);
|
2011-07-05 18:24:04 +00:00
|
|
|
case llvm::Triple::RTEMS:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new RTEMSTargetInfo<Mips32ELTargetInfo>(Triple);
|
2011-07-05 18:24:04 +00:00
|
|
|
case llvm::Triple::FreeBSD:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new FreeBSDTargetInfo<Mips32ELTargetInfo>(Triple);
|
2011-07-05 18:24:04 +00:00
|
|
|
case llvm::Triple::NetBSD:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new NetBSDTargetInfo<Mips32ELTargetInfo>(Triple);
|
2013-09-21 01:27:01 +00:00
|
|
|
case llvm::Triple::NaCl:
|
2015-07-08 13:07:31 +00:00
|
|
|
return new NaClTargetInfo<NaClMips32ELTargetInfo>(Triple);
|
2011-07-05 18:24:04 +00:00
|
|
|
default:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new Mips32ELTargetInfo(Triple);
|
2011-07-05 18:24:04 +00:00
|
|
|
}
|
2009-11-15 10:22:07 +00:00
|
|
|
|
2011-09-20 19:21:49 +00:00
|
|
|
case llvm::Triple::mips64:
|
|
|
|
switch (os) {
|
|
|
|
case llvm::Triple::Linux:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new LinuxTargetInfo<Mips64EBTargetInfo>(Triple);
|
2011-09-20 19:21:49 +00:00
|
|
|
case llvm::Triple::RTEMS:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new RTEMSTargetInfo<Mips64EBTargetInfo>(Triple);
|
2011-09-20 19:21:49 +00:00
|
|
|
case llvm::Triple::FreeBSD:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new FreeBSDTargetInfo<Mips64EBTargetInfo>(Triple);
|
2011-09-20 19:21:49 +00:00
|
|
|
case llvm::Triple::NetBSD:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new NetBSDTargetInfo<Mips64EBTargetInfo>(Triple);
|
2012-08-02 13:45:48 +00:00
|
|
|
case llvm::Triple::OpenBSD:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new OpenBSDTargetInfo<Mips64EBTargetInfo>(Triple);
|
2011-09-20 19:21:49 +00:00
|
|
|
default:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new Mips64EBTargetInfo(Triple);
|
2011-09-20 19:21:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
case llvm::Triple::mips64el:
|
|
|
|
switch (os) {
|
|
|
|
case llvm::Triple::Linux:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new LinuxTargetInfo<Mips64ELTargetInfo>(Triple);
|
2011-09-20 19:21:49 +00:00
|
|
|
case llvm::Triple::RTEMS:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new RTEMSTargetInfo<Mips64ELTargetInfo>(Triple);
|
2011-09-20 19:21:49 +00:00
|
|
|
case llvm::Triple::FreeBSD:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new FreeBSDTargetInfo<Mips64ELTargetInfo>(Triple);
|
2011-09-20 19:21:49 +00:00
|
|
|
case llvm::Triple::NetBSD:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new NetBSDTargetInfo<Mips64ELTargetInfo>(Triple);
|
2012-08-02 13:45:48 +00:00
|
|
|
case llvm::Triple::OpenBSD:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new OpenBSDTargetInfo<Mips64ELTargetInfo>(Triple);
|
2011-09-20 19:21:49 +00:00
|
|
|
default:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new Mips64ELTargetInfo(Triple);
|
2011-09-20 19:21:49 +00:00
|
|
|
}
|
|
|
|
|
2011-08-24 20:22:22 +00:00
|
|
|
case llvm::Triple::le32:
|
|
|
|
switch (os) {
|
2015-05-12 21:18:10 +00:00
|
|
|
case llvm::Triple::NaCl:
|
|
|
|
return new NaClTargetInfo<PNaClTargetInfo>(Triple);
|
|
|
|
default:
|
|
|
|
return nullptr;
|
2011-08-24 20:22:22 +00:00
|
|
|
}
|
|
|
|
|
2014-09-12 17:52:47 +00:00
|
|
|
case llvm::Triple::le64:
|
|
|
|
return new Le64TargetInfo(Triple);
|
|
|
|
|
2009-08-18 05:47:58 +00:00
|
|
|
case llvm::Triple::ppc:
|
2011-04-19 21:43:27 +00:00
|
|
|
if (Triple.isOSDarwin())
|
2013-06-29 16:37:14 +00:00
|
|
|
return new DarwinPPC32TargetInfo(Triple);
|
2011-07-04 21:59:44 +00:00
|
|
|
switch (os) {
|
2011-10-12 09:30:58 +00:00
|
|
|
case llvm::Triple::Linux:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new LinuxTargetInfo<PPC32TargetInfo>(Triple);
|
2011-07-04 21:59:44 +00:00
|
|
|
case llvm::Triple::FreeBSD:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new FreeBSDTargetInfo<PPC32TargetInfo>(Triple);
|
2011-07-04 21:59:44 +00:00
|
|
|
case llvm::Triple::NetBSD:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new NetBSDTargetInfo<PPC32TargetInfo>(Triple);
|
2012-08-02 13:45:48 +00:00
|
|
|
case llvm::Triple::OpenBSD:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new OpenBSDTargetInfo<PPC32TargetInfo>(Triple);
|
2011-07-04 21:59:44 +00:00
|
|
|
case llvm::Triple::RTEMS:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new RTEMSTargetInfo<PPC32TargetInfo>(Triple);
|
2011-07-04 21:59:44 +00:00
|
|
|
default:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new PPC32TargetInfo(Triple);
|
2011-07-04 21:59:44 +00:00
|
|
|
}
|
2009-05-03 13:43:08 +00:00
|
|
|
|
2009-08-18 05:47:58 +00:00
|
|
|
case llvm::Triple::ppc64:
|
2011-04-19 21:43:27 +00:00
|
|
|
if (Triple.isOSDarwin())
|
2013-06-29 16:37:14 +00:00
|
|
|
return new DarwinPPC64TargetInfo(Triple);
|
2011-07-04 21:59:44 +00:00
|
|
|
switch (os) {
|
2011-10-12 09:30:58 +00:00
|
|
|
case llvm::Triple::Linux:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new LinuxTargetInfo<PPC64TargetInfo>(Triple);
|
2011-07-04 21:59:44 +00:00
|
|
|
case llvm::Triple::Lv2:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new PS3PPUTargetInfo<PPC64TargetInfo>(Triple);
|
2011-07-04 21:59:44 +00:00
|
|
|
case llvm::Triple::FreeBSD:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new FreeBSDTargetInfo<PPC64TargetInfo>(Triple);
|
2011-07-04 21:59:44 +00:00
|
|
|
case llvm::Triple::NetBSD:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new NetBSDTargetInfo<PPC64TargetInfo>(Triple);
|
2011-07-04 21:59:44 +00:00
|
|
|
default:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new PPC64TargetInfo(Triple);
|
2011-07-04 21:59:44 +00:00
|
|
|
}
|
2009-07-16 20:09:57 +00:00
|
|
|
|
2013-07-26 01:36:11 +00:00
|
|
|
case llvm::Triple::ppc64le:
|
|
|
|
switch (os) {
|
|
|
|
case llvm::Triple::Linux:
|
|
|
|
return new LinuxTargetInfo<PPC64TargetInfo>(Triple);
|
2015-04-10 20:53:48 +00:00
|
|
|
case llvm::Triple::NetBSD:
|
|
|
|
return new NetBSDTargetInfo<PPC64TargetInfo>(Triple);
|
2013-07-26 01:36:11 +00:00
|
|
|
default:
|
|
|
|
return new PPC64TargetInfo(Triple);
|
|
|
|
}
|
|
|
|
|
2012-05-20 23:28:41 +00:00
|
|
|
case llvm::Triple::nvptx:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new NVPTX32TargetInfo(Triple);
|
2012-05-20 23:28:41 +00:00
|
|
|
case llvm::Triple::nvptx64:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new NVPTX64TargetInfo(Triple);
|
2012-05-20 23:28:41 +00:00
|
|
|
|
2015-01-06 20:34:47 +00:00
|
|
|
case llvm::Triple::amdgcn:
|
2012-10-12 23:32:00 +00:00
|
|
|
case llvm::Triple::r600:
|
2015-06-19 17:54:10 +00:00
|
|
|
return new AMDGPUTargetInfo(Triple);
|
2012-10-12 23:32:00 +00:00
|
|
|
|
2009-08-18 05:47:58 +00:00
|
|
|
case llvm::Triple::sparc:
|
2011-07-04 21:59:44 +00:00
|
|
|
switch (os) {
|
2011-10-12 09:30:58 +00:00
|
|
|
case llvm::Triple::Linux:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new LinuxTargetInfo<SparcV8TargetInfo>(Triple);
|
2011-07-04 21:59:44 +00:00
|
|
|
case llvm::Triple::Solaris:
|
2015-06-04 15:36:29 +00:00
|
|
|
return new SolarisTargetInfo<SparcV8TargetInfo>(Triple);
|
2011-07-04 21:59:44 +00:00
|
|
|
case llvm::Triple::NetBSD:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new NetBSDTargetInfo<SparcV8TargetInfo>(Triple);
|
2012-08-02 13:45:48 +00:00
|
|
|
case llvm::Triple::OpenBSD:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new OpenBSDTargetInfo<SparcV8TargetInfo>(Triple);
|
2011-07-04 21:59:44 +00:00
|
|
|
case llvm::Triple::RTEMS:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new RTEMSTargetInfo<SparcV8TargetInfo>(Triple);
|
2011-07-04 21:59:44 +00:00
|
|
|
default:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new SparcV8TargetInfo(Triple);
|
2011-07-04 21:59:44 +00:00
|
|
|
}
|
2009-08-17 20:08:44 +00:00
|
|
|
|
2015-05-11 15:21:44 +00:00
|
|
|
// The 'sparcel' architecture copies all the above cases except for Solaris.
|
|
|
|
case llvm::Triple::sparcel:
|
|
|
|
switch (os) {
|
|
|
|
case llvm::Triple::Linux:
|
|
|
|
return new LinuxTargetInfo<SparcV8elTargetInfo>(Triple);
|
|
|
|
case llvm::Triple::NetBSD:
|
|
|
|
return new NetBSDTargetInfo<SparcV8elTargetInfo>(Triple);
|
|
|
|
case llvm::Triple::OpenBSD:
|
|
|
|
return new OpenBSDTargetInfo<SparcV8elTargetInfo>(Triple);
|
|
|
|
case llvm::Triple::RTEMS:
|
|
|
|
return new RTEMSTargetInfo<SparcV8elTargetInfo>(Triple);
|
|
|
|
default:
|
|
|
|
return new SparcV8elTargetInfo(Triple);
|
|
|
|
}
|
|
|
|
|
2013-04-16 15:17:49 +00:00
|
|
|
case llvm::Triple::sparcv9:
|
|
|
|
switch (os) {
|
|
|
|
case llvm::Triple::Linux:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new LinuxTargetInfo<SparcV9TargetInfo>(Triple);
|
2013-04-16 15:17:49 +00:00
|
|
|
case llvm::Triple::Solaris:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new SolarisTargetInfo<SparcV9TargetInfo>(Triple);
|
2013-04-16 15:17:49 +00:00
|
|
|
case llvm::Triple::NetBSD:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new NetBSDTargetInfo<SparcV9TargetInfo>(Triple);
|
2013-04-16 15:17:49 +00:00
|
|
|
case llvm::Triple::OpenBSD:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new OpenBSDTargetInfo<SparcV9TargetInfo>(Triple);
|
2013-04-16 15:17:49 +00:00
|
|
|
case llvm::Triple::FreeBSD:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new FreeBSDTargetInfo<SparcV9TargetInfo>(Triple);
|
2013-04-16 15:17:49 +00:00
|
|
|
default:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new SparcV9TargetInfo(Triple);
|
2013-04-16 15:17:49 +00:00
|
|
|
}
|
|
|
|
|
2013-05-06 16:26:41 +00:00
|
|
|
case llvm::Triple::systemz:
|
|
|
|
switch (os) {
|
|
|
|
case llvm::Triple::Linux:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new LinuxTargetInfo<SystemZTargetInfo>(Triple);
|
2013-05-06 16:26:41 +00:00
|
|
|
default:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new SystemZTargetInfo(Triple);
|
2013-05-06 16:26:41 +00:00
|
|
|
}
|
|
|
|
|
2009-08-19 20:47:07 +00:00
|
|
|
case llvm::Triple::tce:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new TCETargetInfo(Triple);
|
2009-08-19 20:47:07 +00:00
|
|
|
|
2009-08-18 05:47:58 +00:00
|
|
|
case llvm::Triple::x86:
|
2011-04-19 21:43:27 +00:00
|
|
|
if (Triple.isOSDarwin())
|
2013-06-29 16:37:14 +00:00
|
|
|
return new DarwinI386TargetInfo(Triple);
|
2011-04-19 21:43:27 +00:00
|
|
|
|
2009-08-18 05:47:58 +00:00
|
|
|
switch (os) {
|
2015-06-13 21:33:49 +00:00
|
|
|
case llvm::Triple::CloudABI:
|
|
|
|
return new CloudABITargetInfo<X86_32TargetInfo>(Triple);
|
2015-03-25 10:38:50 +00:00
|
|
|
case llvm::Triple::Linux: {
|
|
|
|
switch (Triple.getEnvironment()) {
|
|
|
|
default:
|
|
|
|
return new LinuxTargetInfo<X86_32TargetInfo>(Triple);
|
|
|
|
case llvm::Triple::Android:
|
|
|
|
return new AndroidX86_32TargetInfo(Triple);
|
|
|
|
}
|
|
|
|
}
|
2009-08-18 05:47:58 +00:00
|
|
|
case llvm::Triple::DragonFly:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(Triple);
|
2009-08-18 05:47:58 +00:00
|
|
|
case llvm::Triple::NetBSD:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new NetBSDI386TargetInfo(Triple);
|
2009-08-18 05:47:58 +00:00
|
|
|
case llvm::Triple::OpenBSD:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new OpenBSDI386TargetInfo(Triple);
|
2012-08-08 23:57:20 +00:00
|
|
|
case llvm::Triple::Bitrig:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new BitrigI386TargetInfo(Triple);
|
2009-08-18 05:47:58 +00:00
|
|
|
case llvm::Triple::FreeBSD:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new FreeBSDTargetInfo<X86_32TargetInfo>(Triple);
|
2013-09-05 13:47:07 +00:00
|
|
|
case llvm::Triple::KFreeBSD:
|
|
|
|
return new KFreeBSDTargetInfo<X86_32TargetInfo>(Triple);
|
2010-07-07 16:01:42 +00:00
|
|
|
case llvm::Triple::Minix:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new MinixTargetInfo<X86_32TargetInfo>(Triple);
|
2009-08-18 05:47:58 +00:00
|
|
|
case llvm::Triple::Solaris:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new SolarisTargetInfo<X86_32TargetInfo>(Triple);
|
2014-03-27 22:50:18 +00:00
|
|
|
case llvm::Triple::Win32: {
|
|
|
|
switch (Triple.getEnvironment()) {
|
|
|
|
case llvm::Triple::Cygnus:
|
|
|
|
return new CygwinX86_32TargetInfo(Triple);
|
|
|
|
case llvm::Triple::GNU:
|
|
|
|
return new MinGWX86_32TargetInfo(Triple);
|
2014-06-28 23:34:11 +00:00
|
|
|
case llvm::Triple::Itanium:
|
2014-03-27 22:50:18 +00:00
|
|
|
case llvm::Triple::MSVC:
|
2015-07-17 21:26:41 +00:00
|
|
|
default: // Assume MSVC for unknown environments
|
2014-04-04 05:08:53 +00:00
|
|
|
return new MicrosoftX86_32TargetInfo(Triple);
|
2014-03-27 22:50:18 +00:00
|
|
|
}
|
|
|
|
}
|
2010-04-11 19:29:39 +00:00
|
|
|
case llvm::Triple::Haiku:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new HaikuX86_32TargetInfo(Triple);
|
2011-07-01 22:41:14 +00:00
|
|
|
case llvm::Triple::RTEMS:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new RTEMSX86_32TargetInfo(Triple);
|
2012-12-04 18:38:10 +00:00
|
|
|
case llvm::Triple::NaCl:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new NaClTargetInfo<X86_32TargetInfo>(Triple);
|
2015-11-25 09:24:26 +00:00
|
|
|
case llvm::Triple::ELFIAMCU:
|
|
|
|
return new MCUX86_32TargetInfo(Triple);
|
2009-08-18 05:47:58 +00:00
|
|
|
default:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new X86_32TargetInfo(Triple);
|
2009-08-18 05:47:58 +00:00
|
|
|
}
|
2008-05-20 14:21:01 +00:00
|
|
|
|
2009-08-18 05:47:58 +00:00
|
|
|
case llvm::Triple::x86_64:
|
2014-03-27 22:50:18 +00:00
|
|
|
if (Triple.isOSDarwin() || Triple.isOSBinFormatMachO())
|
2013-06-29 16:37:14 +00:00
|
|
|
return new DarwinX86_64TargetInfo(Triple);
|
2011-04-19 21:43:27 +00:00
|
|
|
|
2009-08-18 05:47:58 +00:00
|
|
|
switch (os) {
|
2015-03-11 08:42:46 +00:00
|
|
|
case llvm::Triple::CloudABI:
|
|
|
|
return new CloudABITargetInfo<X86_64TargetInfo>(Triple);
|
2015-03-25 10:38:50 +00:00
|
|
|
case llvm::Triple::Linux: {
|
|
|
|
switch (Triple.getEnvironment()) {
|
|
|
|
default:
|
|
|
|
return new LinuxTargetInfo<X86_64TargetInfo>(Triple);
|
|
|
|
case llvm::Triple::Android:
|
|
|
|
return new AndroidX86_64TargetInfo(Triple);
|
|
|
|
}
|
|
|
|
}
|
2010-01-09 05:41:14 +00:00
|
|
|
case llvm::Triple::DragonFly:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new DragonFlyBSDTargetInfo<X86_64TargetInfo>(Triple);
|
2009-08-18 05:47:58 +00:00
|
|
|
case llvm::Triple::NetBSD:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new NetBSDTargetInfo<X86_64TargetInfo>(Triple);
|
2009-08-18 05:47:58 +00:00
|
|
|
case llvm::Triple::OpenBSD:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new OpenBSDX86_64TargetInfo(Triple);
|
2012-08-08 23:57:20 +00:00
|
|
|
case llvm::Triple::Bitrig:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new BitrigX86_64TargetInfo(Triple);
|
2009-08-18 05:47:58 +00:00
|
|
|
case llvm::Triple::FreeBSD:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new FreeBSDTargetInfo<X86_64TargetInfo>(Triple);
|
2013-09-05 13:47:07 +00:00
|
|
|
case llvm::Triple::KFreeBSD:
|
|
|
|
return new KFreeBSDTargetInfo<X86_64TargetInfo>(Triple);
|
2009-08-18 05:47:58 +00:00
|
|
|
case llvm::Triple::Solaris:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new SolarisTargetInfo<X86_64TargetInfo>(Triple);
|
2014-03-27 22:50:18 +00:00
|
|
|
case llvm::Triple::Win32: {
|
|
|
|
switch (Triple.getEnvironment()) {
|
2015-07-22 17:38:19 +00:00
|
|
|
case llvm::Triple::Cygnus:
|
|
|
|
return new CygwinX86_64TargetInfo(Triple);
|
2014-03-27 22:50:18 +00:00
|
|
|
case llvm::Triple::GNU:
|
|
|
|
return new MinGWX86_64TargetInfo(Triple);
|
|
|
|
case llvm::Triple::MSVC:
|
2015-07-17 21:26:41 +00:00
|
|
|
default: // Assume MSVC for unknown environments
|
2014-04-04 05:08:53 +00:00
|
|
|
return new MicrosoftX86_64TargetInfo(Triple);
|
2014-03-27 22:50:18 +00:00
|
|
|
}
|
|
|
|
}
|
2012-12-04 18:38:10 +00:00
|
|
|
case llvm::Triple::NaCl:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new NaClTargetInfo<X86_64TargetInfo>(Triple);
|
2015-01-27 14:47:44 +00:00
|
|
|
case llvm::Triple::PS4:
|
|
|
|
return new PS4OSTargetInfo<X86_64TargetInfo>(Triple);
|
2009-08-18 05:47:58 +00:00
|
|
|
default:
|
2013-06-29 16:37:14 +00:00
|
|
|
return new X86_64TargetInfo(Triple);
|
2009-08-18 05:47:58 +00:00
|
|
|
}
|
2012-12-11 21:38:14 +00:00
|
|
|
|
2015-05-12 21:18:10 +00:00
|
|
|
case llvm::Triple::spir: {
|
|
|
|
if (Triple.getOS() != llvm::Triple::UnknownOS ||
|
|
|
|
Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
|
|
|
|
return nullptr;
|
|
|
|
return new SPIR32TargetInfo(Triple);
|
|
|
|
}
|
|
|
|
case llvm::Triple::spir64: {
|
|
|
|
if (Triple.getOS() != llvm::Triple::UnknownOS ||
|
|
|
|
Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
|
|
|
|
return nullptr;
|
|
|
|
return new SPIR64TargetInfo(Triple);
|
|
|
|
}
|
2015-09-03 22:51:53 +00:00
|
|
|
case llvm::Triple::wasm32:
|
|
|
|
if (!(Triple == llvm::Triple("wasm32-unknown-unknown")))
|
|
|
|
return nullptr;
|
|
|
|
return new WebAssemblyOSTargetInfo<WebAssembly32TargetInfo>(Triple);
|
|
|
|
case llvm::Triple::wasm64:
|
|
|
|
if (!(Triple == llvm::Triple("wasm64-unknown-unknown")))
|
|
|
|
return nullptr;
|
|
|
|
return new WebAssemblyOSTargetInfo<WebAssembly64TargetInfo>(Triple);
|
2009-08-18 05:47:58 +00:00
|
|
|
}
|
2006-10-14 07:39:34 +00:00
|
|
|
}
|
2009-11-15 06:48:46 +00:00
|
|
|
|
|
|
|
/// CreateTargetInfo - Return the target info object for the specified target
|
2015-08-07 19:07:08 +00:00
|
|
|
/// options.
|
2014-07-06 05:26:44 +00:00
|
|
|
TargetInfo *
|
|
|
|
TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags,
|
|
|
|
const std::shared_ptr<TargetOptions> &Opts) {
|
2012-11-16 04:24:59 +00:00
|
|
|
llvm::Triple Triple(Opts->Triple);
|
2009-11-15 06:48:46 +00:00
|
|
|
|
|
|
|
// Construct the target
|
2014-03-07 20:03:18 +00:00
|
|
|
std::unique_ptr<TargetInfo> Target(AllocateTarget(Triple));
|
2009-11-15 06:48:46 +00:00
|
|
|
if (!Target) {
|
|
|
|
Diags.Report(diag::err_target_unknown_triple) << Triple.str();
|
2014-05-08 06:41:40 +00:00
|
|
|
return nullptr;
|
2009-11-15 06:48:46 +00:00
|
|
|
}
|
2014-07-06 05:26:44 +00:00
|
|
|
Target->TargetOpts = Opts;
|
2009-11-15 06:48:46 +00:00
|
|
|
|
2009-12-18 18:42:37 +00:00
|
|
|
// Set the target CPU if specified.
|
2012-11-16 04:24:59 +00:00
|
|
|
if (!Opts->CPU.empty() && !Target->setCPU(Opts->CPU)) {
|
|
|
|
Diags.Report(diag::err_target_unknown_cpu) << Opts->CPU;
|
2014-05-08 06:41:40 +00:00
|
|
|
return nullptr;
|
2009-12-18 18:42:37 +00:00
|
|
|
}
|
|
|
|
|
2009-11-15 06:48:46 +00:00
|
|
|
// Set the target ABI if specified.
|
2012-11-16 04:24:59 +00:00
|
|
|
if (!Opts->ABI.empty() && !Target->setABI(Opts->ABI)) {
|
|
|
|
Diags.Report(diag::err_target_unknown_abi) << Opts->ABI;
|
2014-05-08 06:41:40 +00:00
|
|
|
return nullptr;
|
2009-11-15 06:48:46 +00:00
|
|
|
}
|
|
|
|
|
2013-08-21 21:59:03 +00:00
|
|
|
// Set the fp math unit.
|
|
|
|
if (!Opts->FPMath.empty() && !Target->setFPMath(Opts->FPMath)) {
|
|
|
|
Diags.Report(diag::err_target_unknown_fpmath) << Opts->FPMath;
|
2014-05-08 06:41:40 +00:00
|
|
|
return nullptr;
|
2013-08-21 21:59:03 +00:00
|
|
|
}
|
|
|
|
|
2009-11-15 06:48:46 +00: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;
|
2015-08-28 22:32:01 +00:00
|
|
|
if (!Target->initFeatureMap(Features, Diags, Opts->CPU,
|
|
|
|
Opts->FeaturesAsWritten))
|
2015-08-25 13:45:24 +00:00
|
|
|
return nullptr;
|
2009-11-15 06:48:46 +00:00
|
|
|
|
|
|
|
// Add the features to the compile options.
|
2012-11-16 04:24:59 +00:00
|
|
|
Opts->Features.clear();
|
2015-08-12 13:38:59 +00:00
|
|
|
for (const auto &F : Features)
|
|
|
|
Opts->Features.push_back((F.getValue() ? "+" : "-") + F.getKey().str());
|
|
|
|
|
2013-10-16 21:26:26 +00:00
|
|
|
if (!Target->handleTargetFeatures(Opts->Features, Diags))
|
2014-05-08 06:41:40 +00:00
|
|
|
return nullptr;
|
2009-11-15 06:48:46 +00:00
|
|
|
|
2014-03-07 19:33:25 +00:00
|
|
|
return Target.release();
|
2009-11-15 06:48:46 +00:00
|
|
|
}
|