blob: b6715bbea1133a8d33e2cdaff582a32d9500ec55 [file] [log] [blame]
Chris Lattner5ba61f02006-10-14 07:39:34 +00001//===--- Targets.cpp - Implement -arch option and targets -----------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner5b12ab82007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Chris Lattner5ba61f02006-10-14 07:39:34 +00007//
8//===----------------------------------------------------------------------===//
9//
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +000010// This file implements construction of a TargetInfo object from a
Ted Kremenek6f6ff372007-12-12 18:05:32 +000011// target triple.
Chris Lattner5ba61f02006-10-14 07:39:34 +000012//
13//===----------------------------------------------------------------------===//
14
Chris Lattner5ba61f02006-10-14 07:39:34 +000015#include "clang/Basic/TargetInfo.h"
Daniel Dunbarb9bbd542009-11-15 06:48:46 +000016#include "clang/Basic/Builtins.h"
17#include "clang/Basic/Diagnostic.h"
Chris Lattnerc7c6dd42008-12-04 22:54:33 +000018#include "clang/Basic/LangOptions.h"
Chandler Carruth26b29a02010-01-20 06:13:02 +000019#include "clang/Basic/MacroBuilder.h"
Daniel Dunbarb9bbd542009-11-15 06:48:46 +000020#include "clang/Basic/TargetBuiltins.h"
21#include "clang/Basic/TargetOptions.h"
Eli Friedman7cef49e2008-05-20 14:27:34 +000022#include "llvm/ADT/APFloat.h"
Daniel Dunbarb9bbd542009-11-15 06:48:46 +000023#include "llvm/ADT/OwningPtr.h"
Daniel Dunbar979586e2009-11-11 09:38:56 +000024#include "llvm/ADT/STLExtras.h"
Daniel Dunbar58bc48c2009-08-19 20:04:03 +000025#include "llvm/ADT/StringRef.h"
Daniel Dunbar979586e2009-11-11 09:38:56 +000026#include "llvm/ADT/StringSwitch.h"
Chris Lattner859c37a2009-08-12 06:24:27 +000027#include "llvm/ADT/Triple.h"
Chris Lattner30ba6742009-08-10 19:03:04 +000028#include "llvm/MC/MCSectionMachO.h"
Dale Johannesen182addf2010-10-29 23:24:33 +000029#include "llvm/Type.h"
Benjamin Kramerdc2f0062010-01-09 18:20:57 +000030#include <algorithm>
Chris Lattner5ba61f02006-10-14 07:39:34 +000031using namespace clang;
32
Chris Lattner5ba61f02006-10-14 07:39:34 +000033//===----------------------------------------------------------------------===//
Chris Lattner1f5ad112006-10-14 18:32:12 +000034// Common code shared among targets.
Chris Lattner5ba61f02006-10-14 07:39:34 +000035//===----------------------------------------------------------------------===//
36
Chris Lattner1e1c0b92009-03-20 16:06:38 +000037/// DefineStd - Define a macro name and standard variants. For example if
38/// MacroName is "unix", then this will define "__unix", "__unix__", and "unix"
39/// when in GNU mode.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +000040static void DefineStd(MacroBuilder &Builder, llvm::StringRef MacroName,
Chris Lattner1e1c0b92009-03-20 16:06:38 +000041 const LangOptions &Opts) {
42 assert(MacroName[0] != '_' && "Identifier should be in the user's namespace");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +000043
Chris Lattner1e1c0b92009-03-20 16:06:38 +000044 // If in GNU mode (e.g. -std=gnu99 but not -std=c99) define the raw identifier
45 // in the user's namespace.
46 if (Opts.GNUMode)
Benjamin Kramer2d6fda32010-01-09 17:55:51 +000047 Builder.defineMacro(MacroName);
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +000048
Chris Lattner1e1c0b92009-03-20 16:06:38 +000049 // Define __unix.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +000050 Builder.defineMacro("__" + MacroName);
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +000051
Chris Lattner1e1c0b92009-03-20 16:06:38 +000052 // Define __unix__.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +000053 Builder.defineMacro("__" + MacroName + "__");
Chris Lattner1e1c0b92009-03-20 16:06:38 +000054}
55
Chris Lattner09d98f52008-10-05 21:50:58 +000056//===----------------------------------------------------------------------===//
57// Defines specific to certain operating systems.
58//===----------------------------------------------------------------------===//
Chris Lattner30ba6742009-08-10 19:03:04 +000059
Torok Edwinb2b37c62009-06-30 17:10:35 +000060namespace {
Douglas Gregorc05d2a12009-07-01 15:12:53 +000061template<typename TgtInfo>
62class OSTargetInfo : public TgtInfo {
Torok Edwinb2b37c62009-06-30 17:10:35 +000063protected:
Daniel Dunbar40165182009-08-24 09:10:05 +000064 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +000065 MacroBuilder &Builder) const=0;
Torok Edwinb2b37c62009-06-30 17:10:35 +000066public:
Douglas Gregorc05d2a12009-07-01 15:12:53 +000067 OSTargetInfo(const std::string& triple) : TgtInfo(triple) {}
Torok Edwinb2b37c62009-06-30 17:10:35 +000068 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +000069 MacroBuilder &Builder) const {
70 TgtInfo::getTargetDefines(Opts, Builder);
71 getOSDefines(Opts, TgtInfo::getTriple(), Builder);
Torok Edwin4e054162009-06-30 17:00:25 +000072 }
Torok Edwinb2b37c62009-06-30 17:10:35 +000073
74};
Chris Lattner859c37a2009-08-12 06:24:27 +000075} // end anonymous namespace
Torok Edwin4e054162009-06-30 17:00:25 +000076
Chris Lattner30ba6742009-08-10 19:03:04 +000077
Daniel Dunbard86666f2010-01-26 01:44:04 +000078static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
Douglas Gregor20b2ebd2011-03-23 00:50:03 +000079 const llvm::Triple &Triple,
80 llvm::StringRef &PlatformName,
81 VersionTuple &PlatformMinVersion) {
Benjamin Kramer2d6fda32010-01-09 17:55:51 +000082 Builder.defineMacro("__APPLE_CC__", "5621");
83 Builder.defineMacro("__APPLE__");
84 Builder.defineMacro("__MACH__");
85 Builder.defineMacro("OBJC_NEW_PROPERTIES");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +000086
John McCall5d36a8c2011-06-16 00:03:19 +000087 if (!Opts.ObjCAutoRefCount) {
John McCall31168b02011-06-15 23:02:42 +000088 // __weak is always defined, for use in blocks and with objc pointers.
89 Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +000090
John McCall31168b02011-06-15 23:02:42 +000091 // Darwin defines __strong even in C mode (just to nothing).
92 if (Opts.getGCMode() != LangOptions::NonGC)
93 Builder.defineMacro("__strong", "__attribute__((objc_gc(strong)))");
94 else
95 Builder.defineMacro("__strong", "");
96
97 // __unsafe_unretained is defined to nothing in non-ARC mode. We even
98 // allow this in C, since one might have block pointers in structs that
99 // are used in pure C code and in Objective-C ARC.
100 Builder.defineMacro("__unsafe_unretained", "");
101
102 // The Objective-C bridged cast keywords are defined to nothing in non-ARC
103 // mode; then they become normal, C-style casts.
104 Builder.defineMacro("__bridge", "");
105 Builder.defineMacro("__bridge_transfer", "");
106 Builder.defineMacro("__bridge_retained", "");
107 }
108
Eli Friedmanfd4b1552009-06-04 23:00:29 +0000109 if (Opts.Static)
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000110 Builder.defineMacro("__STATIC__");
Eli Friedmanfd4b1552009-06-04 23:00:29 +0000111 else
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000112 Builder.defineMacro("__DYNAMIC__");
Daniel Dunbara77eaeb2009-09-03 04:54:28 +0000113
114 if (Opts.POSIXThreads)
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000115 Builder.defineMacro("_REENTRANT");
Daniel Dunbar497ff132009-04-10 19:52:24 +0000116
Daniel Dunbarecf13562011-04-19 21:40:34 +0000117 // Get the platform type and version number from the triple.
Daniel Dunbar497ff132009-04-10 19:52:24 +0000118 unsigned Maj, Min, Rev;
Mike Stump11289f42009-09-09 15:08:12 +0000119
Daniel Dunbard86666f2010-01-26 01:44:04 +0000120 // If no version was given, default to to 10.4.0, for simplifying tests.
Daniel Dunbarecf13562011-04-19 21:40:34 +0000121 if (Triple.getOSName() == "darwin" || Triple.getOSName() == "osx") {
122 PlatformName = "macosx";
Daniel Dunbard86666f2010-01-26 01:44:04 +0000123 Min = Rev = 0;
124 Maj = 8;
Daniel Dunbarecf13562011-04-19 21:40:34 +0000125 } else {
126 // Otherwise, honor all three triple forms ("-darwinNNN[-iphoneos]",
127 // "-osxNNN", and "-iosNNN").
128
129 if (Triple.getOS() == llvm::Triple::Darwin) {
130 // For historical reasons that make little sense, the version passed here
131 // is the "darwin" version, which drops the 10 and offsets by 4.
132 Triple.getOSVersion(Maj, Min, Rev);
133
134 if (Triple.getEnvironmentName() == "iphoneos") {
135 PlatformName = "ios";
136 } else {
Daniel Dunbarecf13562011-04-19 21:40:34 +0000137 PlatformName = "macosx";
138 Rev = Min;
139 Min = Maj - 4;
140 Maj = 10;
141 }
Daniel Dunbarecf13562011-04-19 21:40:34 +0000142 } else {
Daniel Dunbarecf13562011-04-19 21:40:34 +0000143 Triple.getOSVersion(Maj, Min, Rev);
Daniel Dunbarfcd23892011-04-19 23:34:21 +0000144 PlatformName = llvm::Triple::getOSTypeName(Triple.getOS());
Daniel Dunbarecf13562011-04-19 21:40:34 +0000145 }
146 }
Daniel Dunbard86666f2010-01-26 01:44:04 +0000147
148 // Set the appropriate OS version define.
Daniel Dunbarecf13562011-04-19 21:40:34 +0000149 if (PlatformName == "ios") {
Daniel Dunbarbbd48222011-04-21 21:27:33 +0000150 assert(Maj < 10 && Min < 100 && Rev < 100 && "Invalid version!");
Daniel Dunbard86666f2010-01-26 01:44:04 +0000151 char Str[6];
152 Str[0] = '0' + Maj;
153 Str[1] = '0' + (Min / 10);
154 Str[2] = '0' + (Min % 10);
155 Str[3] = '0' + (Rev / 10);
156 Str[4] = '0' + (Rev % 10);
157 Str[5] = '\0';
158 Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", Str);
159 } else {
Daniel Dunbarbbd48222011-04-21 21:27:33 +0000160 // Note that the Driver allows versions which aren't representable in the
161 // define (because we only get a single digit for the minor and micro
162 // revision numbers). So, we limit them to the maximum representable
163 // version.
Daniel Dunbard86666f2010-01-26 01:44:04 +0000164 assert(Triple.getEnvironmentName().empty() && "Invalid environment!");
Daniel Dunbarbbd48222011-04-21 21:27:33 +0000165 assert(Maj < 100 && Min < 100 && Rev < 100 && "Invalid version!");
Daniel Dunbard86666f2010-01-26 01:44:04 +0000166 char Str[5];
167 Str[0] = '0' + (Maj / 10);
168 Str[1] = '0' + (Maj % 10);
Daniel Dunbarbbd48222011-04-21 21:27:33 +0000169 Str[2] = '0' + std::min(Min, 9U);
170 Str[3] = '0' + std::min(Rev, 9U);
Daniel Dunbard86666f2010-01-26 01:44:04 +0000171 Str[4] = '\0';
172 Builder.defineMacro("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", Str);
Daniel Dunbar497ff132009-04-10 19:52:24 +0000173 }
Daniel Dunbarecf13562011-04-19 21:40:34 +0000174
175 PlatformMinVersion = VersionTuple(Maj, Min, Rev);
Eli Friedman3fd920a2008-08-20 02:34:37 +0000176}
Chris Lattner5ba61f02006-10-14 07:39:34 +0000177
Chris Lattner30ba6742009-08-10 19:03:04 +0000178namespace {
Torok Edwinb2b37c62009-06-30 17:10:35 +0000179template<typename Target>
180class DarwinTargetInfo : public OSTargetInfo<Target> {
181protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000182 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000183 MacroBuilder &Builder) const {
Douglas Gregor20b2ebd2011-03-23 00:50:03 +0000184 getDarwinDefines(Builder, Opts, Triple, this->PlatformName,
185 this->PlatformMinVersion);
Torok Edwinb2b37c62009-06-30 17:10:35 +0000186 }
Mike Stump11289f42009-09-09 15:08:12 +0000187
Torok Edwinb2b37c62009-06-30 17:10:35 +0000188public:
189 DarwinTargetInfo(const std::string& triple) :
190 OSTargetInfo<Target>(triple) {
Eric Christopher17c7b892010-06-25 19:04:52 +0000191 this->TLSSupported = llvm::Triple(triple).getDarwinMajorNumber() > 10;
Daniel Dunbar13adc7f2011-02-21 23:12:51 +0000192 this->MCountName = "\01mcount";
Torok Edwinb2b37c62009-06-30 17:10:35 +0000193 }
194
Anders Carlsson0b0a1222010-01-30 18:33:31 +0000195 virtual std::string isValidSectionSpecifier(llvm::StringRef SR) const {
Chris Lattner30ba6742009-08-10 19:03:04 +0000196 // Let MCSectionMachO validate this.
197 llvm::StringRef Segment, Section;
198 unsigned TAA, StubSize;
Daniel Dunbar75942372011-03-19 02:06:21 +0000199 bool HasTAA;
Chris Lattner30ba6742009-08-10 19:03:04 +0000200 return llvm::MCSectionMachO::ParseSectionSpecifier(SR, Segment, Section,
Daniel Dunbar75942372011-03-19 02:06:21 +0000201 TAA, HasTAA, StubSize);
Chris Lattner30ba6742009-08-10 19:03:04 +0000202 }
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000203
Anders Carlsson851318a2010-06-08 22:47:50 +0000204 virtual const char *getStaticInitSectionSpecifier() const {
205 // FIXME: We should return 0 when building kexts.
206 return "__TEXT,__StaticInit,regular,pure_instructions";
207 }
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000208
Torok Edwinb2b37c62009-06-30 17:10:35 +0000209};
210
Chris Lattner30ba6742009-08-10 19:03:04 +0000211
Torok Edwinb2b37c62009-06-30 17:10:35 +0000212// DragonFlyBSD Target
213template<typename Target>
214class DragonFlyBSDTargetInfo : public OSTargetInfo<Target> {
215protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000216 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000217 MacroBuilder &Builder) const {
Torok Edwinb2b37c62009-06-30 17:10:35 +0000218 // DragonFly defines; list based off of gcc output
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000219 Builder.defineMacro("__DragonFly__");
220 Builder.defineMacro("__DragonFly_cc_version", "100001");
221 Builder.defineMacro("__ELF__");
222 Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
223 Builder.defineMacro("__tune_i386__");
224 DefineStd(Builder, "unix", Opts);
Torok Edwinb2b37c62009-06-30 17:10:35 +0000225 }
226public:
Mike Stump11289f42009-09-09 15:08:12 +0000227 DragonFlyBSDTargetInfo(const std::string &triple)
Torok Edwinb2b37c62009-06-30 17:10:35 +0000228 : OSTargetInfo<Target>(triple) {}
229};
230
231// FreeBSD Target
232template<typename Target>
233class FreeBSDTargetInfo : public OSTargetInfo<Target> {
234protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000235 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000236 MacroBuilder &Builder) const {
Torok Edwinb2b37c62009-06-30 17:10:35 +0000237 // FreeBSD defines; list based off of gcc output
238
Daniel Dunbar40165182009-08-24 09:10:05 +0000239 // FIXME: Move version number handling to llvm::Triple.
Benjamin Kramer31a68e72010-01-30 19:55:01 +0000240 llvm::StringRef Release = Triple.getOSName().substr(strlen("freebsd"), 1);
Torok Edwinb2b37c62009-06-30 17:10:35 +0000241
Benjamin Kramer31a68e72010-01-30 19:55:01 +0000242 Builder.defineMacro("__FreeBSD__", Release);
243 Builder.defineMacro("__FreeBSD_cc_version", Release + "00001");
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000244 Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
245 DefineStd(Builder, "unix", Opts);
246 Builder.defineMacro("__ELF__");
Torok Edwinb2b37c62009-06-30 17:10:35 +0000247 }
248public:
Mike Stump11289f42009-09-09 15:08:12 +0000249 FreeBSDTargetInfo(const std::string &triple)
Duncan Sands9cb27e92009-07-08 13:55:08 +0000250 : OSTargetInfo<Target>(triple) {
251 this->UserLabelPrefix = "";
Roman Divacky178e01602011-02-10 16:52:03 +0000252
253 llvm::Triple Triple(triple);
254 switch (Triple.getArch()) {
255 default:
256 case llvm::Triple::x86:
257 case llvm::Triple::x86_64:
258 this->MCountName = ".mcount";
259 break;
260 case llvm::Triple::mips:
261 case llvm::Triple::mipsel:
262 case llvm::Triple::ppc:
263 case llvm::Triple::ppc64:
264 this->MCountName = "_mcount";
265 break;
266 case llvm::Triple::arm:
267 this->MCountName = "__mcount";
268 break;
269 }
270
Duncan Sands9cb27e92009-07-08 13:55:08 +0000271 }
Torok Edwinb2b37c62009-06-30 17:10:35 +0000272};
273
Chris Lattner3e2ee142010-07-07 16:01:42 +0000274// Minix Target
275template<typename Target>
276class MinixTargetInfo : public OSTargetInfo<Target> {
277protected:
278 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
279 MacroBuilder &Builder) const {
280 // Minix defines
281
282 Builder.defineMacro("__minix", "3");
283 Builder.defineMacro("_EM_WSIZE", "4");
284 Builder.defineMacro("_EM_PSIZE", "4");
285 Builder.defineMacro("_EM_SSIZE", "2");
286 Builder.defineMacro("_EM_LSIZE", "4");
287 Builder.defineMacro("_EM_FSIZE", "4");
288 Builder.defineMacro("_EM_DSIZE", "8");
289 DefineStd(Builder, "unix", Opts);
290 }
291public:
292 MinixTargetInfo(const std::string &triple)
293 : OSTargetInfo<Target>(triple) {
294 this->UserLabelPrefix = "";
295 }
296};
297
Torok Edwinb2b37c62009-06-30 17:10:35 +0000298// Linux target
299template<typename Target>
300class LinuxTargetInfo : public OSTargetInfo<Target> {
301protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000302 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000303 MacroBuilder &Builder) const {
Torok Edwinb2b37c62009-06-30 17:10:35 +0000304 // Linux defines; list based off of gcc output
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000305 DefineStd(Builder, "unix", Opts);
306 DefineStd(Builder, "linux", Opts);
307 Builder.defineMacro("__gnu_linux__");
308 Builder.defineMacro("__ELF__");
Daniel Dunbara77eaeb2009-09-03 04:54:28 +0000309 if (Opts.POSIXThreads)
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000310 Builder.defineMacro("_REENTRANT");
Douglas Gregor3ecc6652010-04-21 05:52:38 +0000311 if (Opts.CPlusPlus)
312 Builder.defineMacro("_GNU_SOURCE");
Torok Edwinb2b37c62009-06-30 17:10:35 +0000313 }
314public:
Mike Stump11289f42009-09-09 15:08:12 +0000315 LinuxTargetInfo(const std::string& triple)
Torok Edwinb2b37c62009-06-30 17:10:35 +0000316 : OSTargetInfo<Target>(triple) {
317 this->UserLabelPrefix = "";
Douglas Gregore6d6e512011-01-12 21:19:25 +0000318 this->WIntType = TargetInfo::UnsignedInt;
Torok Edwinb2b37c62009-06-30 17:10:35 +0000319 }
320};
321
Chris Lattnerd1d820ed2009-07-13 20:29:08 +0000322// NetBSD Target
323template<typename Target>
324class NetBSDTargetInfo : public OSTargetInfo<Target> {
325protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000326 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000327 MacroBuilder &Builder) const {
Chris Lattnerd1d820ed2009-07-13 20:29:08 +0000328 // NetBSD defines; list based off of gcc output
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000329 Builder.defineMacro("__NetBSD__");
330 Builder.defineMacro("__unix__");
331 Builder.defineMacro("__ELF__");
Daniel Dunbara77eaeb2009-09-03 04:54:28 +0000332 if (Opts.POSIXThreads)
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000333 Builder.defineMacro("_POSIX_THREADS");
Chris Lattnerd1d820ed2009-07-13 20:29:08 +0000334 }
335public:
Mike Stump11289f42009-09-09 15:08:12 +0000336 NetBSDTargetInfo(const std::string &triple)
Chris Lattnerd1d820ed2009-07-13 20:29:08 +0000337 : OSTargetInfo<Target>(triple) {
338 this->UserLabelPrefix = "";
339 }
340};
341
Torok Edwinb2b37c62009-06-30 17:10:35 +0000342// OpenBSD Target
343template<typename Target>
344class OpenBSDTargetInfo : public OSTargetInfo<Target> {
345protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000346 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000347 MacroBuilder &Builder) const {
Torok Edwinb2b37c62009-06-30 17:10:35 +0000348 // OpenBSD defines; list based off of gcc output
349
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000350 Builder.defineMacro("__OpenBSD__");
351 DefineStd(Builder, "unix", Opts);
352 Builder.defineMacro("__ELF__");
Daniel Dunbara77eaeb2009-09-03 04:54:28 +0000353 if (Opts.POSIXThreads)
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000354 Builder.defineMacro("_POSIX_THREADS");
Torok Edwinb2b37c62009-06-30 17:10:35 +0000355 }
356public:
Mike Stump11289f42009-09-09 15:08:12 +0000357 OpenBSDTargetInfo(const std::string &triple)
Torok Edwinb2b37c62009-06-30 17:10:35 +0000358 : OSTargetInfo<Target>(triple) {}
359};
360
Edward O'Callaghane9a58b12009-11-15 10:22:07 +0000361// PSP Target
362template<typename Target>
363class PSPTargetInfo : public OSTargetInfo<Target> {
364protected:
365 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000366 MacroBuilder &Builder) const {
Edward O'Callaghane9a58b12009-11-15 10:22:07 +0000367 // PSP defines; list based on the output of the pspdev gcc toolchain.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000368 Builder.defineMacro("PSP");
369 Builder.defineMacro("_PSP");
370 Builder.defineMacro("__psp__");
371 Builder.defineMacro("__ELF__");
Edward O'Callaghane9a58b12009-11-15 10:22:07 +0000372 }
373public:
374 PSPTargetInfo(const std::string& triple)
375 : OSTargetInfo<Target>(triple) {
376 this->UserLabelPrefix = "";
377 }
378};
379
John Thompsone467e192009-11-19 17:18:50 +0000380// PS3 PPU Target
381template<typename Target>
382class PS3PPUTargetInfo : public OSTargetInfo<Target> {
383protected:
384 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000385 MacroBuilder &Builder) const {
John Thompsone467e192009-11-19 17:18:50 +0000386 // PS3 PPU defines.
John Thompson957816f2010-03-25 16:18:32 +0000387 Builder.defineMacro("__PPC__");
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000388 Builder.defineMacro("__PPU__");
389 Builder.defineMacro("__CELLOS_LV2__");
390 Builder.defineMacro("__ELF__");
391 Builder.defineMacro("__LP32__");
John Thompson07a61a42010-06-24 22:44:13 +0000392 Builder.defineMacro("_ARCH_PPC64");
393 Builder.defineMacro("__powerpc64__");
John Thompsone467e192009-11-19 17:18:50 +0000394 }
395public:
396 PS3PPUTargetInfo(const std::string& triple)
397 : OSTargetInfo<Target>(triple) {
398 this->UserLabelPrefix = "";
John Thompson6f8dba72009-12-18 14:21:08 +0000399 this->LongWidth = this->LongAlign = this->PointerWidth = this->PointerAlign = 32;
John Thompson07a61a42010-06-24 22:44:13 +0000400 this->IntMaxType = TargetInfo::SignedLongLong;
401 this->UIntMaxType = TargetInfo::UnsignedLongLong;
402 this->Int64Type = TargetInfo::SignedLongLong;
John Thompson6f8dba72009-12-18 14:21:08 +0000403 this->SizeType = TargetInfo::UnsignedInt;
John Thompson07a61a42010-06-24 22:44:13 +0000404 this->DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
405 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";
John Thompsone467e192009-11-19 17:18:50 +0000406 }
407};
408
409// FIXME: Need a real SPU target.
410// PS3 SPU Target
411template<typename Target>
412class PS3SPUTargetInfo : public OSTargetInfo<Target> {
413protected:
414 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000415 MacroBuilder &Builder) const {
John Thompsone467e192009-11-19 17:18:50 +0000416 // PS3 PPU defines.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000417 Builder.defineMacro("__SPU__");
418 Builder.defineMacro("__ELF__");
John Thompsone467e192009-11-19 17:18:50 +0000419 }
420public:
421 PS3SPUTargetInfo(const std::string& triple)
422 : OSTargetInfo<Target>(triple) {
423 this->UserLabelPrefix = "";
424 }
425};
426
Edward O'Callaghan9dda8e982009-10-18 13:33:59 +0000427// AuroraUX target
428template<typename Target>
429class AuroraUXTargetInfo : public OSTargetInfo<Target> {
430protected:
431 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000432 MacroBuilder &Builder) const {
433 DefineStd(Builder, "sun", Opts);
434 DefineStd(Builder, "unix", Opts);
435 Builder.defineMacro("__ELF__");
436 Builder.defineMacro("__svr4__");
437 Builder.defineMacro("__SVR4");
Edward O'Callaghan9dda8e982009-10-18 13:33:59 +0000438 }
439public:
440 AuroraUXTargetInfo(const std::string& triple)
441 : OSTargetInfo<Target>(triple) {
442 this->UserLabelPrefix = "";
443 this->WCharType = this->SignedLong;
444 // FIXME: WIntType should be SignedLong
445 }
446};
447
Torok Edwinb2b37c62009-06-30 17:10:35 +0000448// Solaris target
449template<typename Target>
450class SolarisTargetInfo : public OSTargetInfo<Target> {
451protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000452 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000453 MacroBuilder &Builder) const {
454 DefineStd(Builder, "sun", Opts);
455 DefineStd(Builder, "unix", Opts);
456 Builder.defineMacro("__ELF__");
457 Builder.defineMacro("__svr4__");
458 Builder.defineMacro("__SVR4");
Torok Edwinb2b37c62009-06-30 17:10:35 +0000459 }
460public:
Mike Stump11289f42009-09-09 15:08:12 +0000461 SolarisTargetInfo(const std::string& triple)
Torok Edwinb2b37c62009-06-30 17:10:35 +0000462 : OSTargetInfo<Target>(triple) {
463 this->UserLabelPrefix = "";
464 this->WCharType = this->SignedLong;
465 // FIXME: WIntType should be SignedLong
466 }
467};
Michael J. Spencer4992ca4b2010-10-21 05:21:48 +0000468
469// Windows target
470template<typename Target>
471class WindowsTargetInfo : public OSTargetInfo<Target> {
472protected:
473 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
474 MacroBuilder &Builder) const {
Michael J. Spencer54bf3c32010-10-21 08:22:51 +0000475 Builder.defineMacro("_WIN32");
476 }
477 void getVisualStudioDefines(const LangOptions &Opts,
478 MacroBuilder &Builder) const {
Michael J. Spencer4992ca4b2010-10-21 05:21:48 +0000479 if (Opts.CPlusPlus) {
480 if (Opts.RTTI)
481 Builder.defineMacro("_CPPRTTI");
482
483 if (Opts.Exceptions)
484 Builder.defineMacro("_CPPUNWIND");
485 }
486
487 if (!Opts.CharIsSigned)
488 Builder.defineMacro("_CHAR_UNSIGNED");
489
490 // FIXME: POSIXThreads isn't exactly the option this should be defined for,
491 // but it works for now.
492 if (Opts.POSIXThreads)
493 Builder.defineMacro("_MT");
Michael J. Spencer54bf3c32010-10-21 08:22:51 +0000494
Michael J. Spencer4992ca4b2010-10-21 05:21:48 +0000495 if (Opts.MSCVersion != 0)
496 Builder.defineMacro("_MSC_VER", llvm::Twine(Opts.MSCVersion));
497
498 if (Opts.Microsoft) {
499 Builder.defineMacro("_MSC_EXTENSIONS");
500
501 if (Opts.CPlusPlus0x) {
502 Builder.defineMacro("_RVALUE_REFERENCES_V2_SUPPORTED");
503 Builder.defineMacro("_RVALUE_REFERENCES_SUPPORTED");
504 Builder.defineMacro("_NATIVE_NULLPTR_SUPPORTED");
505 }
506 }
507
508 Builder.defineMacro("_INTEGRAL_MAX_BITS", "64");
Michael J. Spencer4992ca4b2010-10-21 05:21:48 +0000509 }
510
Michael J. Spencer4992ca4b2010-10-21 05:21:48 +0000511public:
512 WindowsTargetInfo(const std::string &triple)
513 : OSTargetInfo<Target>(triple) {}
514};
515
Mike Stump11289f42009-09-09 15:08:12 +0000516} // end anonymous namespace.
Torok Edwinb2b37c62009-06-30 17:10:35 +0000517
Chris Lattner09d98f52008-10-05 21:50:58 +0000518//===----------------------------------------------------------------------===//
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000519// Specific target implementations.
520//===----------------------------------------------------------------------===//
Anders Carlssona7408e72007-10-13 00:45:48 +0000521
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000522namespace {
523// PPC abstract base class
524class PPCTargetInfo : public TargetInfo {
525 static const Builtin::Info BuiltinInfo[];
526 static const char * const GCCRegNames[];
527 static const TargetInfo::GCCRegAlias GCCRegAliases[];
528
529public:
Eli Friedman9ffd4a92009-06-05 07:05:05 +0000530 PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {}
531
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000532 virtual void getTargetBuiltins(const Builtin::Info *&Records,
533 unsigned &NumRecords) const {
Chris Lattner10a5b382007-01-29 05:24:35 +0000534 Records = BuiltinInfo;
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000535 NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner10a5b382007-01-29 05:24:35 +0000536 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000537
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000538 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000539 MacroBuilder &Builder) const;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000540
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000541 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000542 unsigned &NumNames) const;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000543 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000544 unsigned &NumAliases) const;
Anders Carlsson58436352009-02-28 17:11:49 +0000545 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattnerd9725f72009-04-26 07:16:29 +0000546 TargetInfo::ConstraintInfo &Info) const {
Anders Carlsson58436352009-02-28 17:11:49 +0000547 switch (*Name) {
Anders Carlssonf511f642007-11-27 04:11:28 +0000548 default: return false;
549 case 'O': // Zero
John Thompson07a61a42010-06-24 22:44:13 +0000550 break;
Anders Carlssonf511f642007-11-27 04:11:28 +0000551 case 'b': // Base register
552 case 'f': // Floating point register
Chris Lattnerd9725f72009-04-26 07:16:29 +0000553 Info.setAllowsRegister();
John Thompson07a61a42010-06-24 22:44:13 +0000554 break;
555 // FIXME: The following are added to allow parsing.
556 // I just took a guess at what the actions should be.
557 // Also, is more specific checking needed? I.e. specific registers?
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000558 case 'd': // Floating point register (containing 64-bit value)
John Thompson07a61a42010-06-24 22:44:13 +0000559 case 'v': // Altivec vector register
560 Info.setAllowsRegister();
561 break;
562 case 'w':
563 switch (Name[1]) {
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000564 case 'd':// VSX vector register to hold vector double data
565 case 'f':// VSX vector register to hold vector float data
566 case 's':// VSX vector register to hold scalar float data
567 case 'a':// Any VSX register
John Thompson07a61a42010-06-24 22:44:13 +0000568 break;
569 default:
570 return false;
571 }
572 Info.setAllowsRegister();
573 Name++; // Skip over 'w'.
574 break;
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000575 case 'h': // `MQ', `CTR', or `LINK' register
576 case 'q': // `MQ' register
577 case 'c': // `CTR' register
578 case 'l': // `LINK' register
579 case 'x': // `CR' register (condition register) number 0
580 case 'y': // `CR' register (condition register)
581 case 'z': // `XER[CA]' carry bit (part of the XER register)
John Thompson07a61a42010-06-24 22:44:13 +0000582 Info.setAllowsRegister();
583 break;
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000584 case 'I': // Signed 16-bit constant
John Thompson07a61a42010-06-24 22:44:13 +0000585 case 'J': // Unsigned 16-bit constant shifted left 16 bits
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000586 // (use `L' instead for SImode constants)
587 case 'K': // Unsigned 16-bit constant
588 case 'L': // Signed 16-bit constant shifted left 16 bits
589 case 'M': // Constant larger than 31
590 case 'N': // Exact power of 2
591 case 'P': // Constant whose negation is a signed 16-bit constant
John Thompson07a61a42010-06-24 22:44:13 +0000592 case 'G': // Floating point constant that can be loaded into a
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000593 // register with one instruction per word
John Thompson07a61a42010-06-24 22:44:13 +0000594 case 'H': // Integer/Floating point constant that can be loaded
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000595 // into a register using three instructions
John Thompson07a61a42010-06-24 22:44:13 +0000596 break;
597 case 'm': // Memory operand. Note that on PowerPC targets, m can
598 // include addresses that update the base register. It
599 // is therefore only safe to use `m' in an asm statement
600 // if that asm statement accesses the operand exactly once.
601 // The asm statement must also use `%U<opno>' as a
Sebastian Redldd008712010-08-17 22:42:34 +0000602 // placeholder for the "update" flag in the corresponding
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000603 // load or store instruction. For example:
John Thompson07a61a42010-06-24 22:44:13 +0000604 // asm ("st%U0 %1,%0" : "=m" (mem) : "r" (val));
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000605 // is correct but:
John Thompson07a61a42010-06-24 22:44:13 +0000606 // asm ("st %1,%0" : "=m" (mem) : "r" (val));
607 // is not. Use es rather than m if you don't want the base
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000608 // register to be updated.
609 case 'e':
John Thompsonceebdf12010-06-25 00:02:05 +0000610 if (Name[1] != 's')
611 return false;
Sebastian Redldd008712010-08-17 22:42:34 +0000612 // es: A "stable" memory operand; that is, one which does not
John Thompson07a61a42010-06-24 22:44:13 +0000613 // include any automodification of the base register. Unlike
614 // `m', this constraint can be used in asm statements that
615 // might access the operand several times, or that might not
John Thompsonceebdf12010-06-25 00:02:05 +0000616 // access it at all.
John Thompson07a61a42010-06-24 22:44:13 +0000617 Info.setAllowsMemory();
John Thompsonceebdf12010-06-25 00:02:05 +0000618 Name++; // Skip over 'e'.
John Thompson07a61a42010-06-24 22:44:13 +0000619 break;
620 case 'Q': // Memory operand that is an offset from a register (it is
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000621 // usually better to use `m' or `es' in asm statements)
John Thompson07a61a42010-06-24 22:44:13 +0000622 case 'Z': // Memory operand that is an indexed or indirect from a
623 // register (it is usually better to use `m' or `es' in
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000624 // asm statements)
John Thompson07a61a42010-06-24 22:44:13 +0000625 Info.setAllowsMemory();
626 Info.setAllowsRegister();
627 break;
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000628 case 'R': // AIX TOC entry
John Thompson07a61a42010-06-24 22:44:13 +0000629 case 'a': // Address operand that is an indexed or indirect from a
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000630 // register (`p' is preferable for asm statements)
631 case 'S': // Constant suitable as a 64-bit mask operand
632 case 'T': // Constant suitable as a 32-bit mask operand
633 case 'U': // System V Release 4 small data area reference
John Thompson07a61a42010-06-24 22:44:13 +0000634 case 't': // AND masks that can be performed by two rldic{l, r}
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000635 // instructions
636 case 'W': // Vector constant that does not require memory
637 case 'j': // Vector constant that is all zeros.
John Thompson07a61a42010-06-24 22:44:13 +0000638 break;
639 // End FIXME.
Anders Carlssonf511f642007-11-27 04:11:28 +0000640 }
John Thompson07a61a42010-06-24 22:44:13 +0000641 return true;
Anders Carlssonf511f642007-11-27 04:11:28 +0000642 }
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000643 virtual const char *getClobbers() const {
644 return "";
Anders Carlssonf511f642007-11-27 04:11:28 +0000645 }
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000646};
Anders Carlssonf511f642007-11-27 04:11:28 +0000647
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000648const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
Fariborz Jahaniane8473c22010-11-30 17:35:24 +0000649#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES, false },
650#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
651 ALL_LANGUAGES, false },
Chris Lattner5abdec72009-06-14 01:05:48 +0000652#include "clang/Basic/BuiltinsPPC.def"
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000653};
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000654
655
Chris Lattnerecd49032009-03-02 22:27:17 +0000656/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
657/// #defines that are not tied to a specific subtarget.
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000658void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000659 MacroBuilder &Builder) const {
Chris Lattnerecd49032009-03-02 22:27:17 +0000660 // Target identification.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000661 Builder.defineMacro("__ppc__");
662 Builder.defineMacro("_ARCH_PPC");
Chris Lattnerdb5c16b2010-02-16 18:14:57 +0000663 Builder.defineMacro("__powerpc__");
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000664 Builder.defineMacro("__POWERPC__");
Chris Lattnerecd49032009-03-02 22:27:17 +0000665 if (PointerWidth == 64) {
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000666 Builder.defineMacro("_ARCH_PPC64");
667 Builder.defineMacro("_LP64");
668 Builder.defineMacro("__LP64__");
Chris Lattnerdb5c16b2010-02-16 18:14:57 +0000669 Builder.defineMacro("__powerpc64__");
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000670 Builder.defineMacro("__ppc64__");
Chris Lattnerecd49032009-03-02 22:27:17 +0000671 } else {
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000672 Builder.defineMacro("__ppc__");
Chris Lattnerecd49032009-03-02 22:27:17 +0000673 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000674
Chris Lattnerecd49032009-03-02 22:27:17 +0000675 // Target properties.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000676 Builder.defineMacro("_BIG_ENDIAN");
677 Builder.defineMacro("__BIG_ENDIAN__");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000678
Chris Lattnerecd49032009-03-02 22:27:17 +0000679 // Subtarget options.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000680 Builder.defineMacro("__NATURAL_ALIGNMENT__");
681 Builder.defineMacro("__REGISTER_PREFIX__", "");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000682
Chris Lattnerecd49032009-03-02 22:27:17 +0000683 // FIXME: Should be controlled by command line option.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000684 Builder.defineMacro("__LONG_DOUBLE_128__");
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +0000685
John Thompsone467e192009-11-19 17:18:50 +0000686 if (Opts.AltiVec) {
Benjamin Kramer2d6fda32010-01-09 17:55:51 +0000687 Builder.defineMacro("__VEC__", "10206");
688 Builder.defineMacro("__ALTIVEC__");
John Thompsone467e192009-11-19 17:18:50 +0000689 }
Chris Lattnerecd49032009-03-02 22:27:17 +0000690}
691
Chris Lattner17df24e2008-04-21 18:56:49 +0000692
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000693const char * const PPCTargetInfo::GCCRegNames[] = {
Chris Lattnerf7ff53d2009-09-16 05:05:27 +0000694 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
695 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
696 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
697 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
698 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
699 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
700 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
701 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000702 "mq", "lr", "ctr", "ap",
Chris Lattnerf7ff53d2009-09-16 05:05:27 +0000703 "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000704 "xer",
Chris Lattnerf7ff53d2009-09-16 05:05:27 +0000705 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
706 "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
707 "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
708 "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000709 "vrsave", "vscr",
710 "spe_acc", "spefscr",
711 "sfp"
712};
Chris Lattner10a5b382007-01-29 05:24:35 +0000713
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000714void PPCTargetInfo::getGCCRegNames(const char * const *&Names,
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000715 unsigned &NumNames) const {
716 Names = GCCRegNames;
717 NumNames = llvm::array_lengthof(GCCRegNames);
718}
Chris Lattner5ba61f02006-10-14 07:39:34 +0000719
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000720const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
721 // While some of these aliases do map to different registers
722 // they still share the same register name.
Daniel Dunbar1da76c42009-09-17 07:03:19 +0000723 { { "0" }, "r0" },
724 { { "1"}, "r1" },
725 { { "2" }, "r2" },
726 { { "3" }, "r3" },
727 { { "4" }, "r4" },
728 { { "5" }, "r5" },
729 { { "6" }, "r6" },
730 { { "7" }, "r7" },
731 { { "8" }, "r8" },
732 { { "9" }, "r9" },
733 { { "10" }, "r10" },
734 { { "11" }, "r11" },
735 { { "12" }, "r12" },
736 { { "13" }, "r13" },
737 { { "14" }, "r14" },
738 { { "15" }, "r15" },
739 { { "16" }, "r16" },
740 { { "17" }, "r17" },
741 { { "18" }, "r18" },
742 { { "19" }, "r19" },
743 { { "20" }, "r20" },
744 { { "21" }, "r21" },
745 { { "22" }, "r22" },
746 { { "23" }, "r23" },
747 { { "24" }, "r24" },
748 { { "25" }, "r25" },
749 { { "26" }, "r26" },
750 { { "27" }, "r27" },
751 { { "28" }, "r28" },
752 { { "29" }, "r29" },
753 { { "30" }, "r30" },
754 { { "31" }, "r31" },
755 { { "fr0" }, "f0" },
756 { { "fr1" }, "f1" },
757 { { "fr2" }, "f2" },
758 { { "fr3" }, "f3" },
759 { { "fr4" }, "f4" },
760 { { "fr5" }, "f5" },
761 { { "fr6" }, "f6" },
762 { { "fr7" }, "f7" },
763 { { "fr8" }, "f8" },
764 { { "fr9" }, "f9" },
Mike Stumpfaacf012009-09-17 21:15:00 +0000765 { { "fr10" }, "f10" },
Daniel Dunbar1da76c42009-09-17 07:03:19 +0000766 { { "fr11" }, "f11" },
767 { { "fr12" }, "f12" },
768 { { "fr13" }, "f13" },
769 { { "fr14" }, "f14" },
770 { { "fr15" }, "f15" },
771 { { "fr16" }, "f16" },
772 { { "fr17" }, "f17" },
773 { { "fr18" }, "f18" },
774 { { "fr19" }, "f19" },
775 { { "fr20" }, "f20" },
776 { { "fr21" }, "f21" },
777 { { "fr22" }, "f22" },
778 { { "fr23" }, "f23" },
779 { { "fr24" }, "f24" },
780 { { "fr25" }, "f25" },
781 { { "fr26" }, "f26" },
782 { { "fr27" }, "f27" },
783 { { "fr28" }, "f28" },
784 { { "fr29" }, "f29" },
785 { { "fr30" }, "f30" },
786 { { "fr31" }, "f31" },
787 { { "cc" }, "cr0" },
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000788};
789
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000790void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000791 unsigned &NumAliases) const {
792 Aliases = GCCRegAliases;
793 NumAliases = llvm::array_lengthof(GCCRegAliases);
794}
795} // end anonymous namespace.
Chris Lattner02dffbd2006-10-14 07:50:21 +0000796
Chris Lattner5ba61f02006-10-14 07:39:34 +0000797namespace {
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000798class PPC32TargetInfo : public PPCTargetInfo {
Chris Lattner5ba61f02006-10-14 07:39:34 +0000799public:
Chris Lattnerdb5c16b2010-02-16 18:14:57 +0000800 PPC32TargetInfo(const std::string &triple) : PPCTargetInfo(triple) {
Eli Friedman873f65a2008-08-21 00:13:15 +0000801 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
Chris Lattner5c67237f2009-11-07 18:59:41 +0000802 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";
Chris Lattnerdb5c16b2010-02-16 18:14:57 +0000803
804 if (getTriple().getOS() == llvm::Triple::FreeBSD)
Roman Divacky965b0b72011-01-06 08:27:10 +0000805 SizeType = UnsignedInt;
806 }
807
808 virtual const char *getVAListDeclaration() const {
809 // This is the ELF definition, and is overridden by the Darwin sub-target
810 return "typedef struct __va_list_tag {"
811 " unsigned char gpr;"
812 " unsigned char fpr;"
813 " unsigned short reserved;"
814 " void* overflow_arg_area;"
815 " void* reg_save_area;"
816 "} __builtin_va_list[1];";
Eli Friedman873f65a2008-08-21 00:13:15 +0000817 }
Chris Lattner5ba61f02006-10-14 07:39:34 +0000818};
819} // end anonymous namespace.
820
821namespace {
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000822class PPC64TargetInfo : public PPCTargetInfo {
Chris Lattner5ba61f02006-10-14 07:39:34 +0000823public:
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000824 PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
Chris Lattnerba7a6c12008-05-09 06:17:04 +0000825 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedman2857ccb2009-07-01 03:36:11 +0000826 IntMaxType = SignedLong;
827 UIntMaxType = UnsignedLong;
828 Int64Type = SignedLong;
Eli Friedman873f65a2008-08-21 00:13:15 +0000829 DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
Chris Lattner5c67237f2009-11-07 18:59:41 +0000830 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64";
Chris Lattnerba7a6c12008-05-09 06:17:04 +0000831 }
Roman Divacky965b0b72011-01-06 08:27:10 +0000832 virtual const char *getVAListDeclaration() const {
833 return "typedef char* __builtin_va_list;";
834 }
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000835};
836} // end anonymous namespace.
837
Daniel Dunbar0e15c9a2010-05-30 00:07:30 +0000838
839namespace {
Roman Divacky965b0b72011-01-06 08:27:10 +0000840class DarwinPPC32TargetInfo :
841 public DarwinTargetInfo<PPC32TargetInfo> {
Daniel Dunbar0e15c9a2010-05-30 00:07:30 +0000842public:
Roman Divacky965b0b72011-01-06 08:27:10 +0000843 DarwinPPC32TargetInfo(const std::string& triple)
844 : DarwinTargetInfo<PPC32TargetInfo>(triple) {
Daniel Dunbar0e15c9a2010-05-30 00:07:30 +0000845 HasAlignMac68kSupport = true;
Roman Divacky965b0b72011-01-06 08:27:10 +0000846 BoolWidth = BoolAlign = 32; //XXX support -mone-byte-bool?
847 }
848 virtual const char *getVAListDeclaration() const {
849 return "typedef char* __builtin_va_list;";
Daniel Dunbar0e15c9a2010-05-30 00:07:30 +0000850 }
851};
852
853class DarwinPPC64TargetInfo :
854 public DarwinTargetInfo<PPC64TargetInfo> {
855public:
856 DarwinPPC64TargetInfo(const std::string& triple)
857 : DarwinTargetInfo<PPC64TargetInfo>(triple) {
858 HasAlignMac68kSupport = true;
859 }
860};
861} // end anonymous namespace.
862
Chris Lattner5ba61f02006-10-14 07:39:34 +0000863namespace {
Justin Holewinski514cce82011-04-20 19:34:15 +0000864 class PTXTargetInfo : public TargetInfo {
865 static const char * const GCCRegNames[];
866 static const Builtin::Info BuiltinInfo[];
867 public:
868 PTXTargetInfo(const std::string& triple) : TargetInfo(triple) {
869 TLSSupported = false;
870 LongWidth = LongAlign = 64;
871 }
872 virtual void getTargetDefines(const LangOptions &Opts,
873 MacroBuilder &Builder) const {
874 Builder.defineMacro("__PTX__");
875 }
876 virtual void getTargetBuiltins(const Builtin::Info *&Records,
877 unsigned &NumRecords) const {
878 Records = BuiltinInfo;
879 NumRecords = clang::PTX::LastTSBuiltin-Builtin::FirstTSBuiltin;
880 }
881
882 virtual void getGCCRegNames(const char * const *&Names,
883 unsigned &NumNames) const;
884 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
885 unsigned &NumAliases) const {
886 // No aliases.
887 Aliases = 0;
888 NumAliases = 0;
889 }
890 virtual bool validateAsmConstraint(const char *&Name,
891 TargetInfo::ConstraintInfo &info) const {
892 // FIXME: implement
893 return true;
894 }
895 virtual const char *getClobbers() const {
896 // FIXME: Is this really right?
897 return "";
898 }
899 virtual const char *getVAListDeclaration() const {
900 // FIXME: implement
901 return "typedef char* __builtin_va_list;";
902 }
903 };
904
905 const Builtin::Info PTXTargetInfo::BuiltinInfo[] = {
906#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES, false },
907#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
908 ALL_LANGUAGES, false },
909#include "clang/Basic/BuiltinsPTX.def"
910 };
911
912 const char * const PTXTargetInfo::GCCRegNames[] = {
913 "r0"
914 };
915
916 void PTXTargetInfo::getGCCRegNames(const char * const *&Names,
917 unsigned &NumNames) const {
918 Names = GCCRegNames;
919 NumNames = llvm::array_lengthof(GCCRegNames);
920 }
921
922
923 class PTX32TargetInfo : public PTXTargetInfo {
924 public:
925 PTX32TargetInfo(const std::string& triple) : PTXTargetInfo(triple) {
926 PointerWidth = PointerAlign = 32;
927 SizeType = PtrDiffType = IntPtrType = TargetInfo::UnsignedInt;
928 DescriptionString
929 = "e-p:32:32-i64:64:64-f64:64:64-n1:8:16:32:64";
930 }
931 };
932
933 class PTX64TargetInfo : public PTXTargetInfo {
934 public:
935 PTX64TargetInfo(const std::string& triple) : PTXTargetInfo(triple) {
936 PointerWidth = PointerAlign = 64;
937 SizeType = PtrDiffType = IntPtrType = TargetInfo::UnsignedLongLong;
938 DescriptionString
939 = "e-p:64:64-i64:64:64-f64:64:64-n1:8:16:32:64";
940 }
941 };
942}
943
944namespace {
Chris Lattner5178f562010-03-06 21:21:27 +0000945// MBlaze abstract base class
946class MBlazeTargetInfo : public TargetInfo {
947 static const char * const GCCRegNames[];
948 static const TargetInfo::GCCRegAlias GCCRegAliases[];
949
950public:
951 MBlazeTargetInfo(const std::string& triple) : TargetInfo(triple) {
Wesley Peck69bf1282010-12-12 20:56:47 +0000952 DescriptionString = "E-p:32:32:32-i8:8:8-i16:16:16";
Chris Lattner5178f562010-03-06 21:21:27 +0000953 }
954
955 virtual void getTargetBuiltins(const Builtin::Info *&Records,
956 unsigned &NumRecords) const {
957 // FIXME: Implement.
958 Records = 0;
959 NumRecords = 0;
960 }
961
962 virtual void getTargetDefines(const LangOptions &Opts,
963 MacroBuilder &Builder) const;
964
965 virtual const char *getVAListDeclaration() const {
966 return "typedef char* __builtin_va_list;";
967 }
968 virtual const char *getTargetPrefix() const {
969 return "mblaze";
970 }
971 virtual void getGCCRegNames(const char * const *&Names,
972 unsigned &NumNames) const;
973 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
974 unsigned &NumAliases) const;
975 virtual bool validateAsmConstraint(const char *&Name,
976 TargetInfo::ConstraintInfo &Info) const {
977 switch (*Name) {
978 default: return false;
979 case 'O': // Zero
980 return true;
981 case 'b': // Base register
982 case 'f': // Floating point register
983 Info.setAllowsRegister();
984 return true;
985 }
986 }
987 virtual const char *getClobbers() const {
988 return "";
989 }
990};
991
992/// MBlazeTargetInfo::getTargetDefines - Return a set of the MBlaze-specific
993/// #defines that are not tied to a specific subtarget.
994void MBlazeTargetInfo::getTargetDefines(const LangOptions &Opts,
995 MacroBuilder &Builder) const {
996 // Target identification.
997 Builder.defineMacro("__microblaze__");
998 Builder.defineMacro("_ARCH_MICROBLAZE");
999 Builder.defineMacro("__MICROBLAZE__");
1000
1001 // Target properties.
1002 Builder.defineMacro("_BIG_ENDIAN");
1003 Builder.defineMacro("__BIG_ENDIAN__");
1004
1005 // Subtarget options.
1006 Builder.defineMacro("__REGISTER_PREFIX__", "");
1007}
1008
1009
1010const char * const MBlazeTargetInfo::GCCRegNames[] = {
1011 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1012 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
1013 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
1014 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
1015 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
1016 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
1017 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
1018 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
1019 "hi", "lo", "accum","rmsr", "$fcc1","$fcc2","$fcc3","$fcc4",
1020 "$fcc5","$fcc6","$fcc7","$ap", "$rap", "$frp"
1021};
1022
1023void MBlazeTargetInfo::getGCCRegNames(const char * const *&Names,
1024 unsigned &NumNames) const {
1025 Names = GCCRegNames;
1026 NumNames = llvm::array_lengthof(GCCRegNames);
1027}
1028
1029const TargetInfo::GCCRegAlias MBlazeTargetInfo::GCCRegAliases[] = {
1030 { {"f0"}, "r0" },
1031 { {"f1"}, "r1" },
1032 { {"f2"}, "r2" },
1033 { {"f3"}, "r3" },
1034 { {"f4"}, "r4" },
1035 { {"f5"}, "r5" },
1036 { {"f6"}, "r6" },
1037 { {"f7"}, "r7" },
1038 { {"f8"}, "r8" },
1039 { {"f9"}, "r9" },
1040 { {"f10"}, "r10" },
1041 { {"f11"}, "r11" },
1042 { {"f12"}, "r12" },
1043 { {"f13"}, "r13" },
1044 { {"f14"}, "r14" },
1045 { {"f15"}, "r15" },
1046 { {"f16"}, "r16" },
1047 { {"f17"}, "r17" },
1048 { {"f18"}, "r18" },
1049 { {"f19"}, "r19" },
1050 { {"f20"}, "r20" },
1051 { {"f21"}, "r21" },
1052 { {"f22"}, "r22" },
1053 { {"f23"}, "r23" },
1054 { {"f24"}, "r24" },
1055 { {"f25"}, "r25" },
1056 { {"f26"}, "r26" },
1057 { {"f27"}, "r27" },
1058 { {"f28"}, "r28" },
1059 { {"f29"}, "r29" },
1060 { {"f30"}, "r30" },
1061 { {"f31"}, "r31" },
1062};
1063
1064void MBlazeTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
1065 unsigned &NumAliases) const {
1066 Aliases = GCCRegAliases;
1067 NumAliases = llvm::array_lengthof(GCCRegAliases);
1068}
1069} // end anonymous namespace.
1070
1071namespace {
Eli Friedman3fd920a2008-08-20 02:34:37 +00001072// Namespace for x86 abstract base class
1073const Builtin::Info BuiltinInfo[] = {
Fariborz Jahaniane8473c22010-11-30 17:35:24 +00001074#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES, false },
1075#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
1076 ALL_LANGUAGES, false },
Chris Lattner5abdec72009-06-14 01:05:48 +00001077#include "clang/Basic/BuiltinsX86.def"
Eli Friedman3fd920a2008-08-20 02:34:37 +00001078};
Eli Friedmanb5366062008-05-20 14:21:01 +00001079
Nuno Lopescfca1f02009-12-23 17:49:57 +00001080static const char* const GCCRegNames[] = {
Eli Friedman3fd920a2008-08-20 02:34:37 +00001081 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
1082 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
1083 "argp", "flags", "fspr", "dirflag", "frame",
1084 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
1085 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
1086 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
1087 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
1088};
1089
1090const TargetInfo::GCCRegAlias GCCRegAliases[] = {
1091 { { "al", "ah", "eax", "rax" }, "ax" },
1092 { { "bl", "bh", "ebx", "rbx" }, "bx" },
1093 { { "cl", "ch", "ecx", "rcx" }, "cx" },
1094 { { "dl", "dh", "edx", "rdx" }, "dx" },
1095 { { "esi", "rsi" }, "si" },
1096 { { "edi", "rdi" }, "di" },
1097 { { "esp", "rsp" }, "sp" },
1098 { { "ebp", "rbp" }, "bp" },
1099};
1100
1101// X86 target abstract base class; x86-32 and x86-64 are very close, so
1102// most of the implementation can be shared.
1103class X86TargetInfo : public TargetInfo {
Chris Lattner96e43572009-03-02 22:40:39 +00001104 enum X86SSEEnum {
1105 NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42
1106 } SSELevel;
Anders Carlssone437c682010-01-27 03:47:49 +00001107 enum AMD3DNowEnum {
1108 NoAMD3DNow, AMD3DNow, AMD3DNowAthlon
1109 } AMD3DNowLevel;
1110
Eric Christophere1ddaf92010-04-02 23:50:19 +00001111 bool HasAES;
Bruno Cardoso Lopesd81ef1c2010-08-04 22:29:13 +00001112 bool HasAVX;
1113
Eli Friedman3fd920a2008-08-20 02:34:37 +00001114public:
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001115 X86TargetInfo(const std::string& triple)
Eric Christophere1ddaf92010-04-02 23:50:19 +00001116 : TargetInfo(triple), SSELevel(NoMMXSSE), AMD3DNowLevel(NoAMD3DNow),
Bruno Cardoso Lopesd81ef1c2010-08-04 22:29:13 +00001117 HasAES(false), HasAVX(false) {
Eli Friedman3fd920a2008-08-20 02:34:37 +00001118 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
Chris Lattner1f5ad112006-10-14 18:32:12 +00001119 }
Chris Lattner10a5b382007-01-29 05:24:35 +00001120 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1121 unsigned &NumRecords) const {
Eli Friedman3fd920a2008-08-20 02:34:37 +00001122 Records = BuiltinInfo;
1123 NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner10a5b382007-01-29 05:24:35 +00001124 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001125 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedman3fd920a2008-08-20 02:34:37 +00001126 unsigned &NumNames) const {
1127 Names = GCCRegNames;
1128 NumNames = llvm::array_lengthof(GCCRegNames);
Anders Carlsson5fa3f342007-11-24 23:38:12 +00001129 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001130 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Anders Carlsson5fa3f342007-11-24 23:38:12 +00001131 unsigned &NumAliases) const {
Eli Friedman3fd920a2008-08-20 02:34:37 +00001132 Aliases = GCCRegAliases;
1133 NumAliases = llvm::array_lengthof(GCCRegAliases);
Anders Carlssona7408e72007-10-13 00:45:48 +00001134 }
Anders Carlsson58436352009-02-28 17:11:49 +00001135 virtual bool validateAsmConstraint(const char *&Name,
Eli Friedman3fd920a2008-08-20 02:34:37 +00001136 TargetInfo::ConstraintInfo &info) const;
Stuart Hastings7fdc6702011-06-07 23:45:05 +00001137 virtual std::string convertConstraint(const char *&Constraint) const;
Anders Carlssonf511f642007-11-27 04:11:28 +00001138 virtual const char *getClobbers() const {
Eli Friedman3fd920a2008-08-20 02:34:37 +00001139 return "~{dirflag},~{fpsr},~{flags}";
1140 }
Chris Lattner4ba73aa02009-03-20 15:52:06 +00001141 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001142 MacroBuilder &Builder) const;
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001143 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
1144 const std::string &Name,
1145 bool Enabled) const;
Mike Stump11289f42009-09-09 15:08:12 +00001146 virtual void getDefaultFeatures(const std::string &CPU,
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001147 llvm::StringMap<bool> &Features) const;
Daniel Dunbar7b245ed2009-12-19 03:30:57 +00001148 virtual void HandleTargetFeatures(std::vector<std::string> &Features);
Chris Lattner5ba61f02006-10-14 07:39:34 +00001149};
Chris Lattnerc25d8a72009-03-02 22:20:04 +00001150
Mike Stump11289f42009-09-09 15:08:12 +00001151void X86TargetInfo::getDefaultFeatures(const std::string &CPU,
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001152 llvm::StringMap<bool> &Features) const {
Daniel Dunbar4dbaaa62009-05-06 03:16:41 +00001153 // FIXME: This should not be here.
1154 Features["3dnow"] = false;
1155 Features["3dnowa"] = false;
1156 Features["mmx"] = false;
1157 Features["sse"] = false;
1158 Features["sse2"] = false;
1159 Features["sse3"] = false;
1160 Features["ssse3"] = false;
1161 Features["sse41"] = false;
1162 Features["sse42"] = false;
Eric Christophere1ddaf92010-04-02 23:50:19 +00001163 Features["aes"] = false;
Bruno Cardoso Lopesd81ef1c2010-08-04 22:29:13 +00001164 Features["avx"] = false;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001165
Daniel Dunbar4dbaaa62009-05-06 03:16:41 +00001166 // LLVM does not currently recognize this.
1167 // Features["sse4a"] = false;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001168
Daniel Dunbar4dbaaa62009-05-06 03:16:41 +00001169 // FIXME: This *really* should not be here.
1170
1171 // X86_64 always has SSE2.
1172 if (PointerWidth == 64)
1173 Features["sse2"] = Features["sse"] = Features["mmx"] = true;
1174
Daniel Dunbarf9d90272009-05-06 21:56:32 +00001175 if (CPU == "generic" || CPU == "i386" || CPU == "i486" || CPU == "i586" ||
1176 CPU == "pentium" || CPU == "i686" || CPU == "pentiumpro")
1177 ;
1178 else if (CPU == "pentium-mmx" || CPU == "pentium2")
1179 setFeatureEnabled(Features, "mmx", true);
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001180 else if (CPU == "pentium3")
Daniel Dunbarf9d90272009-05-06 21:56:32 +00001181 setFeatureEnabled(Features, "sse", true);
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001182 else if (CPU == "pentium-m" || CPU == "pentium4" || CPU == "x86-64")
Daniel Dunbarf9d90272009-05-06 21:56:32 +00001183 setFeatureEnabled(Features, "sse2", true);
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001184 else if (CPU == "yonah" || CPU == "prescott" || CPU == "nocona")
Daniel Dunbarf9d90272009-05-06 21:56:32 +00001185 setFeatureEnabled(Features, "sse3", true);
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001186 else if (CPU == "core2")
Daniel Dunbarf9d90272009-05-06 21:56:32 +00001187 setFeatureEnabled(Features, "ssse3", true);
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001188 else if (CPU == "penryn") {
1189 setFeatureEnabled(Features, "sse4", true);
1190 Features["sse42"] = false;
1191 } else if (CPU == "atom")
Daniel Dunbarf9d90272009-05-06 21:56:32 +00001192 setFeatureEnabled(Features, "sse3", true);
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001193 else if (CPU == "corei7") {
Daniel Dunbarf9d90272009-05-06 21:56:32 +00001194 setFeatureEnabled(Features, "sse4", true);
Eric Christophere1ddaf92010-04-02 23:50:19 +00001195 setFeatureEnabled(Features, "aes", true);
Benjamin Kramer85e16642011-05-20 15:11:23 +00001196 } else if (CPU == "corei7-avx") {
Roman Divacky27ec14f2011-04-05 20:32:44 +00001197 setFeatureEnabled(Features, "sse4", true);
1198 setFeatureEnabled(Features, "aes", true);
1199// setFeatureEnabled(Features, "avx", true);
1200 } else if (CPU == "k6" || CPU == "winchip-c6")
Daniel Dunbarf9d90272009-05-06 21:56:32 +00001201 setFeatureEnabled(Features, "mmx", true);
Mike Stump11289f42009-09-09 15:08:12 +00001202 else if (CPU == "k6-2" || CPU == "k6-3" || CPU == "athlon" ||
Daniel Dunbarf9d90272009-05-06 21:56:32 +00001203 CPU == "athlon-tbird" || CPU == "winchip2" || CPU == "c3") {
1204 setFeatureEnabled(Features, "mmx", true);
1205 setFeatureEnabled(Features, "3dnow", true);
1206 } else if (CPU == "athlon-4" || CPU == "athlon-xp" || CPU == "athlon-mp") {
1207 setFeatureEnabled(Features, "sse", true);
1208 setFeatureEnabled(Features, "3dnowa", true);
1209 } else if (CPU == "k8" || CPU == "opteron" || CPU == "athlon64" ||
1210 CPU == "athlon-fx") {
Mike Stump11289f42009-09-09 15:08:12 +00001211 setFeatureEnabled(Features, "sse2", true);
Daniel Dunbarf9d90272009-05-06 21:56:32 +00001212 setFeatureEnabled(Features, "3dnowa", true);
Roman Divackydacbfe42010-12-29 13:28:29 +00001213 } else if (CPU == "k8-sse3") {
1214 setFeatureEnabled(Features, "sse3", true);
1215 setFeatureEnabled(Features, "3dnowa", true);
Daniel Dunbarf9d90272009-05-06 21:56:32 +00001216 } else if (CPU == "c3-2")
1217 setFeatureEnabled(Features, "sse", true);
Daniel Dunbar4dbaaa62009-05-06 03:16:41 +00001218}
1219
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001220bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
Mike Stump11289f42009-09-09 15:08:12 +00001221 const std::string &Name,
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001222 bool Enabled) const {
Eric Christopher399ffa52010-03-04 02:26:37 +00001223 // FIXME: This *really* should not be here. We need some way of translating
1224 // options into llvm subtarget features.
1225 if (!Features.count(Name) &&
1226 (Name != "sse4" && Name != "sse4.2" && Name != "sse4.1"))
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001227 return false;
1228
1229 if (Enabled) {
1230 if (Name == "mmx")
1231 Features["mmx"] = true;
1232 else if (Name == "sse")
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001233 Features["mmx"] = Features["sse"] = true;
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001234 else if (Name == "sse2")
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001235 Features["mmx"] = Features["sse"] = Features["sse2"] = true;
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001236 else if (Name == "sse3")
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001237 Features["mmx"] = Features["sse"] = Features["sse2"] =
1238 Features["sse3"] = true;
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001239 else if (Name == "ssse3")
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001240 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001241 Features["ssse3"] = true;
Eric Christopher399ffa52010-03-04 02:26:37 +00001242 else if (Name == "sse4" || Name == "sse4.2")
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001243 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001244 Features["ssse3"] = Features["sse41"] = Features["sse42"] = true;
Eric Christopher399ffa52010-03-04 02:26:37 +00001245 else if (Name == "sse4.1")
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001246 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Eric Christopher399ffa52010-03-04 02:26:37 +00001247 Features["ssse3"] = Features["sse41"] = true;
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001248 else if (Name == "3dnow")
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001249 Features["3dnowa"] = true;
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001250 else if (Name == "3dnowa")
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001251 Features["3dnow"] = Features["3dnowa"] = true;
Eric Christophere1ddaf92010-04-02 23:50:19 +00001252 else if (Name == "aes")
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001253 Features["aes"] = true;
Bruno Cardoso Lopesd81ef1c2010-08-04 22:29:13 +00001254 else if (Name == "avx")
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001255 Features["avx"] = true;
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001256 } else {
1257 if (Name == "mmx")
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001258 Features["mmx"] = Features["3dnow"] = Features["3dnowa"] =
1259 Features["sse"] = Features["sse2"] = Features["sse3"] =
1260 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001261 else if (Name == "sse")
Mike Stump11289f42009-09-09 15:08:12 +00001262 Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001263 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001264 else if (Name == "sse2")
Mike Stump11289f42009-09-09 15:08:12 +00001265 Features["sse2"] = Features["sse3"] = Features["ssse3"] =
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001266 Features["sse41"] = Features["sse42"] = false;
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001267 else if (Name == "sse3")
Mike Stump11289f42009-09-09 15:08:12 +00001268 Features["sse3"] = Features["ssse3"] = Features["sse41"] =
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001269 Features["sse42"] = false;
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001270 else if (Name == "ssse3")
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001271 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
Michael J. Spencera9e41172011-04-17 19:22:03 +00001272 else if (Name == "sse4" || Name == "sse4.1")
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001273 Features["sse41"] = Features["sse42"] = false;
Eric Christophercfeceff2010-03-04 02:31:44 +00001274 else if (Name == "sse4.2")
Daniel Dunbarea1f0982011-05-03 15:34:01 +00001275 Features["sse42"] = false;
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001276 else if (Name == "3dnow")
1277 Features["3dnow"] = Features["3dnowa"] = false;
1278 else if (Name == "3dnowa")
1279 Features["3dnowa"] = false;
Eric Christophere1ddaf92010-04-02 23:50:19 +00001280 else if (Name == "aes")
1281 Features["aes"] = false;
Bruno Cardoso Lopesd81ef1c2010-08-04 22:29:13 +00001282 else if (Name == "avx")
1283 Features["avx"] = false;
Daniel Dunbarbb36aed2009-05-06 21:07:50 +00001284 }
1285
1286 return true;
1287}
1288
Daniel Dunbar4dbaaa62009-05-06 03:16:41 +00001289/// HandleTargetOptions - Perform initialization based on the user
1290/// configured set of features.
Daniel Dunbar7b245ed2009-12-19 03:30:57 +00001291void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) {
Daniel Dunbar979586e2009-11-11 09:38:56 +00001292 // Remember the maximum enabled sselevel.
1293 for (unsigned i = 0, e = Features.size(); i !=e; ++i) {
1294 // Ignore disabled features.
1295 if (Features[i][0] == '-')
1296 continue;
1297
Eric Christophere1ddaf92010-04-02 23:50:19 +00001298 if (Features[i].substr(1) == "aes") {
1299 HasAES = true;
1300 continue;
1301 }
1302
Bruno Cardoso Lopesd81ef1c2010-08-04 22:29:13 +00001303 // FIXME: Not sure yet how to treat AVX in regard to SSE levels.
1304 // For now let it be enabled together with other SSE levels.
1305 if (Features[i].substr(1) == "avx") {
1306 HasAVX = true;
1307 continue;
1308 }
1309
Daniel Dunbar979586e2009-11-11 09:38:56 +00001310 assert(Features[i][0] == '+' && "Invalid target feature!");
1311 X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Features[i].substr(1))
1312 .Case("sse42", SSE42)
1313 .Case("sse41", SSE41)
1314 .Case("ssse3", SSSE3)
Nuno Lopes4cbc8bd2010-03-12 10:20:09 +00001315 .Case("sse3", SSE3)
Daniel Dunbar979586e2009-11-11 09:38:56 +00001316 .Case("sse2", SSE2)
1317 .Case("sse", SSE1)
1318 .Case("mmx", MMX)
1319 .Default(NoMMXSSE);
1320 SSELevel = std::max(SSELevel, Level);
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +00001321
1322 AMD3DNowEnum ThreeDNowLevel =
Anders Carlssone437c682010-01-27 03:47:49 +00001323 llvm::StringSwitch<AMD3DNowEnum>(Features[i].substr(1))
1324 .Case("3dnowa", AMD3DNowAthlon)
1325 .Case("3dnow", AMD3DNow)
1326 .Default(NoAMD3DNow);
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +00001327
Anders Carlssone437c682010-01-27 03:47:49 +00001328 AMD3DNowLevel = std::max(AMD3DNowLevel, ThreeDNowLevel);
Daniel Dunbar979586e2009-11-11 09:38:56 +00001329 }
Chris Lattnerc25d8a72009-03-02 22:20:04 +00001330}
Chris Lattnerecd49032009-03-02 22:27:17 +00001331
1332/// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines
1333/// that are not tied to a specific subtarget.
Chris Lattner4ba73aa02009-03-20 15:52:06 +00001334void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001335 MacroBuilder &Builder) const {
Chris Lattnerecd49032009-03-02 22:27:17 +00001336 // Target identification.
1337 if (PointerWidth == 64) {
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001338 Builder.defineMacro("_LP64");
1339 Builder.defineMacro("__LP64__");
1340 Builder.defineMacro("__amd64__");
1341 Builder.defineMacro("__amd64");
1342 Builder.defineMacro("__x86_64");
1343 Builder.defineMacro("__x86_64__");
Chris Lattnerecd49032009-03-02 22:27:17 +00001344 } else {
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001345 DefineStd(Builder, "i386", Opts);
Chris Lattnerecd49032009-03-02 22:27:17 +00001346 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001347
Eric Christophere1ddaf92010-04-02 23:50:19 +00001348 if (HasAES)
1349 Builder.defineMacro("__AES__");
1350
Bruno Cardoso Lopesd81ef1c2010-08-04 22:29:13 +00001351 if (HasAVX)
1352 Builder.defineMacro("__AVX__");
1353
Chris Lattnerecd49032009-03-02 22:27:17 +00001354 // Target properties.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001355 Builder.defineMacro("__LITTLE_ENDIAN__");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001356
Chris Lattnerecd49032009-03-02 22:27:17 +00001357 // Subtarget options.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001358 Builder.defineMacro("__nocona");
1359 Builder.defineMacro("__nocona__");
1360 Builder.defineMacro("__tune_nocona__");
1361 Builder.defineMacro("__REGISTER_PREFIX__", "");
Chris Lattner96e43572009-03-02 22:40:39 +00001362
Chris Lattner6df41af2009-04-19 17:32:33 +00001363 // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline
1364 // functions in glibc header files that use FP Stack inline asm which the
1365 // backend can't deal with (PR879).
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001366 Builder.defineMacro("__NO_MATH_INLINES");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001367
Chris Lattner96e43572009-03-02 22:40:39 +00001368 // Each case falls through to the previous one here.
1369 switch (SSELevel) {
1370 case SSE42:
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001371 Builder.defineMacro("__SSE4_2__");
Chris Lattner96e43572009-03-02 22:40:39 +00001372 case SSE41:
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001373 Builder.defineMacro("__SSE4_1__");
Chris Lattner96e43572009-03-02 22:40:39 +00001374 case SSSE3:
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001375 Builder.defineMacro("__SSSE3__");
Chris Lattner96e43572009-03-02 22:40:39 +00001376 case SSE3:
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001377 Builder.defineMacro("__SSE3__");
Chris Lattner96e43572009-03-02 22:40:39 +00001378 case SSE2:
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001379 Builder.defineMacro("__SSE2__");
1380 Builder.defineMacro("__SSE2_MATH__"); // -mfp-math=sse always implied.
Chris Lattner96e43572009-03-02 22:40:39 +00001381 case SSE1:
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001382 Builder.defineMacro("__SSE__");
1383 Builder.defineMacro("__SSE_MATH__"); // -mfp-math=sse always implied.
Chris Lattner96e43572009-03-02 22:40:39 +00001384 case MMX:
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001385 Builder.defineMacro("__MMX__");
Chris Lattner96e43572009-03-02 22:40:39 +00001386 case NoMMXSSE:
1387 break;
1388 }
Michael J. Spencerfeb799c2010-10-18 07:10:59 +00001389
Michael J. Spencer4992ca4b2010-10-21 05:21:48 +00001390 if (Opts.Microsoft && PointerWidth == 32) {
Michael J. Spencer4992ca4b2010-10-21 05:21:48 +00001391 switch (SSELevel) {
Michael J. Spencer54bf3c32010-10-21 08:22:51 +00001392 case SSE42:
1393 case SSE41:
1394 case SSSE3:
1395 case SSE3:
Michael J. Spencer4992ca4b2010-10-21 05:21:48 +00001396 case SSE2:
1397 Builder.defineMacro("_M_IX86_FP", llvm::Twine(2));
1398 break;
1399 case SSE1:
1400 Builder.defineMacro("_M_IX86_FP", llvm::Twine(1));
1401 break;
1402 default:
1403 Builder.defineMacro("_M_IX86_FP", llvm::Twine(0));
1404 }
1405 }
1406
Anders Carlssone437c682010-01-27 03:47:49 +00001407 // Each case falls through to the previous one here.
1408 switch (AMD3DNowLevel) {
1409 case AMD3DNowAthlon:
1410 Builder.defineMacro("__3dNOW_A__");
1411 case AMD3DNow:
1412 Builder.defineMacro("__3dNOW__");
1413 case NoAMD3DNow:
1414 break;
1415 }
Chris Lattnerecd49032009-03-02 22:27:17 +00001416}
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001417
1418
Eli Friedman3fd920a2008-08-20 02:34:37 +00001419bool
Anders Carlsson58436352009-02-28 17:11:49 +00001420X86TargetInfo::validateAsmConstraint(const char *&Name,
Chris Lattnerd9725f72009-04-26 07:16:29 +00001421 TargetInfo::ConstraintInfo &Info) const {
Anders Carlsson58436352009-02-28 17:11:49 +00001422 switch (*Name) {
Eli Friedman3fd920a2008-08-20 02:34:37 +00001423 default: return false;
Dale Johannesen46742a42010-08-24 22:33:12 +00001424 case 'Y': // first letter of a pair:
1425 switch (*(Name+1)) {
1426 default: return false;
1427 case '0': // First SSE register.
1428 case 't': // Any SSE register, when SSE2 is enabled.
1429 case 'i': // Any SSE register, when SSE2 and inter-unit moves enabled.
1430 case 'm': // any MMX register, when inter-unit moves enabled.
1431 break; // falls through to setAllowsRegister.
1432 }
Eli Friedman3fd920a2008-08-20 02:34:37 +00001433 case 'a': // eax.
1434 case 'b': // ebx.
1435 case 'c': // ecx.
1436 case 'd': // edx.
1437 case 'S': // esi.
1438 case 'D': // edi.
1439 case 'A': // edx:eax.
Dale Johannesen46742a42010-08-24 22:33:12 +00001440 case 'f': // any x87 floating point stack register.
Eli Friedman3fd920a2008-08-20 02:34:37 +00001441 case 't': // top of floating point stack.
1442 case 'u': // second from top of floating point stack.
1443 case 'q': // Any register accessible as [r]l: a, b, c, and d.
Anders Carlsson83661ac2008-10-06 00:41:45 +00001444 case 'y': // Any MMX register.
Anders Carlsson5f7ee682008-10-06 19:17:39 +00001445 case 'x': // Any SSE register.
Eli Friedman3fd920a2008-08-20 02:34:37 +00001446 case 'Q': // Any register accessible as [r]h: a, b, c, and d.
Dale Johannesen46742a42010-08-24 22:33:12 +00001447 case 'R': // "Legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
1448 case 'l': // "Index" registers: any general register that can be used as an
1449 // index in a base+index memory access.
1450 Info.setAllowsRegister();
1451 return true;
1452 case 'C': // SSE floating point constant.
1453 case 'G': // x87 floating point constant.
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001454 case 'e': // 32-bit signed integer constant for use with zero-extending
Anders Carlssona0b89212009-01-24 18:03:09 +00001455 // x86_64 instructions.
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001456 case 'Z': // 32-bit unsigned integer constant for use with zero-extending
Anders Carlssona0b89212009-01-24 18:03:09 +00001457 // x86_64 instructions.
Eli Friedman3fd920a2008-08-20 02:34:37 +00001458 return true;
1459 }
Dale Johannesen46742a42010-08-24 22:33:12 +00001460 return false;
Eli Friedman3fd920a2008-08-20 02:34:37 +00001461}
1462
Dale Johannesen7d3dfc02010-10-29 23:12:32 +00001463
Eli Friedman3fd920a2008-08-20 02:34:37 +00001464std::string
Stuart Hastings7fdc6702011-06-07 23:45:05 +00001465X86TargetInfo::convertConstraint(const char *&Constraint) const {
1466 switch (*Constraint) {
Eli Friedman3fd920a2008-08-20 02:34:37 +00001467 case 'a': return std::string("{ax}");
1468 case 'b': return std::string("{bx}");
1469 case 'c': return std::string("{cx}");
1470 case 'd': return std::string("{dx}");
1471 case 'S': return std::string("{si}");
1472 case 'D': return std::string("{di}");
Dale Johannesen70f564e2010-10-22 21:07:10 +00001473 case 'p': // address
1474 return std::string("im");
Eli Friedman3fd920a2008-08-20 02:34:37 +00001475 case 't': // top of floating point stack.
1476 return std::string("{st}");
1477 case 'u': // second from top of floating point stack.
1478 return std::string("{st(1)}"); // second from top of floating point stack.
1479 default:
Stuart Hastings7fdc6702011-06-07 23:45:05 +00001480 return std::string(1, *Constraint);
Eli Friedman3fd920a2008-08-20 02:34:37 +00001481 }
1482}
Eli Friedman3fd920a2008-08-20 02:34:37 +00001483} // end anonymous namespace
Chris Lattner5ba61f02006-10-14 07:39:34 +00001484
1485namespace {
Eli Friedman3fd920a2008-08-20 02:34:37 +00001486// X86-32 generic target
1487class X86_32TargetInfo : public X86TargetInfo {
Chris Lattner5ba61f02006-10-14 07:39:34 +00001488public:
Eli Friedman3fd920a2008-08-20 02:34:37 +00001489 X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
1490 DoubleAlign = LongLongAlign = 32;
1491 LongDoubleWidth = 96;
1492 LongDoubleAlign = 32;
Eli Friedman873f65a2008-08-21 00:13:15 +00001493 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1494 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
Chris Lattner5c67237f2009-11-07 18:59:41 +00001495 "a0:0:64-f80:32:32-n8:16:32";
Eli Friedman32ca82a2009-03-29 20:31:09 +00001496 SizeType = UnsignedInt;
1497 PtrDiffType = SignedInt;
1498 IntPtrType = SignedInt;
Anton Korobeynikov6953ef22009-04-03 23:38:25 +00001499 RegParmMax = 3;
Daniel Dunbar6f2e8392010-07-14 23:39:36 +00001500
1501 // Use fpret for all types.
1502 RealTypeUsesObjCFPRet = ((1 << TargetInfo::Float) |
1503 (1 << TargetInfo::Double) |
1504 (1 << TargetInfo::LongDouble));
Eli Friedman3fd920a2008-08-20 02:34:37 +00001505 }
1506 virtual const char *getVAListDeclaration() const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001507 return "typedef char* __builtin_va_list;";
Eli Friedman3fd920a2008-08-20 02:34:37 +00001508 }
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +00001509
Chris Lattnerd545ad12009-09-23 06:06:36 +00001510 int getEHDataRegisterNumber(unsigned RegNo) const {
1511 if (RegNo == 0) return 0;
1512 if (RegNo == 1) return 2;
1513 return -1;
1514 }
Eli Friedman3fd920a2008-08-20 02:34:37 +00001515};
1516} // end anonymous namespace
1517
1518namespace {
Eli Friedmane3aa4542009-07-05 18:47:56 +00001519class OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> {
1520public:
1521 OpenBSDI386TargetInfo(const std::string& triple) :
1522 OpenBSDTargetInfo<X86_32TargetInfo>(triple) {
1523 SizeType = UnsignedLong;
1524 IntPtrType = SignedLong;
Eli Friedman245f2292009-07-05 22:31:18 +00001525 PtrDiffType = SignedLong;
Eli Friedmane3aa4542009-07-05 18:47:56 +00001526 }
1527};
1528} // end anonymous namespace
1529
1530namespace {
Torok Edwinb2b37c62009-06-30 17:10:35 +00001531class DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> {
Eli Friedman3fd920a2008-08-20 02:34:37 +00001532public:
Torok Edwinb2b37c62009-06-30 17:10:35 +00001533 DarwinI386TargetInfo(const std::string& triple) :
1534 DarwinTargetInfo<X86_32TargetInfo>(triple) {
Eli Friedman3fd920a2008-08-20 02:34:37 +00001535 LongDoubleWidth = 128;
1536 LongDoubleAlign = 128;
Eli Friedman32ca82a2009-03-29 20:31:09 +00001537 SizeType = UnsignedLong;
1538 IntPtrType = SignedLong;
Eli Friedman873f65a2008-08-21 00:13:15 +00001539 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1540 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
Chris Lattner5c67237f2009-11-07 18:59:41 +00001541 "a0:0:64-f80:128:128-n8:16:32";
Daniel Dunbarbd606522010-05-27 00:35:16 +00001542 HasAlignMac68kSupport = true;
Torok Edwin4e054162009-06-30 17:00:25 +00001543 }
1544
Eli Friedman3fd920a2008-08-20 02:34:37 +00001545};
Daniel Dunbar10de9e62009-06-29 20:52:51 +00001546} // end anonymous namespace
1547
1548namespace {
Eli Friedmanc968a6a2008-08-21 01:40:19 +00001549// x86-32 Windows target
Michael J. Spencer4992ca4b2010-10-21 05:21:48 +00001550class WindowsX86_32TargetInfo : public WindowsTargetInfo<X86_32TargetInfo> {
Eli Friedmanc968a6a2008-08-21 01:40:19 +00001551public:
1552 WindowsX86_32TargetInfo(const std::string& triple)
Michael J. Spencer4992ca4b2010-10-21 05:21:48 +00001553 : WindowsTargetInfo<X86_32TargetInfo>(triple) {
Eli Friedmand88c8a12009-04-19 21:38:35 +00001554 TLSSupported = false;
Chris Lattner46be2e12009-06-24 17:12:15 +00001555 WCharType = UnsignedShort;
Eli Friedmanebb9e4d2009-06-08 21:16:17 +00001556 DoubleAlign = LongLongAlign = 64;
1557 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
Anton Korobeynikovd7e4a092009-12-19 02:05:07 +00001558 "i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-"
1559 "v128:128:128-a0:0:64-f80:32:32-n8:16:32";
Eli Friedmanc968a6a2008-08-21 01:40:19 +00001560 }
Michael J. Spencer54bf3c32010-10-21 08:22:51 +00001561 virtual void getTargetDefines(const LangOptions &Opts,
1562 MacroBuilder &Builder) const {
1563 WindowsTargetInfo<X86_32TargetInfo>::getTargetDefines(Opts, Builder);
1564 }
1565};
1566} // end anonymous namespace
1567
1568namespace {
1569
1570// x86-32 Windows Visual Studio target
1571class VisualStudioWindowsX86_32TargetInfo : public WindowsX86_32TargetInfo {
1572public:
1573 VisualStudioWindowsX86_32TargetInfo(const std::string& triple)
1574 : WindowsX86_32TargetInfo(triple) {
Eli Friedman015d6282011-03-22 21:25:11 +00001575 LongDoubleWidth = LongDoubleAlign = 64;
Michael J. Spencer54bf3c32010-10-21 08:22:51 +00001576 LongDoubleFormat = &llvm::APFloat::IEEEdouble;
1577 }
1578 virtual void getTargetDefines(const LangOptions &Opts,
1579 MacroBuilder &Builder) const {
1580 WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
1581 WindowsX86_32TargetInfo::getVisualStudioDefines(Opts, Builder);
1582 // The value of the following reflects processor type.
1583 // 300=386, 400=486, 500=Pentium, 600=Blend (default)
1584 // We lost the original triple, so we use the default.
1585 Builder.defineMacro("_M_IX86", "600");
1586 }
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001587};
1588} // end anonymous namespace
1589
1590namespace {
1591// x86-32 MinGW target
1592class MinGWX86_32TargetInfo : public WindowsX86_32TargetInfo {
1593public:
1594 MinGWX86_32TargetInfo(const std::string& triple)
1595 : WindowsX86_32TargetInfo(triple) {
1596 }
1597 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001598 MacroBuilder &Builder) const {
1599 WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
Michael J. Spencer54bf3c32010-10-21 08:22:51 +00001600 DefineStd(Builder, "WIN32", Opts);
1601 DefineStd(Builder, "WINNT", Opts);
1602 Builder.defineMacro("_X86_");
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001603 Builder.defineMacro("__MSVCRT__");
1604 Builder.defineMacro("__MINGW32__");
NAKAMURA Takumib2beb012011-03-15 02:32:50 +00001605
1606 // mingw32-gcc provides __declspec(a) as alias of __attribute__((a)).
1607 // In contrast, clang-cc1 provides __declspec(a) with -fms-extensions.
1608 if (Opts.Microsoft)
1609 // Provide "as-is" __declspec.
1610 Builder.defineMacro("__declspec", "__declspec");
1611 else
1612 // Provide alias of __attribute__ like mingw32-gcc.
1613 Builder.defineMacro("__declspec(a)", "__attribute__((a))");
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001614 }
1615};
1616} // end anonymous namespace
1617
1618namespace {
1619// x86-32 Cygwin target
1620class CygwinX86_32TargetInfo : public X86_32TargetInfo {
1621public:
1622 CygwinX86_32TargetInfo(const std::string& triple)
1623 : X86_32TargetInfo(triple) {
1624 TLSSupported = false;
1625 WCharType = UnsignedShort;
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001626 DoubleAlign = LongLongAlign = 64;
1627 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1628 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
Chris Lattner5c67237f2009-11-07 18:59:41 +00001629 "a0:0:64-f80:32:32-n8:16:32";
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001630 }
1631 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001632 MacroBuilder &Builder) const {
1633 X86_32TargetInfo::getTargetDefines(Opts, Builder);
1634 Builder.defineMacro("__CYGWIN__");
1635 Builder.defineMacro("__CYGWIN32__");
1636 DefineStd(Builder, "unix", Opts);
Douglas Gregor3ecc6652010-04-21 05:52:38 +00001637 if (Opts.CPlusPlus)
1638 Builder.defineMacro("_GNU_SOURCE");
Eli Friedmanaa27a872009-06-08 06:11:14 +00001639 }
Eli Friedmanc968a6a2008-08-21 01:40:19 +00001640};
1641} // end anonymous namespace
1642
1643namespace {
Chris Lattnerb986aba2010-04-11 19:29:39 +00001644// x86-32 Haiku target
1645class HaikuX86_32TargetInfo : public X86_32TargetInfo {
1646public:
1647 HaikuX86_32TargetInfo(const std::string& triple)
1648 : X86_32TargetInfo(triple) {
1649 SizeType = UnsignedLong;
Chris Lattner8b290212010-04-22 17:48:00 +00001650 IntPtrType = SignedLong;
1651 PtrDiffType = SignedLong;
Rafael Espindolac55be6d2010-11-09 16:41:02 +00001652 this->UserLabelPrefix = "";
Eli Friedman04831922010-08-22 01:00:03 +00001653 }
Chris Lattnerb986aba2010-04-11 19:29:39 +00001654 virtual void getTargetDefines(const LangOptions &Opts,
1655 MacroBuilder &Builder) const {
1656 X86_32TargetInfo::getTargetDefines(Opts, Builder);
1657 Builder.defineMacro("__INTEL__");
1658 Builder.defineMacro("__HAIKU__");
1659 }
1660};
1661} // end anonymous namespace
1662
1663namespace {
Eli Friedman3fd920a2008-08-20 02:34:37 +00001664// x86-64 generic target
1665class X86_64TargetInfo : public X86TargetInfo {
1666public:
Chris Lattner4ba73aa02009-03-20 15:52:06 +00001667 X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) {
Chris Lattnerba7a6c12008-05-09 06:17:04 +00001668 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedmanb5366062008-05-20 14:21:01 +00001669 LongDoubleWidth = 128;
1670 LongDoubleAlign = 128;
Rafael Espindolae971b9a2010-06-04 23:15:27 +00001671 LargeArrayMinWidth = 128;
1672 LargeArrayAlign = 128;
Chris Lattnerd0a79b22009-02-05 07:32:46 +00001673 IntMaxType = SignedLong;
1674 UIntMaxType = UnsignedLong;
Eli Friedman2857ccb2009-07-01 03:36:11 +00001675 Int64Type = SignedLong;
Anton Korobeynikov6953ef22009-04-03 23:38:25 +00001676 RegParmMax = 6;
Chris Lattnerd0a79b22009-02-05 07:32:46 +00001677
Eli Friedman873f65a2008-08-21 00:13:15 +00001678 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1679 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
Chris Lattner5c67237f2009-11-07 18:59:41 +00001680 "a0:0:64-s0:64:64-f80:128:128-n8:16:32:64";
Daniel Dunbar6f2e8392010-07-14 23:39:36 +00001681
1682 // Use fpret only for long double.
1683 RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble);
Chris Lattner10a5b382007-01-29 05:24:35 +00001684 }
Anders Carlssona7408e72007-10-13 00:45:48 +00001685 virtual const char *getVAListDeclaration() const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001686 return "typedef struct __va_list_tag {"
1687 " unsigned gp_offset;"
1688 " unsigned fp_offset;"
1689 " void* overflow_arg_area;"
1690 " void* reg_save_area;"
John McCall61d82582010-05-28 18:25:28 +00001691 "} __va_list_tag;"
Eli Friedmanfb36b022009-07-03 00:45:06 +00001692 "typedef __va_list_tag __builtin_va_list[1];";
Anders Carlsson5fa3f342007-11-24 23:38:12 +00001693 }
Michael J. Spencerfeb799c2010-10-18 07:10:59 +00001694
Chris Lattnerd545ad12009-09-23 06:06:36 +00001695 int getEHDataRegisterNumber(unsigned RegNo) const {
1696 if (RegNo == 0) return 0;
1697 if (RegNo == 1) return 1;
1698 return -1;
1699 }
Eli Friedman3fd920a2008-08-20 02:34:37 +00001700};
1701} // end anonymous namespace
1702
1703namespace {
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001704// x86-64 Windows target
Michael J. Spencer4992ca4b2010-10-21 05:21:48 +00001705class WindowsX86_64TargetInfo : public WindowsTargetInfo<X86_64TargetInfo> {
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001706public:
1707 WindowsX86_64TargetInfo(const std::string& triple)
Michael J. Spencer4992ca4b2010-10-21 05:21:48 +00001708 : WindowsTargetInfo<X86_64TargetInfo>(triple) {
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001709 TLSSupported = false;
1710 WCharType = UnsignedShort;
Mike Stumpaf9afe92009-10-08 23:00:00 +00001711 LongWidth = LongAlign = 32;
Michael J. Spencerfeb799c2010-10-18 07:10:59 +00001712 DoubleAlign = LongLongAlign = 64;
Nate Begeman6e8865a2010-07-21 02:02:56 +00001713 IntMaxType = SignedLongLong;
1714 UIntMaxType = UnsignedLongLong;
1715 Int64Type = SignedLongLong;
Cameron Esfahanieb856502010-09-15 00:28:12 +00001716 SizeType = UnsignedLongLong;
1717 PtrDiffType = SignedLongLong;
1718 IntPtrType = SignedLongLong;
NAKAMURA Takumif7c30222011-01-17 22:56:08 +00001719 this->UserLabelPrefix = "";
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001720 }
1721 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001722 MacroBuilder &Builder) const {
Michael J. Spencer4992ca4b2010-10-21 05:21:48 +00001723 WindowsTargetInfo<X86_64TargetInfo>::getTargetDefines(Opts, Builder);
Michael J. Spencer4992ca4b2010-10-21 05:21:48 +00001724 Builder.defineMacro("_WIN64");
Michael J. Spencer54bf3c32010-10-21 08:22:51 +00001725 }
NAKAMURA Takumia2e468c2011-01-17 22:56:23 +00001726 virtual const char *getVAListDeclaration() const {
1727 return "typedef char* __builtin_va_list;";
1728 }
Michael J. Spencer54bf3c32010-10-21 08:22:51 +00001729};
1730} // end anonymous namespace
1731
1732namespace {
1733// x86-64 Windows Visual Studio target
1734class VisualStudioWindowsX86_64TargetInfo : public WindowsX86_64TargetInfo {
1735public:
1736 VisualStudioWindowsX86_64TargetInfo(const std::string& triple)
1737 : WindowsX86_64TargetInfo(triple) {
Eli Friedman015d6282011-03-22 21:25:11 +00001738 LongDoubleWidth = LongDoubleAlign = 64;
1739 LongDoubleFormat = &llvm::APFloat::IEEEdouble;
Michael J. Spencer54bf3c32010-10-21 08:22:51 +00001740 }
1741 virtual void getTargetDefines(const LangOptions &Opts,
1742 MacroBuilder &Builder) const {
1743 WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
1744 WindowsX86_64TargetInfo::getVisualStudioDefines(Opts, Builder);
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001745 Builder.defineMacro("_M_X64");
Michael J. Spencer4992ca4b2010-10-21 05:21:48 +00001746 Builder.defineMacro("_M_AMD64");
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001747 }
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001748};
1749} // end anonymous namespace
1750
1751namespace {
1752// x86-64 MinGW target
1753class MinGWX86_64TargetInfo : public WindowsX86_64TargetInfo {
1754public:
1755 MinGWX86_64TargetInfo(const std::string& triple)
1756 : WindowsX86_64TargetInfo(triple) {
1757 }
1758 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001759 MacroBuilder &Builder) const {
1760 WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
Michael J. Spencer54bf3c32010-10-21 08:22:51 +00001761 DefineStd(Builder, "WIN64", Opts);
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001762 Builder.defineMacro("__MSVCRT__");
NAKAMURA Takumi2b7eeb22011-03-08 12:06:46 +00001763 Builder.defineMacro("__MINGW32__");
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001764 Builder.defineMacro("__MINGW64__");
NAKAMURA Takumib2beb012011-03-15 02:32:50 +00001765
1766 // mingw32-gcc provides __declspec(a) as alias of __attribute__((a)).
1767 // In contrast, clang-cc1 provides __declspec(a) with -fms-extensions.
1768 if (Opts.Microsoft)
1769 // Provide "as-is" __declspec.
1770 Builder.defineMacro("__declspec", "__declspec");
1771 else
1772 // Provide alias of __attribute__ like mingw32-gcc.
1773 Builder.defineMacro("__declspec(a)", "__attribute__((a))");
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001774 }
1775};
1776} // end anonymous namespace
1777
1778namespace {
Eli Friedman2857ccb2009-07-01 03:36:11 +00001779class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> {
1780public:
Mike Stump11289f42009-09-09 15:08:12 +00001781 DarwinX86_64TargetInfo(const std::string& triple)
Eli Friedman2857ccb2009-07-01 03:36:11 +00001782 : DarwinTargetInfo<X86_64TargetInfo>(triple) {
1783 Int64Type = SignedLongLong;
1784 }
1785};
1786} // end anonymous namespace
1787
1788namespace {
Eli Friedman245f2292009-07-05 22:31:18 +00001789class OpenBSDX86_64TargetInfo : public OpenBSDTargetInfo<X86_64TargetInfo> {
1790public:
Mike Stump11289f42009-09-09 15:08:12 +00001791 OpenBSDX86_64TargetInfo(const std::string& triple)
Eli Friedman245f2292009-07-05 22:31:18 +00001792 : OpenBSDTargetInfo<X86_64TargetInfo>(triple) {
1793 IntMaxType = SignedLongLong;
1794 UIntMaxType = UnsignedLongLong;
1795 Int64Type = SignedLongLong;
1796 }
1797};
1798} // end anonymous namespace
1799
1800namespace {
Eli Friedmanf05b7722008-08-20 07:44:10 +00001801class ARMTargetInfo : public TargetInfo {
Daniel Dunbar0def3d12009-12-21 23:28:17 +00001802 // Possible FPU choices.
1803 enum FPUMode {
1804 NoFPU,
1805 VFP2FPU,
1806 VFP3FPU,
1807 NeonFPU
1808 };
1809
1810 static bool FPUModeIsVFP(FPUMode Mode) {
1811 return Mode >= VFP2FPU && Mode <= NeonFPU;
1812 }
1813
1814 static const TargetInfo::GCCRegAlias GCCRegAliases[];
1815 static const char * const GCCRegNames[];
Daniel Dunbar1da76c42009-09-17 07:03:19 +00001816
Daniel Dunbaracde99e2009-12-18 18:42:37 +00001817 std::string ABI, CPU;
Daniel Dunbar0def3d12009-12-21 23:28:17 +00001818
1819 unsigned FPU : 3;
1820
Daniel Dunbar893d4752009-12-19 04:15:38 +00001821 unsigned IsThumb : 1;
1822
1823 // Initialized via features.
1824 unsigned SoftFloat : 1;
1825 unsigned SoftFloatABI : 1;
Daniel Dunbarb4091a92009-09-14 00:35:03 +00001826
Chris Lattner5cc15e02010-03-03 19:03:45 +00001827 static const Builtin::Info BuiltinInfo[];
1828
Chris Lattner17df24e2008-04-21 18:56:49 +00001829public:
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001830 ARMTargetInfo(const std::string &TripleStr)
Daniel Dunbaracde99e2009-12-18 18:42:37 +00001831 : TargetInfo(TripleStr), ABI("aapcs-linux"), CPU("arm1136j-s")
Daniel Dunbarb4091a92009-09-14 00:35:03 +00001832 {
Daniel Dunbar125f8fb2009-09-14 00:02:24 +00001833 SizeType = UnsignedInt;
1834 PtrDiffType = SignedInt;
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001835
Chris Lattner1a8f3942010-04-23 16:29:58 +00001836 // {} in inline assembly are neon specifiers, not assembly variant
1837 // specifiers.
1838 NoAsmVariants = true;
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +00001839
Daniel Dunbaracde99e2009-12-18 18:42:37 +00001840 // FIXME: Should we just treat this as a feature?
Daniel Dunbarc454ecf2009-12-18 19:57:13 +00001841 IsThumb = getTriple().getArchName().startswith("thumb");
Daniel Dunbar03184792009-09-22 21:44:58 +00001842 if (IsThumb) {
Sandeep Patelf87b3732011-04-04 22:58:12 +00001843 // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
1844 // so set preferred for small types to 32.
Daniel Dunbar03184792009-09-22 21:44:58 +00001845 DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
1846 "i64:64:64-f32:32:32-f64:64:64-"
Bob Wilsone3a15fe2011-04-04 16:53:11 +00001847 "v64:64:64-v128:64:128-a0:0:32-n32");
Daniel Dunbar03184792009-09-22 21:44:58 +00001848 } else {
1849 DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1850 "i64:64:64-f32:32:32-f64:64:64-"
Bob Wilsone3a15fe2011-04-04 16:53:11 +00001851 "v64:64:64-v128:64:128-a0:0:64-n32");
Daniel Dunbar03184792009-09-22 21:44:58 +00001852 }
John McCall86353412010-08-21 22:46:04 +00001853
1854 // ARM targets default to using the ARM C++ ABI.
1855 CXXABI = CXXABI_ARM;
Eli Friedmanb5366062008-05-20 14:21:01 +00001856 }
Daniel Dunbarb4091a92009-09-14 00:35:03 +00001857 virtual const char *getABI() const { return ABI.c_str(); }
Daniel Dunbar125f8fb2009-09-14 00:02:24 +00001858 virtual bool setABI(const std::string &Name) {
Daniel Dunbarb4091a92009-09-14 00:35:03 +00001859 ABI = Name;
1860
Daniel Dunbar125f8fb2009-09-14 00:02:24 +00001861 // The defaults (above) are for AAPCS, check if we need to change them.
1862 //
1863 // FIXME: We need support for -meabi... we could just mangle it into the
1864 // name.
1865 if (Name == "apcs-gnu") {
Daniel Dunbar377dc2f2010-01-27 20:23:08 +00001866 DoubleAlign = LongLongAlign = LongDoubleAlign = 32;
Daniel Dunbar125f8fb2009-09-14 00:02:24 +00001867 SizeType = UnsignedLong;
1868
Daniel Dunbarf8125062010-04-22 16:14:54 +00001869 // Do not respect the alignment of bit-field types when laying out
1870 // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
1871 UseBitFieldTypeAlignment = false;
1872
Daniel Dunbar03184792009-09-22 21:44:58 +00001873 if (IsThumb) {
Sandeep Patelf87b3732011-04-04 22:58:12 +00001874 // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
1875 // so set preferred for small types to 32.
Daniel Dunbar03184792009-09-22 21:44:58 +00001876 DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
1877 "i64:32:32-f32:32:32-f64:32:32-"
Bob Wilsone3a15fe2011-04-04 16:53:11 +00001878 "v64:32:64-v128:32:128-a0:0:32-n32");
Daniel Dunbar03184792009-09-22 21:44:58 +00001879 } else {
1880 DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
Bob Wilsone3a15fe2011-04-04 16:53:11 +00001881 "i64:32:64-f32:32:32-f64:32:64-"
1882 "v64:32:64-v128:32:128-a0:0:32-n32");
Daniel Dunbar03184792009-09-22 21:44:58 +00001883 }
1884
Daniel Dunbar125f8fb2009-09-14 00:02:24 +00001885 // FIXME: Override "preferred align" for double and long long.
1886 } else if (Name == "aapcs") {
1887 // FIXME: Enumerated types are variable width in straight AAPCS.
1888 } else if (Name == "aapcs-linux") {
1889 ;
1890 } else
1891 return false;
1892
1893 return true;
1894 }
Daniel Dunbar893d4752009-12-19 04:15:38 +00001895
Daniel Dunbar0def3d12009-12-21 23:28:17 +00001896 void getDefaultFeatures(const std::string &CPU,
1897 llvm::StringMap<bool> &Features) const {
1898 // FIXME: This should not be here.
1899 Features["vfp2"] = false;
1900 Features["vfp3"] = false;
1901 Features["neon"] = false;
1902
1903 if (CPU == "arm1136jf-s" || CPU == "arm1176jzf-s" || CPU == "mpcore")
1904 Features["vfp2"] = true;
1905 else if (CPU == "cortex-a8" || CPU == "cortex-a9")
1906 Features["neon"] = true;
1907 }
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +00001908
Daniel Dunbar893d4752009-12-19 04:15:38 +00001909 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
1910 const std::string &Name,
1911 bool Enabled) const {
Daniel Dunbar0def3d12009-12-21 23:28:17 +00001912 if (Name == "soft-float" || Name == "soft-float-abi") {
1913 Features[Name] = Enabled;
1914 } else if (Name == "vfp2" || Name == "vfp3" || Name == "neon") {
1915 // These effectively are a single option, reset them when any is enabled.
1916 if (Enabled)
1917 Features["vfp2"] = Features["vfp3"] = Features["neon"] = false;
1918 Features[Name] = Enabled;
1919 } else
Daniel Dunbar893d4752009-12-19 04:15:38 +00001920 return false;
1921
Daniel Dunbar893d4752009-12-19 04:15:38 +00001922 return true;
1923 }
1924
1925 virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
Daniel Dunbar0def3d12009-12-21 23:28:17 +00001926 FPU = NoFPU;
Daniel Dunbar893d4752009-12-19 04:15:38 +00001927 SoftFloat = SoftFloatABI = false;
1928 for (unsigned i = 0, e = Features.size(); i != e; ++i) {
1929 if (Features[i] == "+soft-float")
1930 SoftFloat = true;
1931 else if (Features[i] == "+soft-float-abi")
1932 SoftFloatABI = true;
Daniel Dunbar0def3d12009-12-21 23:28:17 +00001933 else if (Features[i] == "+vfp2")
1934 FPU = VFP2FPU;
1935 else if (Features[i] == "+vfp3")
1936 FPU = VFP3FPU;
1937 else if (Features[i] == "+neon")
1938 FPU = NeonFPU;
Daniel Dunbar893d4752009-12-19 04:15:38 +00001939 }
1940
1941 // Remove front-end specific options which the backend handles differently.
1942 std::vector<std::string>::iterator it;
1943 it = std::find(Features.begin(), Features.end(), "+soft-float");
1944 if (it != Features.end())
1945 Features.erase(it);
1946 it = std::find(Features.begin(), Features.end(), "+soft-float-abi");
1947 if (it != Features.end())
1948 Features.erase(it);
1949 }
1950
Daniel Dunbaracde99e2009-12-18 18:42:37 +00001951 static const char *getCPUDefineSuffix(llvm::StringRef Name) {
1952 return llvm::StringSwitch<const char*>(Name)
1953 .Cases("arm8", "arm810", "4")
1954 .Cases("strongarm", "strongarm110", "strongarm1100", "strongarm1110", "4")
1955 .Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "arm720t", "arm9", "4T")
1956 .Cases("arm9tdmi", "arm920", "arm920t", "arm922t", "arm940t", "4T")
1957 .Case("ep9312", "4T")
1958 .Cases("arm10tdmi", "arm1020t", "5T")
1959 .Cases("arm9e", "arm946e-s", "arm966e-s", "arm968e-s", "5TE")
1960 .Case("arm926ej-s", "5TEJ")
1961 .Cases("arm10e", "arm1020e", "arm1022e", "5TE")
1962 .Cases("xscale", "iwmmxt", "5TE")
Daniel Dunbar0def3d12009-12-21 23:28:17 +00001963 .Case("arm1136j-s", "6J")
Daniel Dunbaracde99e2009-12-18 18:42:37 +00001964 .Cases("arm1176jz-s", "arm1176jzf-s", "6ZK")
Daniel Dunbar0def3d12009-12-21 23:28:17 +00001965 .Cases("arm1136jf-s", "mpcorenovfp", "mpcore", "6K")
Daniel Dunbaracde99e2009-12-18 18:42:37 +00001966 .Cases("arm1156t2-s", "arm1156t2f-s", "6T2")
1967 .Cases("cortex-a8", "cortex-a9", "7A")
Bob Wilson44acad82011-01-06 16:57:20 +00001968 .Case("cortex-m3", "7M")
Bob Wilson87ba1d32011-03-21 21:55:25 +00001969 .Case("cortex-m0", "6M")
Daniel Dunbaracde99e2009-12-18 18:42:37 +00001970 .Default(0);
1971 }
1972 virtual bool setCPU(const std::string &Name) {
1973 if (!getCPUDefineSuffix(Name))
1974 return false;
1975
1976 CPU = Name;
1977 return true;
1978 }
Chris Lattner4ba73aa02009-03-20 15:52:06 +00001979 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001980 MacroBuilder &Builder) const {
Chris Lattnerecd49032009-03-02 22:27:17 +00001981 // Target identification.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001982 Builder.defineMacro("__arm");
1983 Builder.defineMacro("__arm__");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001984
Chris Lattnerecd49032009-03-02 22:27:17 +00001985 // Target properties.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001986 Builder.defineMacro("__ARMEL__");
1987 Builder.defineMacro("__LITTLE_ENDIAN__");
1988 Builder.defineMacro("__REGISTER_PREFIX__", "");
Daniel Dunbaracde99e2009-12-18 18:42:37 +00001989
1990 llvm::StringRef CPUArch = getCPUDefineSuffix(CPU);
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001991 Builder.defineMacro("__ARM_ARCH_" + CPUArch + "__");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001992
Mike Stump9d54bd72009-04-08 02:07:04 +00001993 // Subtarget options.
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001994
Daniel Dunbaracde99e2009-12-18 18:42:37 +00001995 // FIXME: It's more complicated than this and we don't really support
1996 // interworking.
1997 if ('5' <= CPUArch[0] && CPUArch[0] <= '7')
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00001998 Builder.defineMacro("__THUMB_INTERWORK__");
Daniel Dunbaracde99e2009-12-18 18:42:37 +00001999
Daniel Dunbaracde99e2009-12-18 18:42:37 +00002000 if (ABI == "aapcs" || ABI == "aapcs-linux")
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002001 Builder.defineMacro("__ARM_EABI__");
Daniel Dunbaracde99e2009-12-18 18:42:37 +00002002
Daniel Dunbar893d4752009-12-19 04:15:38 +00002003 if (SoftFloat)
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002004 Builder.defineMacro("__SOFTFP__");
Daniel Dunbaracde99e2009-12-18 18:42:37 +00002005
2006 if (CPU == "xscale")
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002007 Builder.defineMacro("__XSCALE__");
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00002008
Bob Wilson19c1b882011-05-13 18:56:03 +00002009 bool IsARMv7 = CPUArch.startswith("7");
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00002010 if (IsThumb) {
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002011 Builder.defineMacro("__THUMBEL__");
2012 Builder.defineMacro("__thumb__");
Bob Wilson19c1b882011-05-13 18:56:03 +00002013 if (CPUArch == "6T2" || IsARMv7)
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002014 Builder.defineMacro("__thumb2__");
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00002015 }
2016
2017 // Note, this is always on in gcc, even though it doesn't make sense.
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002018 Builder.defineMacro("__APCS_32__");
Daniel Dunbar0def3d12009-12-21 23:28:17 +00002019
2020 if (FPUModeIsVFP((FPUMode) FPU))
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002021 Builder.defineMacro("__VFP_FP__");
Daniel Dunbar0def3d12009-12-21 23:28:17 +00002022
2023 // This only gets set when Neon instructions are actually available, unlike
2024 // the VFP define, hence the soft float and arch check. This is subtly
2025 // different from gcc, we follow the intent which was that it should be set
2026 // when Neon instructions are actually available.
Bob Wilson19c1b882011-05-13 18:56:03 +00002027 if (FPU == NeonFPU && !SoftFloat && IsARMv7)
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002028 Builder.defineMacro("__ARM_NEON__");
Chris Lattner17df24e2008-04-21 18:56:49 +00002029 }
2030 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2031 unsigned &NumRecords) const {
Chris Lattner5cc15e02010-03-03 19:03:45 +00002032 Records = BuiltinInfo;
2033 NumRecords = clang::ARM::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner17df24e2008-04-21 18:56:49 +00002034 }
2035 virtual const char *getVAListDeclaration() const {
John McCalle155a3d2011-05-09 02:19:37 +00002036 return "typedef void* __builtin_va_list;";
Chris Lattner17df24e2008-04-21 18:56:49 +00002037 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00002038 virtual void getGCCRegNames(const char * const *&Names,
Daniel Dunbar1da76c42009-09-17 07:03:19 +00002039 unsigned &NumNames) const;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00002040 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Daniel Dunbar1da76c42009-09-17 07:03:19 +00002041 unsigned &NumAliases) const;
Anders Carlsson58436352009-02-28 17:11:49 +00002042 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattnerd9725f72009-04-26 07:16:29 +00002043 TargetInfo::ConstraintInfo &Info) const {
Eli Friedmanf05b7722008-08-20 07:44:10 +00002044 // FIXME: Check if this is complete
Anders Carlsson58436352009-02-28 17:11:49 +00002045 switch (*Name) {
Eli Friedmanf05b7722008-08-20 07:44:10 +00002046 default:
Nate Begeman2908fa02008-04-22 05:03:19 +00002047 case 'l': // r0-r7
2048 case 'h': // r8-r15
2049 case 'w': // VFP Floating point register single precision
2050 case 'P': // VFP Floating point register double precision
Chris Lattnerd9725f72009-04-26 07:16:29 +00002051 Info.setAllowsRegister();
Nate Begeman2908fa02008-04-22 05:03:19 +00002052 return true;
Stuart Hastings7fdc6702011-06-07 23:45:05 +00002053 case 'U': // a memory reference...
2054 switch (Name[1]) {
2055 case 'q': // ...ARMV4 ldrsb
2056 case 'v': // ...VFP load/store (reg+constant offset)
2057 case 'y': // ...iWMMXt load/store
2058 Info.setAllowsMemory();
2059 Name++;
2060 return true;
2061 }
Nate Begeman2908fa02008-04-22 05:03:19 +00002062 }
Chris Lattner17df24e2008-04-21 18:56:49 +00002063 return false;
2064 }
Evan Chengd863adb2011-06-16 19:13:15 +00002065 virtual std::string convertConstraint(const char *&Constraint) const {
Stuart Hastings7fdc6702011-06-07 23:45:05 +00002066 std::string R;
2067 switch (*Constraint) {
2068 case 'U': // Two-character constraint; add "^" hint for later parsing.
Stuart Hastings5b7b11c2011-06-08 16:06:31 +00002069 R = std::string("^") + std::string(Constraint, 2);
Stuart Hastings7fdc6702011-06-07 23:45:05 +00002070 Constraint++;
2071 break;
Eric Christopher7d237c12011-06-17 00:40:18 +00002072 case 'p': // 'p' should be translated to 'r' by default.
2073 R = std::string("r");
2074 break;
Stuart Hastings7fdc6702011-06-07 23:45:05 +00002075 default:
2076 return std::string(1, *Constraint);
2077 }
2078 return R;
2079 }
Chris Lattner17df24e2008-04-21 18:56:49 +00002080 virtual const char *getClobbers() const {
Eli Friedmanf05b7722008-08-20 07:44:10 +00002081 // FIXME: Is this really right?
Chris Lattner17df24e2008-04-21 18:56:49 +00002082 return "";
2083 }
2084};
Daniel Dunbar1da76c42009-09-17 07:03:19 +00002085
2086const char * const ARMTargetInfo::GCCRegNames[] = {
Daniel Dunbar9034aa32010-08-11 02:17:20 +00002087 // Integer registers
Daniel Dunbar1da76c42009-09-17 07:03:19 +00002088 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
Daniel Dunbar9034aa32010-08-11 02:17:20 +00002089 "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc",
2090
2091 // Float registers
2092 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2093 "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15",
2094 "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23",
Dale Johannesen7fd51bc2010-10-27 23:34:42 +00002095 "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
Daniel Dunbar9034aa32010-08-11 02:17:20 +00002096
Dale Johannesen7fd51bc2010-10-27 23:34:42 +00002097 // Double registers
2098 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
2099 "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15",
Dale Johannesend2b2ad02010-10-28 01:05:37 +00002100 "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23",
2101 "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
Dale Johannesen7fd51bc2010-10-27 23:34:42 +00002102
2103 // Quad registers
Dale Johannesend2b2ad02010-10-28 01:05:37 +00002104 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7",
2105 "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
Daniel Dunbar1da76c42009-09-17 07:03:19 +00002106};
2107
2108void ARMTargetInfo::getGCCRegNames(const char * const *&Names,
Daniel Dunbar256e1f32010-08-11 02:17:11 +00002109 unsigned &NumNames) const {
Daniel Dunbar1da76c42009-09-17 07:03:19 +00002110 Names = GCCRegNames;
2111 NumNames = llvm::array_lengthof(GCCRegNames);
2112}
2113
2114const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
Daniel Dunbar1da76c42009-09-17 07:03:19 +00002115 { { "a1" }, "r0" },
2116 { { "a2" }, "r1" },
2117 { { "a3" }, "r2" },
2118 { { "a4" }, "r3" },
2119 { { "v1" }, "r4" },
2120 { { "v2" }, "r5" },
2121 { { "v3" }, "r6" },
2122 { { "v4" }, "r7" },
2123 { { "v5" }, "r8" },
2124 { { "v6", "rfp" }, "r9" },
2125 { { "sl" }, "r10" },
2126 { { "fp" }, "r11" },
2127 { { "ip" }, "r12" },
Daniel Dunbar256e1f32010-08-11 02:17:11 +00002128 { { "r13" }, "sp" },
2129 { { "r14" }, "lr" },
2130 { { "r15" }, "pc" },
Dale Johannesen7fd51bc2010-10-27 23:34:42 +00002131 // The S, D and Q registers overlap, but aren't really aliases; we
2132 // don't want to substitute one of these for a different-sized one.
Daniel Dunbar1da76c42009-09-17 07:03:19 +00002133};
2134
2135void ARMTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
2136 unsigned &NumAliases) const {
2137 Aliases = GCCRegAliases;
2138 NumAliases = llvm::array_lengthof(GCCRegAliases);
2139}
Chris Lattner5cc15e02010-03-03 19:03:45 +00002140
2141const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
Fariborz Jahaniane8473c22010-11-30 17:35:24 +00002142#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES, false },
2143#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
2144 ALL_LANGUAGES, false },
Chris Lattner5cc15e02010-03-03 19:03:45 +00002145#include "clang/Basic/BuiltinsARM.def"
2146};
Chris Lattner17df24e2008-04-21 18:56:49 +00002147} // end anonymous namespace.
2148
Eli Friedmanf05b7722008-08-20 07:44:10 +00002149
2150namespace {
Mike Stump11289f42009-09-09 15:08:12 +00002151class DarwinARMTargetInfo :
Torok Edwinb2b37c62009-06-30 17:10:35 +00002152 public DarwinTargetInfo<ARMTargetInfo> {
2153protected:
Daniel Dunbar40165182009-08-24 09:10:05 +00002154 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002155 MacroBuilder &Builder) const {
Douglas Gregor20b2ebd2011-03-23 00:50:03 +00002156 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
Eli Friedmand88c8a12009-04-19 21:38:35 +00002157 }
Eli Friedmanf05b7722008-08-20 07:44:10 +00002158
Torok Edwinb2b37c62009-06-30 17:10:35 +00002159public:
Mike Stump11289f42009-09-09 15:08:12 +00002160 DarwinARMTargetInfo(const std::string& triple)
Daniel Dunbar3eeeccd2010-05-27 07:00:26 +00002161 : DarwinTargetInfo<ARMTargetInfo>(triple) {
2162 HasAlignMac68kSupport = true;
2163 }
Eli Friedmanf05b7722008-08-20 07:44:10 +00002164};
2165} // end anonymous namespace.
2166
Chris Lattner5ba61f02006-10-14 07:39:34 +00002167namespace {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00002168class SparcV8TargetInfo : public TargetInfo {
Chris Lattner9b415d62009-01-27 01:58:38 +00002169 static const TargetInfo::GCCRegAlias GCCRegAliases[];
2170 static const char * const GCCRegNames[];
Bruno Cardoso Lopese7f211c2010-11-09 17:21:19 +00002171 bool SoftFloat;
Gabor Greif49991682008-02-21 16:29:08 +00002172public:
Eli Friedmanda8f5a92008-08-20 07:28:14 +00002173 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
2174 // FIXME: Support Sparc quad-precision long double?
Eli Friedman873f65a2008-08-21 00:13:15 +00002175 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
Chris Lattner5c67237f2009-11-07 18:59:41 +00002176 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
Eli Friedmanda8f5a92008-08-20 07:28:14 +00002177 }
Bruno Cardoso Lopese7f211c2010-11-09 17:21:19 +00002178 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
2179 const std::string &Name,
2180 bool Enabled) const {
2181 if (Name == "soft-float")
2182 Features[Name] = Enabled;
2183 else
2184 return false;
2185
2186 return true;
2187 }
2188 virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
2189 SoftFloat = false;
2190 for (unsigned i = 0, e = Features.size(); i != e; ++i)
2191 if (Features[i] == "+soft-float")
2192 SoftFloat = true;
2193 }
Chris Lattner4ba73aa02009-03-20 15:52:06 +00002194 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002195 MacroBuilder &Builder) const {
2196 DefineStd(Builder, "sparc", Opts);
2197 Builder.defineMacro("__sparcv8");
2198 Builder.defineMacro("__REGISTER_PREFIX__", "");
Bruno Cardoso Lopese7f211c2010-11-09 17:21:19 +00002199
2200 if (SoftFloat)
2201 Builder.defineMacro("SOFT_FLOAT", "1");
Gabor Greif49991682008-02-21 16:29:08 +00002202 }
2203 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2204 unsigned &NumRecords) const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00002205 // FIXME: Implement!
Gabor Greif49991682008-02-21 16:29:08 +00002206 }
2207 virtual const char *getVAListDeclaration() const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00002208 return "typedef void* __builtin_va_list;";
Gabor Greif49991682008-02-21 16:29:08 +00002209 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00002210 virtual void getGCCRegNames(const char * const *&Names,
Chris Lattner9b415d62009-01-27 01:58:38 +00002211 unsigned &NumNames) const;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00002212 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattner9b415d62009-01-27 01:58:38 +00002213 unsigned &NumAliases) const;
Anders Carlsson58436352009-02-28 17:11:49 +00002214 virtual bool validateAsmConstraint(const char *&Name,
Gabor Greif49991682008-02-21 16:29:08 +00002215 TargetInfo::ConstraintInfo &info) const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00002216 // FIXME: Implement!
2217 return false;
Gabor Greif49991682008-02-21 16:29:08 +00002218 }
2219 virtual const char *getClobbers() const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00002220 // FIXME: Implement!
2221 return "";
Gabor Greif49991682008-02-21 16:29:08 +00002222 }
2223};
2224
Chris Lattner9b415d62009-01-27 01:58:38 +00002225const char * const SparcV8TargetInfo::GCCRegNames[] = {
2226 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2227 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2228 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2229 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
2230};
2231
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00002232void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names,
Chris Lattner9b415d62009-01-27 01:58:38 +00002233 unsigned &NumNames) const {
2234 Names = GCCRegNames;
2235 NumNames = llvm::array_lengthof(GCCRegNames);
2236}
2237
2238const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = {
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00002239 { { "g0" }, "r0" },
2240 { { "g1" }, "r1" },
2241 { { "g2" }, "r2" },
2242 { { "g3" }, "r3" },
2243 { { "g4" }, "r4" },
2244 { { "g5" }, "r5" },
2245 { { "g6" }, "r6" },
2246 { { "g7" }, "r7" },
2247 { { "o0" }, "r8" },
2248 { { "o1" }, "r9" },
2249 { { "o2" }, "r10" },
2250 { { "o3" }, "r11" },
2251 { { "o4" }, "r12" },
2252 { { "o5" }, "r13" },
2253 { { "o6", "sp" }, "r14" },
2254 { { "o7" }, "r15" },
2255 { { "l0" }, "r16" },
2256 { { "l1" }, "r17" },
2257 { { "l2" }, "r18" },
2258 { { "l3" }, "r19" },
2259 { { "l4" }, "r20" },
2260 { { "l5" }, "r21" },
2261 { { "l6" }, "r22" },
2262 { { "l7" }, "r23" },
2263 { { "i0" }, "r24" },
2264 { { "i1" }, "r25" },
2265 { { "i2" }, "r26" },
2266 { { "i3" }, "r27" },
2267 { { "i4" }, "r28" },
2268 { { "i5" }, "r29" },
2269 { { "i6", "fp" }, "r30" },
2270 { { "i7" }, "r31" },
Chris Lattner9b415d62009-01-27 01:58:38 +00002271};
2272
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00002273void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattner9b415d62009-01-27 01:58:38 +00002274 unsigned &NumAliases) const {
2275 Aliases = GCCRegAliases;
2276 NumAliases = llvm::array_lengthof(GCCRegAliases);
2277}
Gabor Greif49991682008-02-21 16:29:08 +00002278} // end anonymous namespace.
2279
Eli Friedmanda8f5a92008-08-20 07:28:14 +00002280namespace {
Edward O'Callaghan9dda8e982009-10-18 13:33:59 +00002281class AuroraUXSparcV8TargetInfo : public AuroraUXTargetInfo<SparcV8TargetInfo> {
2282public:
2283 AuroraUXSparcV8TargetInfo(const std::string& triple) :
2284 AuroraUXTargetInfo<SparcV8TargetInfo>(triple) {
2285 SizeType = UnsignedInt;
2286 PtrDiffType = SignedInt;
2287 }
2288};
Torok Edwinb2b37c62009-06-30 17:10:35 +00002289class SolarisSparcV8TargetInfo : public SolarisTargetInfo<SparcV8TargetInfo> {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00002290public:
2291 SolarisSparcV8TargetInfo(const std::string& triple) :
Torok Edwinb2b37c62009-06-30 17:10:35 +00002292 SolarisTargetInfo<SparcV8TargetInfo>(triple) {
Eli Friedmand50881c2008-11-02 02:43:55 +00002293 SizeType = UnsignedInt;
2294 PtrDiffType = SignedInt;
Eli Friedmanda8f5a92008-08-20 07:28:14 +00002295 }
2296};
2297} // end anonymous namespace.
Chris Lattner5ba61f02006-10-14 07:39:34 +00002298
Chris Lattnerb781dc792008-05-08 05:58:21 +00002299namespace {
Anton Korobeynikova0f54372009-05-03 13:43:08 +00002300 class MSP430TargetInfo : public TargetInfo {
2301 static const char * const GCCRegNames[];
2302 public:
2303 MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) {
2304 TLSSupported = false;
Anton Korobeynikovcbc4e982010-01-30 12:55:11 +00002305 IntWidth = 16; IntAlign = 16;
2306 LongWidth = 32; LongLongWidth = 64;
2307 LongAlign = LongLongAlign = 16;
2308 PointerWidth = 16; PointerAlign = 16;
Anton Korobeynikova0f54372009-05-03 13:43:08 +00002309 SizeType = UnsignedInt;
2310 IntMaxType = SignedLong;
2311 UIntMaxType = UnsignedLong;
2312 IntPtrType = SignedShort;
2313 PtrDiffType = SignedInt;
Edward O'Callaghan847f2a12009-11-21 00:49:54 +00002314 SigAtomicType = SignedLong;
Anton Korobeynikovd94329a2009-12-19 01:32:37 +00002315 DescriptionString = "e-p:16:16:16-i8:8:8-i16:16:16-i32:16:32-n8:16";
Anton Korobeynikova0f54372009-05-03 13:43:08 +00002316 }
2317 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002318 MacroBuilder &Builder) const {
2319 Builder.defineMacro("MSP430");
2320 Builder.defineMacro("__MSP430__");
Anton Korobeynikova0f54372009-05-03 13:43:08 +00002321 // FIXME: defines for different 'flavours' of MCU
2322 }
2323 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2324 unsigned &NumRecords) const {
2325 // FIXME: Implement.
2326 Records = 0;
2327 NumRecords = 0;
2328 }
Anton Korobeynikova0f54372009-05-03 13:43:08 +00002329 virtual void getGCCRegNames(const char * const *&Names,
2330 unsigned &NumNames) const;
2331 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2332 unsigned &NumAliases) const {
2333 // No aliases.
2334 Aliases = 0;
2335 NumAliases = 0;
2336 }
2337 virtual bool validateAsmConstraint(const char *&Name,
2338 TargetInfo::ConstraintInfo &info) const {
Anton Korobeynikov051913b2009-10-15 23:17:13 +00002339 // No target constraints for now.
2340 return false;
Anton Korobeynikova0f54372009-05-03 13:43:08 +00002341 }
2342 virtual const char *getClobbers() const {
2343 // FIXME: Is this really right?
2344 return "";
2345 }
2346 virtual const char *getVAListDeclaration() const {
2347 // FIXME: implement
Anton Korobeynikov2f910822009-05-08 18:24:57 +00002348 return "typedef char* __builtin_va_list;";
Anton Korobeynikova0f54372009-05-03 13:43:08 +00002349 }
2350 };
2351
2352 const char * const MSP430TargetInfo::GCCRegNames[] = {
2353 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2354 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
2355 };
2356
2357 void MSP430TargetInfo::getGCCRegNames(const char * const *&Names,
2358 unsigned &NumNames) const {
2359 Names = GCCRegNames;
2360 NumNames = llvm::array_lengthof(GCCRegNames);
2361 }
2362}
2363
2364
Anton Korobeynikovb5b703b2009-07-16 20:09:57 +00002365namespace {
2366 class SystemZTargetInfo : public TargetInfo {
2367 static const char * const GCCRegNames[];
2368 public:
2369 SystemZTargetInfo(const std::string& triple) : TargetInfo(triple) {
2370 TLSSupported = false;
2371 IntWidth = IntAlign = 32;
2372 LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64;
2373 PointerWidth = PointerAlign = 64;
Chris Lattner5c67237f2009-11-07 18:59:41 +00002374 DescriptionString = "E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-"
2375 "i64:64:64-f32:32:32-f64:64:64-f128:128:128-a0:16:16-n32:64";
Anton Korobeynikovb5b703b2009-07-16 20:09:57 +00002376 }
2377 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002378 MacroBuilder &Builder) const {
2379 Builder.defineMacro("__s390__");
2380 Builder.defineMacro("__s390x__");
Anton Korobeynikovb5b703b2009-07-16 20:09:57 +00002381 }
2382 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2383 unsigned &NumRecords) const {
2384 // FIXME: Implement.
2385 Records = 0;
2386 NumRecords = 0;
2387 }
Anton Korobeynikovb5b703b2009-07-16 20:09:57 +00002388
Anton Korobeynikovb5b703b2009-07-16 20:09:57 +00002389 virtual void getGCCRegNames(const char * const *&Names,
2390 unsigned &NumNames) const;
2391 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2392 unsigned &NumAliases) const {
2393 // No aliases.
2394 Aliases = 0;
2395 NumAliases = 0;
2396 }
2397 virtual bool validateAsmConstraint(const char *&Name,
2398 TargetInfo::ConstraintInfo &info) const {
2399 // FIXME: implement
2400 return true;
2401 }
2402 virtual const char *getClobbers() const {
2403 // FIXME: Is this really right?
2404 return "";
2405 }
2406 virtual const char *getVAListDeclaration() const {
2407 // FIXME: implement
2408 return "typedef char* __builtin_va_list;";
2409 }
2410 };
2411
2412 const char * const SystemZTargetInfo::GCCRegNames[] = {
2413 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2414 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
2415 };
2416
2417 void SystemZTargetInfo::getGCCRegNames(const char * const *&Names,
2418 unsigned &NumNames) const {
2419 Names = GCCRegNames;
2420 NumNames = llvm::array_lengthof(GCCRegNames);
2421 }
2422}
2423
Jakob Stoklund Olesen0de52f92009-08-17 20:08:44 +00002424namespace {
2425 class BlackfinTargetInfo : public TargetInfo {
2426 static const char * const GCCRegNames[];
2427 public:
2428 BlackfinTargetInfo(const std::string& triple) : TargetInfo(triple) {
2429 TLSSupported = false;
2430 DoubleAlign = 32;
2431 LongLongAlign = 32;
2432 LongDoubleAlign = 32;
Chris Lattner5c67237f2009-11-07 18:59:41 +00002433 DescriptionString = "e-p:32:32-i64:32-f64:32-n32";
Jakob Stoklund Olesen0de52f92009-08-17 20:08:44 +00002434 }
2435
2436 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002437 MacroBuilder &Builder) const {
2438 DefineStd(Builder, "bfin", Opts);
2439 DefineStd(Builder, "BFIN", Opts);
2440 Builder.defineMacro("__ADSPBLACKFIN__");
Jakob Stoklund Olesen0de52f92009-08-17 20:08:44 +00002441 // FIXME: This one is really dependent on -mcpu
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002442 Builder.defineMacro("__ADSPLPBLACKFIN__");
Jakob Stoklund Olesen0de52f92009-08-17 20:08:44 +00002443 // FIXME: Add cpu-dependent defines and __SILICON_REVISION__
2444 }
2445
2446 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2447 unsigned &NumRecords) const {
2448 // FIXME: Implement.
2449 Records = 0;
2450 NumRecords = 0;
2451 }
2452
Jakob Stoklund Olesen0de52f92009-08-17 20:08:44 +00002453 virtual void getGCCRegNames(const char * const *&Names,
2454 unsigned &NumNames) const;
2455
2456 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2457 unsigned &NumAliases) const {
2458 // No aliases.
2459 Aliases = 0;
2460 NumAliases = 0;
2461 }
2462
2463 virtual bool validateAsmConstraint(const char *&Name,
2464 TargetInfo::ConstraintInfo &Info) const {
2465 if (strchr("adzDWeABbvfcCtukxywZY", Name[0])) {
2466 Info.setAllowsRegister();
2467 return true;
2468 }
2469 return false;
2470 }
2471
2472 virtual const char *getClobbers() const {
2473 return "";
2474 }
2475
2476 virtual const char *getVAListDeclaration() const {
2477 return "typedef char* __builtin_va_list;";
2478 }
2479 };
2480
2481 const char * const BlackfinTargetInfo::GCCRegNames[] = {
2482 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2483 "p0", "p1", "p2", "p3", "p4", "p5", "sp", "fp",
2484 "i0", "i1", "i2", "i3", "b0", "b1", "b2", "b3",
2485 "l0", "l1", "l2", "l3", "m0", "m1", "m2", "m3",
2486 "a0", "a1", "cc",
2487 "rets", "reti", "retx", "retn", "rete", "astat", "seqstat", "usp",
2488 "argp", "lt0", "lt1", "lc0", "lc1", "lb0", "lb1"
2489 };
2490
2491 void BlackfinTargetInfo::getGCCRegNames(const char * const *&Names,
2492 unsigned &NumNames) const {
2493 Names = GCCRegNames;
2494 NumNames = llvm::array_lengthof(GCCRegNames);
2495 }
2496}
2497
Eli Friedmana9c3d712009-08-19 20:47:07 +00002498namespace {
2499
Mike Stump11289f42009-09-09 15:08:12 +00002500 // LLVM and Clang cannot be used directly to output native binaries for
2501 // target, but is used to compile C code to llvm bitcode with correct
Eli Friedmana9c3d712009-08-19 20:47:07 +00002502 // type and alignment information.
Mike Stump11289f42009-09-09 15:08:12 +00002503 //
2504 // TCE uses the llvm bitcode as input and uses it for generating customized
2505 // target processor and program binary. TCE co-design environment is
Eli Friedmana9c3d712009-08-19 20:47:07 +00002506 // publicly available in http://tce.cs.tut.fi
2507
2508 class TCETargetInfo : public TargetInfo{
2509 public:
2510 TCETargetInfo(const std::string& triple) : TargetInfo(triple) {
2511 TLSSupported = false;
2512 IntWidth = 32;
2513 LongWidth = LongLongWidth = 32;
Eli Friedmana9c3d712009-08-19 20:47:07 +00002514 PointerWidth = 32;
2515 IntAlign = 32;
2516 LongAlign = LongLongAlign = 32;
2517 PointerAlign = 32;
2518 SizeType = UnsignedInt;
2519 IntMaxType = SignedLong;
2520 UIntMaxType = UnsignedLong;
2521 IntPtrType = SignedInt;
2522 PtrDiffType = SignedInt;
2523 FloatWidth = 32;
2524 FloatAlign = 32;
2525 DoubleWidth = 32;
2526 DoubleAlign = 32;
2527 LongDoubleWidth = 32;
2528 LongDoubleAlign = 32;
2529 FloatFormat = &llvm::APFloat::IEEEsingle;
2530 DoubleFormat = &llvm::APFloat::IEEEsingle;
2531 LongDoubleFormat = &llvm::APFloat::IEEEsingle;
Chris Lattner09797542010-03-04 21:07:38 +00002532 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-"
2533 "i16:16:32-i32:32:32-i64:32:32-"
NAKAMURA Takumidba4ed32011-02-18 08:44:38 +00002534 "f32:32:32-f64:32:32-v64:32:32-"
2535 "v128:32:32-a0:0:32-n32";
Eli Friedmana9c3d712009-08-19 20:47:07 +00002536 }
2537
2538 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002539 MacroBuilder &Builder) const {
2540 DefineStd(Builder, "tce", Opts);
2541 Builder.defineMacro("__TCE__");
2542 Builder.defineMacro("__TCE_V1__");
Eli Friedmana9c3d712009-08-19 20:47:07 +00002543 }
2544 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2545 unsigned &NumRecords) const {}
Daniel Dunbar576d90d2009-08-24 09:54:37 +00002546 virtual const char *getClobbers() const {
2547 return "";
2548 }
Eli Friedmana9c3d712009-08-19 20:47:07 +00002549 virtual const char *getVAListDeclaration() const {
2550 return "typedef void* __builtin_va_list;";
2551 }
Eli Friedmana9c3d712009-08-19 20:47:07 +00002552 virtual void getGCCRegNames(const char * const *&Names,
2553 unsigned &NumNames) const {}
2554 virtual bool validateAsmConstraint(const char *&Name,
2555 TargetInfo::ConstraintInfo &info) const {
2556 return true;
2557 }
2558 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2559 unsigned &NumAliases) const {}
2560 };
2561}
2562
Edward O'Callaghane9a58b12009-11-15 10:22:07 +00002563namespace {
2564class MipsTargetInfo : public TargetInfo {
Eric Christopher0b26a612010-03-02 02:41:08 +00002565 std::string ABI, CPU;
Edward O'Callaghane9a58b12009-11-15 10:22:07 +00002566 static const TargetInfo::GCCRegAlias GCCRegAliases[];
2567 static const char * const GCCRegNames[];
2568public:
Eric Christopher0b26a612010-03-02 02:41:08 +00002569 MipsTargetInfo(const std::string& triple) : TargetInfo(triple), ABI("o32") {
Edward O'Callaghane9a58b12009-11-15 10:22:07 +00002570 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
Akira Hatanakab579fe52011-06-02 00:09:17 +00002571 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
2572 SizeType = UnsignedInt;
2573 PtrDiffType = SignedInt;
Edward O'Callaghane9a58b12009-11-15 10:22:07 +00002574 }
Eric Christopher0b26a612010-03-02 02:41:08 +00002575 virtual const char *getABI() const { return ABI.c_str(); }
2576 virtual bool setABI(const std::string &Name) {
2577
2578 if ((Name == "o32") || (Name == "eabi")) {
2579 ABI = Name;
2580 return true;
2581 } else
2582 return false;
2583 }
2584 virtual bool setCPU(const std::string &Name) {
2585 CPU = Name;
2586 return true;
2587 }
2588 void getDefaultFeatures(const std::string &CPU,
2589 llvm::StringMap<bool> &Features) const {
2590 Features[ABI] = true;
2591 Features[CPU] = true;
2592 }
2593 virtual void getArchDefines(const LangOptions &Opts,
2594 MacroBuilder &Builder) const {
2595 if (ABI == "o32")
2596 Builder.defineMacro("__mips_o32");
2597 else if (ABI == "eabi")
2598 Builder.defineMacro("__mips_eabi");
2599 }
Edward O'Callaghane9a58b12009-11-15 10:22:07 +00002600 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002601 MacroBuilder &Builder) const {
2602 DefineStd(Builder, "mips", Opts);
2603 Builder.defineMacro("_mips");
2604 DefineStd(Builder, "MIPSEB", Opts);
2605 Builder.defineMacro("_MIPSEB");
2606 Builder.defineMacro("__REGISTER_PREFIX__", "");
Eric Christopher0b26a612010-03-02 02:41:08 +00002607 getArchDefines(Opts, Builder);
Edward O'Callaghane9a58b12009-11-15 10:22:07 +00002608 }
2609 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2610 unsigned &NumRecords) const {
2611 // FIXME: Implement!
2612 }
2613 virtual const char *getVAListDeclaration() const {
2614 return "typedef void* __builtin_va_list;";
2615 }
2616 virtual void getGCCRegNames(const char * const *&Names,
2617 unsigned &NumNames) const;
2618 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2619 unsigned &NumAliases) const;
2620 virtual bool validateAsmConstraint(const char *&Name,
2621 TargetInfo::ConstraintInfo &Info) const {
2622 switch (*Name) {
2623 default:
2624 case 'r': // CPU registers.
2625 case 'd': // Equivalent to "r" unless generating MIPS16 code.
2626 case 'y': // Equivalent to "r", backwards compatibility only.
2627 case 'f': // floating-point registers.
2628 Info.setAllowsRegister();
2629 return true;
2630 }
2631 return false;
2632 }
2633
2634 virtual const char *getClobbers() const {
2635 // FIXME: Implement!
2636 return "";
2637 }
2638};
2639
2640const char * const MipsTargetInfo::GCCRegNames[] = {
Michael J. Spencer4c0ffa82010-10-21 03:16:25 +00002641 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
Edward O'Callaghane9a58b12009-11-15 10:22:07 +00002642 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
2643 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
2644 "$24", "$25", "$26", "$27", "$28", "$sp", "$fp", "$31",
2645 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
2646 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
2647 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
2648 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
2649 "hi", "lo", "", "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
2650 "$fcc5","$fcc6","$fcc7"
2651};
2652
2653void MipsTargetInfo::getGCCRegNames(const char * const *&Names,
2654 unsigned &NumNames) const {
2655 Names = GCCRegNames;
2656 NumNames = llvm::array_lengthof(GCCRegNames);
2657}
2658
2659const TargetInfo::GCCRegAlias MipsTargetInfo::GCCRegAliases[] = {
2660 { { "at" }, "$1" },
2661 { { "v0" }, "$2" },
2662 { { "v1" }, "$3" },
2663 { { "a0" }, "$4" },
2664 { { "a1" }, "$5" },
2665 { { "a2" }, "$6" },
2666 { { "a3" }, "$7" },
2667 { { "t0" }, "$8" },
2668 { { "t1" }, "$9" },
2669 { { "t2" }, "$10" },
2670 { { "t3" }, "$11" },
2671 { { "t4" }, "$12" },
2672 { { "t5" }, "$13" },
2673 { { "t6" }, "$14" },
2674 { { "t7" }, "$15" },
2675 { { "s0" }, "$16" },
2676 { { "s1" }, "$17" },
2677 { { "s2" }, "$18" },
2678 { { "s3" }, "$19" },
2679 { { "s4" }, "$20" },
2680 { { "s5" }, "$21" },
2681 { { "s6" }, "$22" },
2682 { { "s7" }, "$23" },
2683 { { "t8" }, "$24" },
2684 { { "t9" }, "$25" },
2685 { { "k0" }, "$26" },
2686 { { "k1" }, "$27" },
2687 { { "gp" }, "$28" },
2688 { { "sp" }, "$29" },
2689 { { "fp" }, "$30" },
2690 { { "ra" }, "$31" }
2691};
2692
2693void MipsTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
2694 unsigned &NumAliases) const {
2695 Aliases = GCCRegAliases;
2696 NumAliases = llvm::array_lengthof(GCCRegAliases);
2697}
2698} // end anonymous namespace.
2699
2700namespace {
2701class MipselTargetInfo : public MipsTargetInfo {
2702public:
2703 MipselTargetInfo(const std::string& triple) : MipsTargetInfo(triple) {
2704 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
Akira Hatanakab579fe52011-06-02 00:09:17 +00002705 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
Edward O'Callaghane9a58b12009-11-15 10:22:07 +00002706 }
2707
2708 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002709 MacroBuilder &Builder) const;
Edward O'Callaghane9a58b12009-11-15 10:22:07 +00002710};
2711
2712void MipselTargetInfo::getTargetDefines(const LangOptions &Opts,
Benjamin Kramer2d6fda32010-01-09 17:55:51 +00002713 MacroBuilder &Builder) const {
2714 DefineStd(Builder, "mips", Opts);
2715 Builder.defineMacro("_mips");
2716 DefineStd(Builder, "MIPSEL", Opts);
2717 Builder.defineMacro("_MIPSEL");
2718 Builder.defineMacro("__REGISTER_PREFIX__", "");
Eric Christopher0b26a612010-03-02 02:41:08 +00002719 getArchDefines(Opts, Builder);
Edward O'Callaghane9a58b12009-11-15 10:22:07 +00002720}
2721} // end anonymous namespace.
2722
Chris Lattner5ba61f02006-10-14 07:39:34 +00002723//===----------------------------------------------------------------------===//
2724// Driver code
2725//===----------------------------------------------------------------------===//
2726
Daniel Dunbarb9bbd542009-11-15 06:48:46 +00002727static TargetInfo *AllocateTarget(const std::string &T) {
Daniel Dunbar52322032009-08-18 05:47:58 +00002728 llvm::Triple Triple(T);
2729 llvm::Triple::OSType os = Triple.getOS();
Eli Friedmanb5366062008-05-20 14:21:01 +00002730
Daniel Dunbar52322032009-08-18 05:47:58 +00002731 switch (Triple.getArch()) {
2732 default:
2733 return NULL;
Eli Friedmanb5366062008-05-20 14:21:01 +00002734
Daniel Dunbar52322032009-08-18 05:47:58 +00002735 case llvm::Triple::arm:
Daniel Dunbar33a004e2009-09-11 01:14:50 +00002736 case llvm::Triple::thumb:
Daniel Dunbar14ad22f2011-04-19 21:43:27 +00002737 if (Triple.isOSDarwin())
2738 return new DarwinARMTargetInfo(T);
2739
Daniel Dunbar52322032009-08-18 05:47:58 +00002740 switch (os) {
Rafael Espindolaad8fed52010-06-10 00:46:51 +00002741 case llvm::Triple::Linux:
2742 return new LinuxTargetInfo<ARMTargetInfo>(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002743 case llvm::Triple::FreeBSD:
Torok Edwinb2b37c62009-06-30 17:10:35 +00002744 return new FreeBSDTargetInfo<ARMTargetInfo>(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002745 default:
2746 return new ARMTargetInfo(T);
2747 }
Eli Friedmanb5366062008-05-20 14:21:01 +00002748
Daniel Dunbar52322032009-08-18 05:47:58 +00002749 case llvm::Triple::bfin:
Jakob Stoklund Olesen0de52f92009-08-17 20:08:44 +00002750 return new BlackfinTargetInfo(T);
2751
Daniel Dunbar52322032009-08-18 05:47:58 +00002752 case llvm::Triple::msp430:
2753 return new MSP430TargetInfo(T);
Eli Friedmanb5366062008-05-20 14:21:01 +00002754
Edward O'Callaghane9a58b12009-11-15 10:22:07 +00002755 case llvm::Triple::mips:
2756 if (os == llvm::Triple::Psp)
2757 return new PSPTargetInfo<MipsTargetInfo>(T);
2758 if (os == llvm::Triple::Linux)
2759 return new LinuxTargetInfo<MipsTargetInfo>(T);
2760 return new MipsTargetInfo(T);
2761
2762 case llvm::Triple::mipsel:
2763 if (os == llvm::Triple::Psp)
2764 return new PSPTargetInfo<MipselTargetInfo>(T);
2765 if (os == llvm::Triple::Linux)
2766 return new LinuxTargetInfo<MipselTargetInfo>(T);
2767 return new MipselTargetInfo(T);
2768
Daniel Dunbar52322032009-08-18 05:47:58 +00002769 case llvm::Triple::ppc:
Daniel Dunbar14ad22f2011-04-19 21:43:27 +00002770 if (Triple.isOSDarwin())
Roman Divacky965b0b72011-01-06 08:27:10 +00002771 return new DarwinPPC32TargetInfo(T);
Chris Lattnerdb5c16b2010-02-16 18:14:57 +00002772 else if (os == llvm::Triple::FreeBSD)
2773 return new FreeBSDTargetInfo<PPC32TargetInfo>(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002774 return new PPC32TargetInfo(T);
2775
2776 case llvm::Triple::ppc64:
Daniel Dunbar14ad22f2011-04-19 21:43:27 +00002777 if (Triple.isOSDarwin())
Daniel Dunbar0e15c9a2010-05-30 00:07:30 +00002778 return new DarwinPPC64TargetInfo(T);
John Thompsone467e192009-11-19 17:18:50 +00002779 else if (os == llvm::Triple::Lv2)
2780 return new PS3PPUTargetInfo<PPC64TargetInfo>(T);
Chris Lattnerdb5c16b2010-02-16 18:14:57 +00002781 else if (os == llvm::Triple::FreeBSD)
2782 return new FreeBSDTargetInfo<PPC64TargetInfo>(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002783 return new PPC64TargetInfo(T);
2784
Justin Holewinski514cce82011-04-20 19:34:15 +00002785 case llvm::Triple::ptx32:
2786 return new PTX32TargetInfo(T);
2787 case llvm::Triple::ptx64:
2788 return new PTX64TargetInfo(T);
2789
Chris Lattner5178f562010-03-06 21:21:27 +00002790 case llvm::Triple::mblaze:
2791 return new MBlazeTargetInfo(T);
2792
Daniel Dunbar52322032009-08-18 05:47:58 +00002793 case llvm::Triple::sparc:
Edward O'Callaghan9dda8e982009-10-18 13:33:59 +00002794 if (os == llvm::Triple::AuroraUX)
2795 return new AuroraUXSparcV8TargetInfo(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002796 if (os == llvm::Triple::Solaris)
2797 return new SolarisSparcV8TargetInfo(T);
2798 return new SparcV8TargetInfo(T);
2799
John Thompsone467e192009-11-19 17:18:50 +00002800 // FIXME: Need a real SPU target.
2801 case llvm::Triple::cellspu:
2802 return new PS3SPUTargetInfo<PPC64TargetInfo>(T);
2803
Daniel Dunbar52322032009-08-18 05:47:58 +00002804 case llvm::Triple::systemz:
2805 return new SystemZTargetInfo(T);
2806
Eli Friedmana9c3d712009-08-19 20:47:07 +00002807 case llvm::Triple::tce:
2808 return new TCETargetInfo(T);
2809
Daniel Dunbar52322032009-08-18 05:47:58 +00002810 case llvm::Triple::x86:
Daniel Dunbar14ad22f2011-04-19 21:43:27 +00002811 if (Triple.isOSDarwin())
2812 return new DarwinI386TargetInfo(T);
2813
Daniel Dunbar52322032009-08-18 05:47:58 +00002814 switch (os) {
Edward O'Callaghan9dda8e982009-10-18 13:33:59 +00002815 case llvm::Triple::AuroraUX:
2816 return new AuroraUXTargetInfo<X86_32TargetInfo>(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002817 case llvm::Triple::Linux:
2818 return new LinuxTargetInfo<X86_32TargetInfo>(T);
2819 case llvm::Triple::DragonFly:
2820 return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(T);
2821 case llvm::Triple::NetBSD:
2822 return new NetBSDTargetInfo<X86_32TargetInfo>(T);
2823 case llvm::Triple::OpenBSD:
2824 return new OpenBSDI386TargetInfo(T);
2825 case llvm::Triple::FreeBSD:
2826 return new FreeBSDTargetInfo<X86_32TargetInfo>(T);
Chris Lattner3e2ee142010-07-07 16:01:42 +00002827 case llvm::Triple::Minix:
2828 return new MinixTargetInfo<X86_32TargetInfo>(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002829 case llvm::Triple::Solaris:
2830 return new SolarisTargetInfo<X86_32TargetInfo>(T);
2831 case llvm::Triple::Cygwin:
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00002832 return new CygwinX86_32TargetInfo(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002833 case llvm::Triple::MinGW32:
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00002834 return new MinGWX86_32TargetInfo(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002835 case llvm::Triple::Win32:
Michael J. Spencer54bf3c32010-10-21 08:22:51 +00002836 return new VisualStudioWindowsX86_32TargetInfo(T);
Chris Lattnerb986aba2010-04-11 19:29:39 +00002837 case llvm::Triple::Haiku:
2838 return new HaikuX86_32TargetInfo(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002839 default:
2840 return new X86_32TargetInfo(T);
2841 }
2842
2843 case llvm::Triple::x86_64:
Daniel Dunbar14ad22f2011-04-19 21:43:27 +00002844 if (Triple.isOSDarwin() || Triple.getEnvironment() == llvm::Triple::MachO)
2845 return new DarwinX86_64TargetInfo(T);
2846
Daniel Dunbar52322032009-08-18 05:47:58 +00002847 switch (os) {
Edward O'Callaghan9dda8e982009-10-18 13:33:59 +00002848 case llvm::Triple::AuroraUX:
2849 return new AuroraUXTargetInfo<X86_64TargetInfo>(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002850 case llvm::Triple::Linux:
2851 return new LinuxTargetInfo<X86_64TargetInfo>(T);
Chris Lattner002ba6b2010-01-09 05:41:14 +00002852 case llvm::Triple::DragonFly:
2853 return new DragonFlyBSDTargetInfo<X86_64TargetInfo>(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002854 case llvm::Triple::NetBSD:
2855 return new NetBSDTargetInfo<X86_64TargetInfo>(T);
2856 case llvm::Triple::OpenBSD:
2857 return new OpenBSDX86_64TargetInfo(T);
2858 case llvm::Triple::FreeBSD:
2859 return new FreeBSDTargetInfo<X86_64TargetInfo>(T);
2860 case llvm::Triple::Solaris:
2861 return new SolarisTargetInfo<X86_64TargetInfo>(T);
NAKAMURA Takumi31ea2f12011-02-17 08:51:38 +00002862 case llvm::Triple::MinGW32:
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00002863 return new MinGWX86_64TargetInfo(T);
2864 case llvm::Triple::Win32: // This is what Triple.h supports now.
Daniel Dunbar14ad22f2011-04-19 21:43:27 +00002865 return new VisualStudioWindowsX86_64TargetInfo(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002866 default:
2867 return new X86_64TargetInfo(T);
2868 }
2869 }
Chris Lattner5ba61f02006-10-14 07:39:34 +00002870}
Daniel Dunbarb9bbd542009-11-15 06:48:46 +00002871
2872/// CreateTargetInfo - Return the target info object for the specified target
2873/// triple.
2874TargetInfo *TargetInfo::CreateTargetInfo(Diagnostic &Diags,
Daniel Dunbar7b245ed2009-12-19 03:30:57 +00002875 TargetOptions &Opts) {
Daniel Dunbarb9bbd542009-11-15 06:48:46 +00002876 llvm::Triple Triple(Opts.Triple);
2877
2878 // Construct the target
2879 llvm::OwningPtr<TargetInfo> Target(AllocateTarget(Triple.str()));
2880 if (!Target) {
2881 Diags.Report(diag::err_target_unknown_triple) << Triple.str();
2882 return 0;
2883 }
2884
Daniel Dunbaracde99e2009-12-18 18:42:37 +00002885 // Set the target CPU if specified.
2886 if (!Opts.CPU.empty() && !Target->setCPU(Opts.CPU)) {
2887 Diags.Report(diag::err_target_unknown_cpu) << Opts.CPU;
2888 return 0;
2889 }
2890
Daniel Dunbarb9bbd542009-11-15 06:48:46 +00002891 // Set the target ABI if specified.
2892 if (!Opts.ABI.empty() && !Target->setABI(Opts.ABI)) {
2893 Diags.Report(diag::err_target_unknown_abi) << Opts.ABI;
2894 return 0;
2895 }
2896
Charles Davis95a546e2010-06-11 01:06:47 +00002897 // Set the target C++ ABI.
John McCall86353412010-08-21 22:46:04 +00002898 if (!Opts.CXXABI.empty() && !Target->setCXXABI(Opts.CXXABI)) {
Charles Davis95a546e2010-06-11 01:06:47 +00002899 Diags.Report(diag::err_target_unknown_cxxabi) << Opts.CXXABI;
2900 return 0;
2901 }
2902
Daniel Dunbarb9bbd542009-11-15 06:48:46 +00002903 // Compute the default target features, we need the target to handle this
2904 // because features may have dependencies on one another.
2905 llvm::StringMap<bool> Features;
2906 Target->getDefaultFeatures(Opts.CPU, Features);
2907
2908 // Apply the user specified deltas.
2909 for (std::vector<std::string>::const_iterator it = Opts.Features.begin(),
2910 ie = Opts.Features.end(); it != ie; ++it) {
2911 const char *Name = it->c_str();
2912
2913 // Apply the feature via the target.
2914 if ((Name[0] != '-' && Name[0] != '+') ||
2915 !Target->setFeatureEnabled(Features, Name + 1, (Name[0] == '+'))) {
2916 Diags.Report(diag::err_target_invalid_feature) << Name;
2917 return 0;
2918 }
2919 }
2920
2921 // Add the features to the compile options.
2922 //
2923 // FIXME: If we are completely confident that we have the right set, we only
2924 // need to pass the minuses.
Daniel Dunbar7b245ed2009-12-19 03:30:57 +00002925 Opts.Features.clear();
Daniel Dunbarb9bbd542009-11-15 06:48:46 +00002926 for (llvm::StringMap<bool>::const_iterator it = Features.begin(),
2927 ie = Features.end(); it != ie; ++it)
Daniel Dunbar7b245ed2009-12-19 03:30:57 +00002928 Opts.Features.push_back(std::string(it->second ? "+" : "-") + it->first());
2929 Target->HandleTargetFeatures(Opts.Features);
Daniel Dunbarb9bbd542009-11-15 06:48:46 +00002930
2931 return Target.take();
2932}