blob: 8479be9397bc1c8efd41a943cb4e30672931a3d8 [file] [log] [blame]
Reid Spencer5f016e22007-07-11 17:01:13 +00001//===--- Targets.cpp - Implement -arch option and targets -----------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner0bc735f2007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Reid Spencer5f016e22007-07-11 17:01:13 +00007//
8//===----------------------------------------------------------------------===//
9//
Anton Korobeynikova7c47172009-05-03 13:42:53 +000010// This file implements construction of a TargetInfo object from a
Ted Kremenekbbced582007-12-12 18:05:32 +000011// target triple.
Reid Spencer5f016e22007-07-11 17:01:13 +000012//
13//===----------------------------------------------------------------------===//
14
Reid Spencer5f016e22007-07-11 17:01:13 +000015#include "clang/Basic/TargetInfo.h"
Daniel Dunbard58c03f2009-11-15 06:48:46 +000016#include "clang/Basic/Builtins.h"
17#include "clang/Basic/Diagnostic.h"
Chris Lattner8fc4dfb2008-12-04 22:54:33 +000018#include "clang/Basic/LangOptions.h"
Chandler Carruth103b71c2010-01-20 06:13:02 +000019#include "clang/Basic/MacroBuilder.h"
Daniel Dunbard58c03f2009-11-15 06:48:46 +000020#include "clang/Basic/TargetBuiltins.h"
21#include "clang/Basic/TargetOptions.h"
Eli Friedman25531262008-05-20 14:27:34 +000022#include "llvm/ADT/APFloat.h"
Daniel Dunbard58c03f2009-11-15 06:48:46 +000023#include "llvm/ADT/OwningPtr.h"
Daniel Dunbar29a790b2009-11-11 09:38:56 +000024#include "llvm/ADT/STLExtras.h"
Daniel Dunbar77659342009-08-19 20:04:03 +000025#include "llvm/ADT/StringRef.h"
Daniel Dunbar29a790b2009-11-11 09:38:56 +000026#include "llvm/ADT/StringSwitch.h"
Chris Lattner4c28b1c2009-08-12 06:24:27 +000027#include "llvm/ADT/Triple.h"
Chris Lattner797c3c42009-08-10 19:03:04 +000028#include "llvm/MC/MCSectionMachO.h"
Dale Johannesen1e592cb2010-10-29 23:24:33 +000029#include "llvm/Type.h"
Benjamin Kramer48725082010-01-09 18:20:57 +000030#include <algorithm>
Reid Spencer5f016e22007-07-11 17:01:13 +000031using namespace clang;
32
Reid Spencer5f016e22007-07-11 17:01:13 +000033//===----------------------------------------------------------------------===//
34// Common code shared among targets.
35//===----------------------------------------------------------------------===//
36
Chris Lattnerca45cff2009-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 Kramera9992772010-01-09 17:55:51 +000040static void DefineStd(MacroBuilder &Builder, llvm::StringRef MacroName,
Chris Lattnerca45cff2009-03-20 16:06:38 +000041 const LangOptions &Opts) {
42 assert(MacroName[0] != '_' && "Identifier should be in the user's namespace");
Anton Korobeynikova7c47172009-05-03 13:42:53 +000043
Chris Lattnerca45cff2009-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 Kramera9992772010-01-09 17:55:51 +000047 Builder.defineMacro(MacroName);
Anton Korobeynikova7c47172009-05-03 13:42:53 +000048
Chris Lattnerca45cff2009-03-20 16:06:38 +000049 // Define __unix.
Benjamin Kramera9992772010-01-09 17:55:51 +000050 Builder.defineMacro("__" + MacroName);
Anton Korobeynikova7c47172009-05-03 13:42:53 +000051
Chris Lattnerca45cff2009-03-20 16:06:38 +000052 // Define __unix__.
Benjamin Kramera9992772010-01-09 17:55:51 +000053 Builder.defineMacro("__" + MacroName + "__");
Chris Lattnerca45cff2009-03-20 16:06:38 +000054}
55
Chris Lattnerd29b6302008-10-05 21:50:58 +000056//===----------------------------------------------------------------------===//
57// Defines specific to certain operating systems.
58//===----------------------------------------------------------------------===//
Chris Lattner797c3c42009-08-10 19:03:04 +000059
Torok Edwin5f6c1942009-06-30 17:10:35 +000060namespace {
Douglas Gregora3844922009-07-01 15:12:53 +000061template<typename TgtInfo>
62class OSTargetInfo : public TgtInfo {
Torok Edwin5f6c1942009-06-30 17:10:35 +000063protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +000064 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +000065 MacroBuilder &Builder) const=0;
Torok Edwin5f6c1942009-06-30 17:10:35 +000066public:
Douglas Gregora3844922009-07-01 15:12:53 +000067 OSTargetInfo(const std::string& triple) : TgtInfo(triple) {}
Torok Edwin5f6c1942009-06-30 17:10:35 +000068 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +000069 MacroBuilder &Builder) const {
70 TgtInfo::getTargetDefines(Opts, Builder);
71 getOSDefines(Opts, TgtInfo::getTriple(), Builder);
Torok Edwinb0a5b242009-06-30 17:00:25 +000072 }
Torok Edwin5f6c1942009-06-30 17:10:35 +000073
74};
Chris Lattner4c28b1c2009-08-12 06:24:27 +000075} // end anonymous namespace
Torok Edwinb0a5b242009-06-30 17:00:25 +000076
Chris Lattner797c3c42009-08-10 19:03:04 +000077
Daniel Dunbar21ae3192010-01-26 01:44:04 +000078static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
Douglas Gregor0a0d2b12011-03-23 00:50:03 +000079 const llvm::Triple &Triple,
80 llvm::StringRef &PlatformName,
81 VersionTuple &PlatformMinVersion) {
Benjamin Kramera9992772010-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 Korobeynikova7c47172009-05-03 13:42:53 +000086
John McCall098df7f2011-06-16 00:03:19 +000087 if (!Opts.ObjCAutoRefCount) {
John McCallf85e1932011-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 Korobeynikova7c47172009-05-03 13:42:53 +000090
John McCallf85e1932011-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", "");
John McCall18164422011-06-17 21:23:37 +0000107 Builder.defineMacro("__bridge_retain", "");
John McCallf85e1932011-06-15 23:02:42 +0000108 }
109
Eli Friedman2de4fee2009-06-04 23:00:29 +0000110 if (Opts.Static)
Benjamin Kramera9992772010-01-09 17:55:51 +0000111 Builder.defineMacro("__STATIC__");
Eli Friedman2de4fee2009-06-04 23:00:29 +0000112 else
Benjamin Kramera9992772010-01-09 17:55:51 +0000113 Builder.defineMacro("__DYNAMIC__");
Daniel Dunbar5345c392009-09-03 04:54:28 +0000114
115 if (Opts.POSIXThreads)
Benjamin Kramera9992772010-01-09 17:55:51 +0000116 Builder.defineMacro("_REENTRANT");
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000117
Daniel Dunbar0d027ba2011-04-19 21:40:34 +0000118 // Get the platform type and version number from the triple.
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000119 unsigned Maj, Min, Rev;
Mike Stump1eb44332009-09-09 15:08:12 +0000120
Daniel Dunbar21ae3192010-01-26 01:44:04 +0000121 // If no version was given, default to to 10.4.0, for simplifying tests.
Daniel Dunbar0d027ba2011-04-19 21:40:34 +0000122 if (Triple.getOSName() == "darwin" || Triple.getOSName() == "osx") {
123 PlatformName = "macosx";
Daniel Dunbar21ae3192010-01-26 01:44:04 +0000124 Min = Rev = 0;
125 Maj = 8;
Daniel Dunbar0d027ba2011-04-19 21:40:34 +0000126 } else {
127 // Otherwise, honor all three triple forms ("-darwinNNN[-iphoneos]",
128 // "-osxNNN", and "-iosNNN").
129
130 if (Triple.getOS() == llvm::Triple::Darwin) {
131 // For historical reasons that make little sense, the version passed here
132 // is the "darwin" version, which drops the 10 and offsets by 4.
133 Triple.getOSVersion(Maj, Min, Rev);
134
135 if (Triple.getEnvironmentName() == "iphoneos") {
136 PlatformName = "ios";
137 } else {
Daniel Dunbar0d027ba2011-04-19 21:40:34 +0000138 PlatformName = "macosx";
139 Rev = Min;
140 Min = Maj - 4;
141 Maj = 10;
142 }
Daniel Dunbar0d027ba2011-04-19 21:40:34 +0000143 } else {
Daniel Dunbar0d027ba2011-04-19 21:40:34 +0000144 Triple.getOSVersion(Maj, Min, Rev);
Daniel Dunbara4ff6482011-04-19 23:34:21 +0000145 PlatformName = llvm::Triple::getOSTypeName(Triple.getOS());
Daniel Dunbar0d027ba2011-04-19 21:40:34 +0000146 }
147 }
Daniel Dunbar21ae3192010-01-26 01:44:04 +0000148
149 // Set the appropriate OS version define.
Daniel Dunbar0d027ba2011-04-19 21:40:34 +0000150 if (PlatformName == "ios") {
Daniel Dunbar8a3a7f32011-04-21 21:27:33 +0000151 assert(Maj < 10 && Min < 100 && Rev < 100 && "Invalid version!");
Daniel Dunbar21ae3192010-01-26 01:44:04 +0000152 char Str[6];
153 Str[0] = '0' + Maj;
154 Str[1] = '0' + (Min / 10);
155 Str[2] = '0' + (Min % 10);
156 Str[3] = '0' + (Rev / 10);
157 Str[4] = '0' + (Rev % 10);
158 Str[5] = '\0';
159 Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", Str);
160 } else {
Daniel Dunbar8a3a7f32011-04-21 21:27:33 +0000161 // Note that the Driver allows versions which aren't representable in the
162 // define (because we only get a single digit for the minor and micro
163 // revision numbers). So, we limit them to the maximum representable
164 // version.
Daniel Dunbar21ae3192010-01-26 01:44:04 +0000165 assert(Triple.getEnvironmentName().empty() && "Invalid environment!");
Daniel Dunbar8a3a7f32011-04-21 21:27:33 +0000166 assert(Maj < 100 && Min < 100 && Rev < 100 && "Invalid version!");
Daniel Dunbar21ae3192010-01-26 01:44:04 +0000167 char Str[5];
168 Str[0] = '0' + (Maj / 10);
169 Str[1] = '0' + (Maj % 10);
Daniel Dunbar8a3a7f32011-04-21 21:27:33 +0000170 Str[2] = '0' + std::min(Min, 9U);
171 Str[3] = '0' + std::min(Rev, 9U);
Daniel Dunbar21ae3192010-01-26 01:44:04 +0000172 Str[4] = '\0';
173 Builder.defineMacro("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", Str);
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000174 }
Daniel Dunbar0d027ba2011-04-19 21:40:34 +0000175
176 PlatformMinVersion = VersionTuple(Maj, Min, Rev);
Eli Friedman618234a2008-08-20 02:34:37 +0000177}
Reid Spencer5f016e22007-07-11 17:01:13 +0000178
Chris Lattner797c3c42009-08-10 19:03:04 +0000179namespace {
Torok Edwin5f6c1942009-06-30 17:10:35 +0000180template<typename Target>
181class DarwinTargetInfo : public OSTargetInfo<Target> {
182protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000183 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000184 MacroBuilder &Builder) const {
Douglas Gregor0a0d2b12011-03-23 00:50:03 +0000185 getDarwinDefines(Builder, Opts, Triple, this->PlatformName,
186 this->PlatformMinVersion);
Torok Edwin5f6c1942009-06-30 17:10:35 +0000187 }
Mike Stump1eb44332009-09-09 15:08:12 +0000188
Torok Edwin5f6c1942009-06-30 17:10:35 +0000189public:
190 DarwinTargetInfo(const std::string& triple) :
191 OSTargetInfo<Target>(triple) {
Eric Christopheraa7333c2011-07-02 00:20:22 +0000192 llvm::Triple T = llvm::Triple(triple);
193 this->TLSSupported = T.isMacOSX() && !T.isMacOSXVersionLT(10,7);
Daniel Dunbare177d3b2011-02-21 23:12:51 +0000194 this->MCountName = "\01mcount";
Torok Edwin5f6c1942009-06-30 17:10:35 +0000195 }
196
Anders Carlssonf959fb52010-01-30 18:33:31 +0000197 virtual std::string isValidSectionSpecifier(llvm::StringRef SR) const {
Chris Lattner797c3c42009-08-10 19:03:04 +0000198 // Let MCSectionMachO validate this.
199 llvm::StringRef Segment, Section;
200 unsigned TAA, StubSize;
Daniel Dunbar9ae186f2011-03-19 02:06:21 +0000201 bool HasTAA;
Chris Lattner797c3c42009-08-10 19:03:04 +0000202 return llvm::MCSectionMachO::ParseSectionSpecifier(SR, Segment, Section,
Daniel Dunbar9ae186f2011-03-19 02:06:21 +0000203 TAA, HasTAA, StubSize);
Chris Lattner797c3c42009-08-10 19:03:04 +0000204 }
Michael J. Spencer20249a12010-10-21 03:16:25 +0000205
Anders Carlsson18af3682010-06-08 22:47:50 +0000206 virtual const char *getStaticInitSectionSpecifier() const {
207 // FIXME: We should return 0 when building kexts.
208 return "__TEXT,__StaticInit,regular,pure_instructions";
209 }
Michael J. Spencer20249a12010-10-21 03:16:25 +0000210
Torok Edwin5f6c1942009-06-30 17:10:35 +0000211};
212
Chris Lattner797c3c42009-08-10 19:03:04 +0000213
Torok Edwin5f6c1942009-06-30 17:10:35 +0000214// DragonFlyBSD Target
215template<typename Target>
216class DragonFlyBSDTargetInfo : public OSTargetInfo<Target> {
217protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000218 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000219 MacroBuilder &Builder) const {
Torok Edwin5f6c1942009-06-30 17:10:35 +0000220 // DragonFly defines; list based off of gcc output
Benjamin Kramera9992772010-01-09 17:55:51 +0000221 Builder.defineMacro("__DragonFly__");
222 Builder.defineMacro("__DragonFly_cc_version", "100001");
223 Builder.defineMacro("__ELF__");
224 Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
225 Builder.defineMacro("__tune_i386__");
226 DefineStd(Builder, "unix", Opts);
Torok Edwin5f6c1942009-06-30 17:10:35 +0000227 }
228public:
Mike Stump1eb44332009-09-09 15:08:12 +0000229 DragonFlyBSDTargetInfo(const std::string &triple)
Torok Edwin5f6c1942009-06-30 17:10:35 +0000230 : OSTargetInfo<Target>(triple) {}
231};
232
233// FreeBSD Target
234template<typename Target>
235class FreeBSDTargetInfo : public OSTargetInfo<Target> {
236protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000237 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000238 MacroBuilder &Builder) const {
Torok Edwin5f6c1942009-06-30 17:10:35 +0000239 // FreeBSD defines; list based off of gcc output
240
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000241 // FIXME: Move version number handling to llvm::Triple.
Benjamin Kramer3bb65302010-01-30 19:55:01 +0000242 llvm::StringRef Release = Triple.getOSName().substr(strlen("freebsd"), 1);
Torok Edwin5f6c1942009-06-30 17:10:35 +0000243
Benjamin Kramer3bb65302010-01-30 19:55:01 +0000244 Builder.defineMacro("__FreeBSD__", Release);
245 Builder.defineMacro("__FreeBSD_cc_version", Release + "00001");
Benjamin Kramera9992772010-01-09 17:55:51 +0000246 Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
247 DefineStd(Builder, "unix", Opts);
248 Builder.defineMacro("__ELF__");
Torok Edwin5f6c1942009-06-30 17:10:35 +0000249 }
250public:
Mike Stump1eb44332009-09-09 15:08:12 +0000251 FreeBSDTargetInfo(const std::string &triple)
Duncan Sands1e90faf2009-07-08 13:55:08 +0000252 : OSTargetInfo<Target>(triple) {
253 this->UserLabelPrefix = "";
Roman Divackybe4c8702011-02-10 16:52:03 +0000254
255 llvm::Triple Triple(triple);
256 switch (Triple.getArch()) {
257 default:
258 case llvm::Triple::x86:
259 case llvm::Triple::x86_64:
260 this->MCountName = ".mcount";
261 break;
262 case llvm::Triple::mips:
263 case llvm::Triple::mipsel:
264 case llvm::Triple::ppc:
265 case llvm::Triple::ppc64:
266 this->MCountName = "_mcount";
267 break;
268 case llvm::Triple::arm:
269 this->MCountName = "__mcount";
270 break;
271 }
272
Duncan Sands1e90faf2009-07-08 13:55:08 +0000273 }
Torok Edwin5f6c1942009-06-30 17:10:35 +0000274};
275
Chris Lattner38e317d2010-07-07 16:01:42 +0000276// Minix Target
277template<typename Target>
278class MinixTargetInfo : public OSTargetInfo<Target> {
279protected:
280 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
281 MacroBuilder &Builder) const {
282 // Minix defines
283
284 Builder.defineMacro("__minix", "3");
285 Builder.defineMacro("_EM_WSIZE", "4");
286 Builder.defineMacro("_EM_PSIZE", "4");
287 Builder.defineMacro("_EM_SSIZE", "2");
288 Builder.defineMacro("_EM_LSIZE", "4");
289 Builder.defineMacro("_EM_FSIZE", "4");
290 Builder.defineMacro("_EM_DSIZE", "8");
291 DefineStd(Builder, "unix", Opts);
292 }
293public:
294 MinixTargetInfo(const std::string &triple)
295 : OSTargetInfo<Target>(triple) {
296 this->UserLabelPrefix = "";
297 }
298};
299
Torok Edwin5f6c1942009-06-30 17:10:35 +0000300// Linux target
301template<typename Target>
302class LinuxTargetInfo : public OSTargetInfo<Target> {
303protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000304 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000305 MacroBuilder &Builder) const {
Torok Edwin5f6c1942009-06-30 17:10:35 +0000306 // Linux defines; list based off of gcc output
Benjamin Kramera9992772010-01-09 17:55:51 +0000307 DefineStd(Builder, "unix", Opts);
308 DefineStd(Builder, "linux", Opts);
309 Builder.defineMacro("__gnu_linux__");
310 Builder.defineMacro("__ELF__");
Daniel Dunbar5345c392009-09-03 04:54:28 +0000311 if (Opts.POSIXThreads)
Benjamin Kramera9992772010-01-09 17:55:51 +0000312 Builder.defineMacro("_REENTRANT");
Douglas Gregor2b003fd2010-04-21 05:52:38 +0000313 if (Opts.CPlusPlus)
314 Builder.defineMacro("_GNU_SOURCE");
Torok Edwin5f6c1942009-06-30 17:10:35 +0000315 }
316public:
Mike Stump1eb44332009-09-09 15:08:12 +0000317 LinuxTargetInfo(const std::string& triple)
Torok Edwin5f6c1942009-06-30 17:10:35 +0000318 : OSTargetInfo<Target>(triple) {
319 this->UserLabelPrefix = "";
Douglas Gregor12e84642011-01-12 21:19:25 +0000320 this->WIntType = TargetInfo::UnsignedInt;
Torok Edwin5f6c1942009-06-30 17:10:35 +0000321 }
322};
323
Chris Lattnerb62bb282009-07-13 20:29:08 +0000324// NetBSD Target
325template<typename Target>
326class NetBSDTargetInfo : public OSTargetInfo<Target> {
327protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000328 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000329 MacroBuilder &Builder) const {
Chris Lattnerb62bb282009-07-13 20:29:08 +0000330 // NetBSD defines; list based off of gcc output
Benjamin Kramera9992772010-01-09 17:55:51 +0000331 Builder.defineMacro("__NetBSD__");
332 Builder.defineMacro("__unix__");
333 Builder.defineMacro("__ELF__");
Daniel Dunbar5345c392009-09-03 04:54:28 +0000334 if (Opts.POSIXThreads)
Benjamin Kramera9992772010-01-09 17:55:51 +0000335 Builder.defineMacro("_POSIX_THREADS");
Chris Lattnerb62bb282009-07-13 20:29:08 +0000336 }
337public:
Mike Stump1eb44332009-09-09 15:08:12 +0000338 NetBSDTargetInfo(const std::string &triple)
Chris Lattnerb62bb282009-07-13 20:29:08 +0000339 : OSTargetInfo<Target>(triple) {
340 this->UserLabelPrefix = "";
341 }
342};
343
Torok Edwin5f6c1942009-06-30 17:10:35 +0000344// OpenBSD Target
345template<typename Target>
346class OpenBSDTargetInfo : public OSTargetInfo<Target> {
347protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000348 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000349 MacroBuilder &Builder) const {
Torok Edwin5f6c1942009-06-30 17:10:35 +0000350 // OpenBSD defines; list based off of gcc output
351
Benjamin Kramera9992772010-01-09 17:55:51 +0000352 Builder.defineMacro("__OpenBSD__");
353 DefineStd(Builder, "unix", Opts);
354 Builder.defineMacro("__ELF__");
Daniel Dunbar5345c392009-09-03 04:54:28 +0000355 if (Opts.POSIXThreads)
Benjamin Kramera9992772010-01-09 17:55:51 +0000356 Builder.defineMacro("_POSIX_THREADS");
Torok Edwin5f6c1942009-06-30 17:10:35 +0000357 }
358public:
Mike Stump1eb44332009-09-09 15:08:12 +0000359 OpenBSDTargetInfo(const std::string &triple)
Torok Edwin5f6c1942009-06-30 17:10:35 +0000360 : OSTargetInfo<Target>(triple) {}
361};
362
Edward O'Callaghan84423a82009-11-15 10:22:07 +0000363// PSP Target
364template<typename Target>
365class PSPTargetInfo : public OSTargetInfo<Target> {
366protected:
367 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000368 MacroBuilder &Builder) const {
Edward O'Callaghan84423a82009-11-15 10:22:07 +0000369 // PSP defines; list based on the output of the pspdev gcc toolchain.
Benjamin Kramera9992772010-01-09 17:55:51 +0000370 Builder.defineMacro("PSP");
371 Builder.defineMacro("_PSP");
372 Builder.defineMacro("__psp__");
373 Builder.defineMacro("__ELF__");
Edward O'Callaghan84423a82009-11-15 10:22:07 +0000374 }
375public:
376 PSPTargetInfo(const std::string& triple)
377 : OSTargetInfo<Target>(triple) {
378 this->UserLabelPrefix = "";
379 }
380};
381
John Thompson3f6918a2009-11-19 17:18:50 +0000382// PS3 PPU Target
383template<typename Target>
384class PS3PPUTargetInfo : public OSTargetInfo<Target> {
385protected:
386 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000387 MacroBuilder &Builder) const {
John Thompson3f6918a2009-11-19 17:18:50 +0000388 // PS3 PPU defines.
John Thompsonfb457972010-03-25 16:18:32 +0000389 Builder.defineMacro("__PPC__");
Benjamin Kramera9992772010-01-09 17:55:51 +0000390 Builder.defineMacro("__PPU__");
391 Builder.defineMacro("__CELLOS_LV2__");
392 Builder.defineMacro("__ELF__");
393 Builder.defineMacro("__LP32__");
John Thompson8e6065a2010-06-24 22:44:13 +0000394 Builder.defineMacro("_ARCH_PPC64");
395 Builder.defineMacro("__powerpc64__");
John Thompson3f6918a2009-11-19 17:18:50 +0000396 }
397public:
398 PS3PPUTargetInfo(const std::string& triple)
399 : OSTargetInfo<Target>(triple) {
400 this->UserLabelPrefix = "";
John Thompsonec387af2009-12-18 14:21:08 +0000401 this->LongWidth = this->LongAlign = this->PointerWidth = this->PointerAlign = 32;
John Thompson8e6065a2010-06-24 22:44:13 +0000402 this->IntMaxType = TargetInfo::SignedLongLong;
403 this->UIntMaxType = TargetInfo::UnsignedLongLong;
404 this->Int64Type = TargetInfo::SignedLongLong;
John Thompsonec387af2009-12-18 14:21:08 +0000405 this->SizeType = TargetInfo::UnsignedInt;
John Thompson8e6065a2010-06-24 22:44:13 +0000406 this->DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
407 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";
John Thompson3f6918a2009-11-19 17:18:50 +0000408 }
409};
410
411// FIXME: Need a real SPU target.
412// PS3 SPU Target
413template<typename Target>
414class PS3SPUTargetInfo : public OSTargetInfo<Target> {
415protected:
416 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000417 MacroBuilder &Builder) const {
John Thompson3f6918a2009-11-19 17:18:50 +0000418 // PS3 PPU defines.
Benjamin Kramera9992772010-01-09 17:55:51 +0000419 Builder.defineMacro("__SPU__");
420 Builder.defineMacro("__ELF__");
John Thompson3f6918a2009-11-19 17:18:50 +0000421 }
422public:
423 PS3SPUTargetInfo(const std::string& triple)
424 : OSTargetInfo<Target>(triple) {
425 this->UserLabelPrefix = "";
426 }
427};
428
Edward O'Callaghan991f9a72009-10-18 13:33:59 +0000429// AuroraUX target
430template<typename Target>
431class AuroraUXTargetInfo : public OSTargetInfo<Target> {
432protected:
433 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000434 MacroBuilder &Builder) const {
435 DefineStd(Builder, "sun", Opts);
436 DefineStd(Builder, "unix", Opts);
437 Builder.defineMacro("__ELF__");
438 Builder.defineMacro("__svr4__");
439 Builder.defineMacro("__SVR4");
Edward O'Callaghan991f9a72009-10-18 13:33:59 +0000440 }
441public:
442 AuroraUXTargetInfo(const std::string& triple)
443 : OSTargetInfo<Target>(triple) {
444 this->UserLabelPrefix = "";
445 this->WCharType = this->SignedLong;
446 // FIXME: WIntType should be SignedLong
447 }
448};
449
Torok Edwin5f6c1942009-06-30 17:10:35 +0000450// Solaris target
451template<typename Target>
452class SolarisTargetInfo : public OSTargetInfo<Target> {
453protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +0000454 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +0000455 MacroBuilder &Builder) const {
456 DefineStd(Builder, "sun", Opts);
457 DefineStd(Builder, "unix", Opts);
458 Builder.defineMacro("__ELF__");
459 Builder.defineMacro("__svr4__");
460 Builder.defineMacro("__SVR4");
Torok Edwin5f6c1942009-06-30 17:10:35 +0000461 }
462public:
Mike Stump1eb44332009-09-09 15:08:12 +0000463 SolarisTargetInfo(const std::string& triple)
Torok Edwin5f6c1942009-06-30 17:10:35 +0000464 : OSTargetInfo<Target>(triple) {
465 this->UserLabelPrefix = "";
466 this->WCharType = this->SignedLong;
467 // FIXME: WIntType should be SignedLong
468 }
469};
Michael J. Spencerdae4ac42010-10-21 05:21:48 +0000470
471// Windows target
472template<typename Target>
473class WindowsTargetInfo : public OSTargetInfo<Target> {
474protected:
475 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
476 MacroBuilder &Builder) const {
Michael J. Spencera764e832010-10-21 08:22:51 +0000477 Builder.defineMacro("_WIN32");
478 }
479 void getVisualStudioDefines(const LangOptions &Opts,
480 MacroBuilder &Builder) const {
Michael J. Spencerdae4ac42010-10-21 05:21:48 +0000481 if (Opts.CPlusPlus) {
482 if (Opts.RTTI)
483 Builder.defineMacro("_CPPRTTI");
484
485 if (Opts.Exceptions)
486 Builder.defineMacro("_CPPUNWIND");
487 }
488
489 if (!Opts.CharIsSigned)
490 Builder.defineMacro("_CHAR_UNSIGNED");
491
492 // FIXME: POSIXThreads isn't exactly the option this should be defined for,
493 // but it works for now.
494 if (Opts.POSIXThreads)
495 Builder.defineMacro("_MT");
Michael J. Spencera764e832010-10-21 08:22:51 +0000496
Michael J. Spencerdae4ac42010-10-21 05:21:48 +0000497 if (Opts.MSCVersion != 0)
498 Builder.defineMacro("_MSC_VER", llvm::Twine(Opts.MSCVersion));
499
500 if (Opts.Microsoft) {
501 Builder.defineMacro("_MSC_EXTENSIONS");
502
503 if (Opts.CPlusPlus0x) {
504 Builder.defineMacro("_RVALUE_REFERENCES_V2_SUPPORTED");
505 Builder.defineMacro("_RVALUE_REFERENCES_SUPPORTED");
506 Builder.defineMacro("_NATIVE_NULLPTR_SUPPORTED");
507 }
508 }
509
510 Builder.defineMacro("_INTEGRAL_MAX_BITS", "64");
Michael J. Spencerdae4ac42010-10-21 05:21:48 +0000511 }
512
Michael J. Spencerdae4ac42010-10-21 05:21:48 +0000513public:
514 WindowsTargetInfo(const std::string &triple)
515 : OSTargetInfo<Target>(triple) {}
516};
517
Mike Stump1eb44332009-09-09 15:08:12 +0000518} // end anonymous namespace.
Torok Edwin5f6c1942009-06-30 17:10:35 +0000519
Chris Lattnerd29b6302008-10-05 21:50:58 +0000520//===----------------------------------------------------------------------===//
Eli Friedmane4277982008-08-20 23:11:40 +0000521// Specific target implementations.
522//===----------------------------------------------------------------------===//
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000523
Eli Friedmane4277982008-08-20 23:11:40 +0000524namespace {
525// PPC abstract base class
526class PPCTargetInfo : public TargetInfo {
527 static const Builtin::Info BuiltinInfo[];
528 static const char * const GCCRegNames[];
529 static const TargetInfo::GCCRegAlias GCCRegAliases[];
Eli Friedmane4277982008-08-20 23:11:40 +0000530public:
Eli Friedman15b91762009-06-05 07:05:05 +0000531 PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {}
532
Eli Friedmane4277982008-08-20 23:11:40 +0000533 virtual void getTargetBuiltins(const Builtin::Info *&Records,
534 unsigned &NumRecords) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000535 Records = BuiltinInfo;
Eli Friedmane4277982008-08-20 23:11:40 +0000536 NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
Reid Spencer5f016e22007-07-11 17:01:13 +0000537 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000538
Chris Lattner33328642009-03-20 15:52:06 +0000539 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +0000540 MacroBuilder &Builder) const;
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000541
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000542 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedmane4277982008-08-20 23:11:40 +0000543 unsigned &NumNames) const;
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000544 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Eli Friedmane4277982008-08-20 23:11:40 +0000545 unsigned &NumAliases) const;
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000546 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattner44def072009-04-26 07:16:29 +0000547 TargetInfo::ConstraintInfo &Info) const {
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000548 switch (*Name) {
Anders Carlssond04c6e22007-11-27 04:11:28 +0000549 default: return false;
550 case 'O': // Zero
John Thompson8e6065a2010-06-24 22:44:13 +0000551 break;
Anders Carlssond04c6e22007-11-27 04:11:28 +0000552 case 'b': // Base register
553 case 'f': // Floating point register
Chris Lattner44def072009-04-26 07:16:29 +0000554 Info.setAllowsRegister();
John Thompson8e6065a2010-06-24 22:44:13 +0000555 break;
556 // FIXME: The following are added to allow parsing.
557 // I just took a guess at what the actions should be.
558 // Also, is more specific checking needed? I.e. specific registers?
Michael J. Spencer20249a12010-10-21 03:16:25 +0000559 case 'd': // Floating point register (containing 64-bit value)
John Thompson8e6065a2010-06-24 22:44:13 +0000560 case 'v': // Altivec vector register
561 Info.setAllowsRegister();
562 break;
563 case 'w':
564 switch (Name[1]) {
Michael J. Spencer20249a12010-10-21 03:16:25 +0000565 case 'd':// VSX vector register to hold vector double data
566 case 'f':// VSX vector register to hold vector float data
567 case 's':// VSX vector register to hold scalar float data
568 case 'a':// Any VSX register
John Thompson8e6065a2010-06-24 22:44:13 +0000569 break;
570 default:
571 return false;
572 }
573 Info.setAllowsRegister();
574 Name++; // Skip over 'w'.
575 break;
Michael J. Spencer20249a12010-10-21 03:16:25 +0000576 case 'h': // `MQ', `CTR', or `LINK' register
577 case 'q': // `MQ' register
578 case 'c': // `CTR' register
579 case 'l': // `LINK' register
580 case 'x': // `CR' register (condition register) number 0
581 case 'y': // `CR' register (condition register)
582 case 'z': // `XER[CA]' carry bit (part of the XER register)
John Thompson8e6065a2010-06-24 22:44:13 +0000583 Info.setAllowsRegister();
584 break;
Michael J. Spencer20249a12010-10-21 03:16:25 +0000585 case 'I': // Signed 16-bit constant
John Thompson8e6065a2010-06-24 22:44:13 +0000586 case 'J': // Unsigned 16-bit constant shifted left 16 bits
Michael J. Spencer20249a12010-10-21 03:16:25 +0000587 // (use `L' instead for SImode constants)
588 case 'K': // Unsigned 16-bit constant
589 case 'L': // Signed 16-bit constant shifted left 16 bits
590 case 'M': // Constant larger than 31
591 case 'N': // Exact power of 2
592 case 'P': // Constant whose negation is a signed 16-bit constant
John Thompson8e6065a2010-06-24 22:44:13 +0000593 case 'G': // Floating point constant that can be loaded into a
Michael J. Spencer20249a12010-10-21 03:16:25 +0000594 // register with one instruction per word
John Thompson8e6065a2010-06-24 22:44:13 +0000595 case 'H': // Integer/Floating point constant that can be loaded
Michael J. Spencer20249a12010-10-21 03:16:25 +0000596 // into a register using three instructions
John Thompson8e6065a2010-06-24 22:44:13 +0000597 break;
598 case 'm': // Memory operand. Note that on PowerPC targets, m can
599 // include addresses that update the base register. It
600 // is therefore only safe to use `m' in an asm statement
601 // if that asm statement accesses the operand exactly once.
602 // The asm statement must also use `%U<opno>' as a
Sebastian Redl5005a6c2010-08-17 22:42:34 +0000603 // placeholder for the "update" flag in the corresponding
Michael J. Spencer20249a12010-10-21 03:16:25 +0000604 // load or store instruction. For example:
John Thompson8e6065a2010-06-24 22:44:13 +0000605 // asm ("st%U0 %1,%0" : "=m" (mem) : "r" (val));
Michael J. Spencer20249a12010-10-21 03:16:25 +0000606 // is correct but:
John Thompson8e6065a2010-06-24 22:44:13 +0000607 // asm ("st %1,%0" : "=m" (mem) : "r" (val));
608 // is not. Use es rather than m if you don't want the base
Michael J. Spencer20249a12010-10-21 03:16:25 +0000609 // register to be updated.
610 case 'e':
John Thompson56b6eca2010-06-25 00:02:05 +0000611 if (Name[1] != 's')
612 return false;
Sebastian Redl5005a6c2010-08-17 22:42:34 +0000613 // es: A "stable" memory operand; that is, one which does not
John Thompson8e6065a2010-06-24 22:44:13 +0000614 // include any automodification of the base register. Unlike
615 // `m', this constraint can be used in asm statements that
616 // might access the operand several times, or that might not
John Thompson56b6eca2010-06-25 00:02:05 +0000617 // access it at all.
John Thompson8e6065a2010-06-24 22:44:13 +0000618 Info.setAllowsMemory();
John Thompson56b6eca2010-06-25 00:02:05 +0000619 Name++; // Skip over 'e'.
John Thompson8e6065a2010-06-24 22:44:13 +0000620 break;
621 case 'Q': // Memory operand that is an offset from a register (it is
Michael J. Spencer20249a12010-10-21 03:16:25 +0000622 // usually better to use `m' or `es' in asm statements)
John Thompson8e6065a2010-06-24 22:44:13 +0000623 case 'Z': // Memory operand that is an indexed or indirect from a
624 // register (it is usually better to use `m' or `es' in
Michael J. Spencer20249a12010-10-21 03:16:25 +0000625 // asm statements)
John Thompson8e6065a2010-06-24 22:44:13 +0000626 Info.setAllowsMemory();
627 Info.setAllowsRegister();
628 break;
Michael J. Spencer20249a12010-10-21 03:16:25 +0000629 case 'R': // AIX TOC entry
John Thompson8e6065a2010-06-24 22:44:13 +0000630 case 'a': // Address operand that is an indexed or indirect from a
Michael J. Spencer20249a12010-10-21 03:16:25 +0000631 // register (`p' is preferable for asm statements)
632 case 'S': // Constant suitable as a 64-bit mask operand
633 case 'T': // Constant suitable as a 32-bit mask operand
634 case 'U': // System V Release 4 small data area reference
John Thompson8e6065a2010-06-24 22:44:13 +0000635 case 't': // AND masks that can be performed by two rldic{l, r}
Michael J. Spencer20249a12010-10-21 03:16:25 +0000636 // instructions
637 case 'W': // Vector constant that does not require memory
638 case 'j': // Vector constant that is all zeros.
John Thompson8e6065a2010-06-24 22:44:13 +0000639 break;
640 // End FIXME.
Anders Carlssond04c6e22007-11-27 04:11:28 +0000641 }
John Thompson8e6065a2010-06-24 22:44:13 +0000642 return true;
Anders Carlssond04c6e22007-11-27 04:11:28 +0000643 }
Eli Friedmane4277982008-08-20 23:11:40 +0000644 virtual const char *getClobbers() const {
645 return "";
Anders Carlssond04c6e22007-11-27 04:11:28 +0000646 }
Eli Friedmane4277982008-08-20 23:11:40 +0000647};
Anders Carlssond04c6e22007-11-27 04:11:28 +0000648
Eli Friedmane4277982008-08-20 23:11:40 +0000649const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
Fariborz Jahanian67aba812010-11-30 17:35:24 +0000650#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES, false },
651#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
652 ALL_LANGUAGES, false },
Chris Lattner6b15cdc2009-06-14 01:05:48 +0000653#include "clang/Basic/BuiltinsPPC.def"
Eli Friedmane4277982008-08-20 23:11:40 +0000654};
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000655
656
Chris Lattnerc0f59212009-03-02 22:27:17 +0000657/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
658/// #defines that are not tied to a specific subtarget.
Chris Lattner33328642009-03-20 15:52:06 +0000659void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +0000660 MacroBuilder &Builder) const {
Chris Lattnerc0f59212009-03-02 22:27:17 +0000661 // Target identification.
Benjamin Kramera9992772010-01-09 17:55:51 +0000662 Builder.defineMacro("__ppc__");
663 Builder.defineMacro("_ARCH_PPC");
Chris Lattnere03ae302010-02-16 18:14:57 +0000664 Builder.defineMacro("__powerpc__");
Benjamin Kramera9992772010-01-09 17:55:51 +0000665 Builder.defineMacro("__POWERPC__");
Chris Lattnerc0f59212009-03-02 22:27:17 +0000666 if (PointerWidth == 64) {
Benjamin Kramera9992772010-01-09 17:55:51 +0000667 Builder.defineMacro("_ARCH_PPC64");
668 Builder.defineMacro("_LP64");
669 Builder.defineMacro("__LP64__");
Chris Lattnere03ae302010-02-16 18:14:57 +0000670 Builder.defineMacro("__powerpc64__");
Benjamin Kramera9992772010-01-09 17:55:51 +0000671 Builder.defineMacro("__ppc64__");
Chris Lattnerc0f59212009-03-02 22:27:17 +0000672 } else {
Benjamin Kramera9992772010-01-09 17:55:51 +0000673 Builder.defineMacro("__ppc__");
Chris Lattnerc0f59212009-03-02 22:27:17 +0000674 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000675
Chris Lattnerc0f59212009-03-02 22:27:17 +0000676 // Target properties.
Benjamin Kramera9992772010-01-09 17:55:51 +0000677 Builder.defineMacro("_BIG_ENDIAN");
678 Builder.defineMacro("__BIG_ENDIAN__");
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000679
Chris Lattnerc0f59212009-03-02 22:27:17 +0000680 // Subtarget options.
Benjamin Kramera9992772010-01-09 17:55:51 +0000681 Builder.defineMacro("__NATURAL_ALIGNMENT__");
682 Builder.defineMacro("__REGISTER_PREFIX__", "");
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000683
Chris Lattnerc0f59212009-03-02 22:27:17 +0000684 // FIXME: Should be controlled by command line option.
Benjamin Kramera9992772010-01-09 17:55:51 +0000685 Builder.defineMacro("__LONG_DOUBLE_128__");
Michael J. Spencer20249a12010-10-21 03:16:25 +0000686
John Thompson3f6918a2009-11-19 17:18:50 +0000687 if (Opts.AltiVec) {
Benjamin Kramera9992772010-01-09 17:55:51 +0000688 Builder.defineMacro("__VEC__", "10206");
689 Builder.defineMacro("__ALTIVEC__");
John Thompson3f6918a2009-11-19 17:18:50 +0000690 }
Chris Lattnerc0f59212009-03-02 22:27:17 +0000691}
692
Chris Lattner393ff042008-04-21 18:56:49 +0000693
Eli Friedmane4277982008-08-20 23:11:40 +0000694const char * const PPCTargetInfo::GCCRegNames[] = {
Chris Lattnere94e0d42009-09-16 05:05:27 +0000695 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
696 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
697 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
698 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
699 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
700 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
701 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
702 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
Eli Friedmane4277982008-08-20 23:11:40 +0000703 "mq", "lr", "ctr", "ap",
Chris Lattnere94e0d42009-09-16 05:05:27 +0000704 "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
Eli Friedmane4277982008-08-20 23:11:40 +0000705 "xer",
Chris Lattnere94e0d42009-09-16 05:05:27 +0000706 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
707 "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
708 "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
709 "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
Eli Friedmane4277982008-08-20 23:11:40 +0000710 "vrsave", "vscr",
711 "spe_acc", "spefscr",
712 "sfp"
713};
Reid Spencer5f016e22007-07-11 17:01:13 +0000714
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000715void PPCTargetInfo::getGCCRegNames(const char * const *&Names,
Eli Friedmane4277982008-08-20 23:11:40 +0000716 unsigned &NumNames) const {
717 Names = GCCRegNames;
718 NumNames = llvm::array_lengthof(GCCRegNames);
719}
Reid Spencer5f016e22007-07-11 17:01:13 +0000720
Eli Friedmane4277982008-08-20 23:11:40 +0000721const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
722 // While some of these aliases do map to different registers
723 // they still share the same register name.
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +0000724 { { "0" }, "r0" },
725 { { "1"}, "r1" },
726 { { "2" }, "r2" },
727 { { "3" }, "r3" },
728 { { "4" }, "r4" },
729 { { "5" }, "r5" },
730 { { "6" }, "r6" },
731 { { "7" }, "r7" },
732 { { "8" }, "r8" },
733 { { "9" }, "r9" },
734 { { "10" }, "r10" },
735 { { "11" }, "r11" },
736 { { "12" }, "r12" },
737 { { "13" }, "r13" },
738 { { "14" }, "r14" },
739 { { "15" }, "r15" },
740 { { "16" }, "r16" },
741 { { "17" }, "r17" },
742 { { "18" }, "r18" },
743 { { "19" }, "r19" },
744 { { "20" }, "r20" },
745 { { "21" }, "r21" },
746 { { "22" }, "r22" },
747 { { "23" }, "r23" },
748 { { "24" }, "r24" },
749 { { "25" }, "r25" },
750 { { "26" }, "r26" },
751 { { "27" }, "r27" },
752 { { "28" }, "r28" },
753 { { "29" }, "r29" },
754 { { "30" }, "r30" },
755 { { "31" }, "r31" },
756 { { "fr0" }, "f0" },
757 { { "fr1" }, "f1" },
758 { { "fr2" }, "f2" },
759 { { "fr3" }, "f3" },
760 { { "fr4" }, "f4" },
761 { { "fr5" }, "f5" },
762 { { "fr6" }, "f6" },
763 { { "fr7" }, "f7" },
764 { { "fr8" }, "f8" },
765 { { "fr9" }, "f9" },
Mike Stump10880392009-09-17 21:15:00 +0000766 { { "fr10" }, "f10" },
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +0000767 { { "fr11" }, "f11" },
768 { { "fr12" }, "f12" },
769 { { "fr13" }, "f13" },
770 { { "fr14" }, "f14" },
771 { { "fr15" }, "f15" },
772 { { "fr16" }, "f16" },
773 { { "fr17" }, "f17" },
774 { { "fr18" }, "f18" },
775 { { "fr19" }, "f19" },
776 { { "fr20" }, "f20" },
777 { { "fr21" }, "f21" },
778 { { "fr22" }, "f22" },
779 { { "fr23" }, "f23" },
780 { { "fr24" }, "f24" },
781 { { "fr25" }, "f25" },
782 { { "fr26" }, "f26" },
783 { { "fr27" }, "f27" },
784 { { "fr28" }, "f28" },
785 { { "fr29" }, "f29" },
786 { { "fr30" }, "f30" },
787 { { "fr31" }, "f31" },
788 { { "cc" }, "cr0" },
Eli Friedmane4277982008-08-20 23:11:40 +0000789};
790
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000791void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
Eli Friedmane4277982008-08-20 23:11:40 +0000792 unsigned &NumAliases) const {
793 Aliases = GCCRegAliases;
794 NumAliases = llvm::array_lengthof(GCCRegAliases);
795}
796} // end anonymous namespace.
Reid Spencer5f016e22007-07-11 17:01:13 +0000797
798namespace {
Eli Friedmane4277982008-08-20 23:11:40 +0000799class PPC32TargetInfo : public PPCTargetInfo {
Reid Spencer5f016e22007-07-11 17:01:13 +0000800public:
Chris Lattnere03ae302010-02-16 18:14:57 +0000801 PPC32TargetInfo(const std::string &triple) : PPCTargetInfo(triple) {
Eli Friedmaned855cb2008-08-21 00:13:15 +0000802 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
Chris Lattner1932e122009-11-07 18:59:41 +0000803 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";
Chris Lattnere03ae302010-02-16 18:14:57 +0000804
Joerg Sonnenberger6ac26fa2011-07-04 21:57:55 +0000805 switch (getTriple().getOS()) {
806 case llvm::Triple::FreeBSD:
807 case llvm::Triple::NetBSD:
Roman Divackyc81f2a22011-01-06 08:27:10 +0000808 SizeType = UnsignedInt;
Joerg Sonnenberger6ac26fa2011-07-04 21:57:55 +0000809 break;
810 }
Roman Divackyc81f2a22011-01-06 08:27:10 +0000811 }
812
813 virtual const char *getVAListDeclaration() const {
814 // This is the ELF definition, and is overridden by the Darwin sub-target
815 return "typedef struct __va_list_tag {"
816 " unsigned char gpr;"
817 " unsigned char fpr;"
818 " unsigned short reserved;"
819 " void* overflow_arg_area;"
820 " void* reg_save_area;"
821 "} __builtin_va_list[1];";
Eli Friedmaned855cb2008-08-21 00:13:15 +0000822 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000823};
824} // end anonymous namespace.
825
826namespace {
Eli Friedmane4277982008-08-20 23:11:40 +0000827class PPC64TargetInfo : public PPCTargetInfo {
Reid Spencer5f016e22007-07-11 17:01:13 +0000828public:
Eli Friedmane4277982008-08-20 23:11:40 +0000829 PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
Chris Lattnerf291b102008-05-09 06:17:04 +0000830 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedman3c7b6e42009-07-01 03:36:11 +0000831 IntMaxType = SignedLong;
832 UIntMaxType = UnsignedLong;
833 Int64Type = SignedLong;
Eli Friedmaned855cb2008-08-21 00:13:15 +0000834 DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
Chris Lattner1932e122009-11-07 18:59:41 +0000835 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64";
Chris Lattnerf291b102008-05-09 06:17:04 +0000836 }
Roman Divackyc81f2a22011-01-06 08:27:10 +0000837 virtual const char *getVAListDeclaration() const {
838 return "typedef char* __builtin_va_list;";
839 }
Eli Friedmane4277982008-08-20 23:11:40 +0000840};
841} // end anonymous namespace.
842
Daniel Dunbar4c6a2262010-05-30 00:07:30 +0000843
844namespace {
Roman Divackyc81f2a22011-01-06 08:27:10 +0000845class DarwinPPC32TargetInfo :
846 public DarwinTargetInfo<PPC32TargetInfo> {
Daniel Dunbar4c6a2262010-05-30 00:07:30 +0000847public:
Roman Divackyc81f2a22011-01-06 08:27:10 +0000848 DarwinPPC32TargetInfo(const std::string& triple)
849 : DarwinTargetInfo<PPC32TargetInfo>(triple) {
Daniel Dunbar4c6a2262010-05-30 00:07:30 +0000850 HasAlignMac68kSupport = true;
Roman Divackyc81f2a22011-01-06 08:27:10 +0000851 BoolWidth = BoolAlign = 32; //XXX support -mone-byte-bool?
852 }
853 virtual const char *getVAListDeclaration() const {
854 return "typedef char* __builtin_va_list;";
Daniel Dunbar4c6a2262010-05-30 00:07:30 +0000855 }
856};
857
858class DarwinPPC64TargetInfo :
859 public DarwinTargetInfo<PPC64TargetInfo> {
860public:
861 DarwinPPC64TargetInfo(const std::string& triple)
862 : DarwinTargetInfo<PPC64TargetInfo>(triple) {
863 HasAlignMac68kSupport = true;
864 }
865};
866} // end anonymous namespace.
867
Reid Spencer5f016e22007-07-11 17:01:13 +0000868namespace {
Justin Holewinski285dc652011-04-20 19:34:15 +0000869 class PTXTargetInfo : public TargetInfo {
870 static const char * const GCCRegNames[];
871 static const Builtin::Info BuiltinInfo[];
872 public:
873 PTXTargetInfo(const std::string& triple) : TargetInfo(triple) {
874 TLSSupported = false;
875 LongWidth = LongAlign = 64;
876 }
877 virtual void getTargetDefines(const LangOptions &Opts,
878 MacroBuilder &Builder) const {
879 Builder.defineMacro("__PTX__");
880 }
881 virtual void getTargetBuiltins(const Builtin::Info *&Records,
882 unsigned &NumRecords) const {
883 Records = BuiltinInfo;
884 NumRecords = clang::PTX::LastTSBuiltin-Builtin::FirstTSBuiltin;
885 }
886
887 virtual void getGCCRegNames(const char * const *&Names,
888 unsigned &NumNames) const;
889 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
890 unsigned &NumAliases) const {
891 // No aliases.
892 Aliases = 0;
893 NumAliases = 0;
894 }
895 virtual bool validateAsmConstraint(const char *&Name,
896 TargetInfo::ConstraintInfo &info) const {
897 // FIXME: implement
898 return true;
899 }
900 virtual const char *getClobbers() const {
901 // FIXME: Is this really right?
902 return "";
903 }
904 virtual const char *getVAListDeclaration() const {
905 // FIXME: implement
906 return "typedef char* __builtin_va_list;";
907 }
908 };
909
910 const Builtin::Info PTXTargetInfo::BuiltinInfo[] = {
911#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES, false },
912#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
913 ALL_LANGUAGES, false },
914#include "clang/Basic/BuiltinsPTX.def"
915 };
916
917 const char * const PTXTargetInfo::GCCRegNames[] = {
918 "r0"
919 };
920
921 void PTXTargetInfo::getGCCRegNames(const char * const *&Names,
922 unsigned &NumNames) const {
923 Names = GCCRegNames;
924 NumNames = llvm::array_lengthof(GCCRegNames);
925 }
926
927
928 class PTX32TargetInfo : public PTXTargetInfo {
929 public:
930 PTX32TargetInfo(const std::string& triple) : PTXTargetInfo(triple) {
931 PointerWidth = PointerAlign = 32;
932 SizeType = PtrDiffType = IntPtrType = TargetInfo::UnsignedInt;
933 DescriptionString
934 = "e-p:32:32-i64:64:64-f64:64:64-n1:8:16:32:64";
935 }
936 };
937
938 class PTX64TargetInfo : public PTXTargetInfo {
939 public:
940 PTX64TargetInfo(const std::string& triple) : PTXTargetInfo(triple) {
941 PointerWidth = PointerAlign = 64;
942 SizeType = PtrDiffType = IntPtrType = TargetInfo::UnsignedLongLong;
943 DescriptionString
944 = "e-p:64:64-i64:64:64-f64:64:64-n1:8:16:32:64";
945 }
946 };
947}
948
949namespace {
Chris Lattner9cbeb632010-03-06 21:21:27 +0000950// MBlaze abstract base class
951class MBlazeTargetInfo : public TargetInfo {
952 static const char * const GCCRegNames[];
953 static const TargetInfo::GCCRegAlias GCCRegAliases[];
954
955public:
956 MBlazeTargetInfo(const std::string& triple) : TargetInfo(triple) {
Wesley Pecka48fa4b2010-12-12 20:56:47 +0000957 DescriptionString = "E-p:32:32:32-i8:8:8-i16:16:16";
Chris Lattner9cbeb632010-03-06 21:21:27 +0000958 }
959
960 virtual void getTargetBuiltins(const Builtin::Info *&Records,
961 unsigned &NumRecords) const {
962 // FIXME: Implement.
963 Records = 0;
964 NumRecords = 0;
965 }
966
967 virtual void getTargetDefines(const LangOptions &Opts,
968 MacroBuilder &Builder) const;
969
970 virtual const char *getVAListDeclaration() const {
971 return "typedef char* __builtin_va_list;";
972 }
973 virtual const char *getTargetPrefix() const {
974 return "mblaze";
975 }
976 virtual void getGCCRegNames(const char * const *&Names,
977 unsigned &NumNames) const;
978 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
979 unsigned &NumAliases) const;
980 virtual bool validateAsmConstraint(const char *&Name,
981 TargetInfo::ConstraintInfo &Info) const {
982 switch (*Name) {
983 default: return false;
984 case 'O': // Zero
985 return true;
986 case 'b': // Base register
987 case 'f': // Floating point register
988 Info.setAllowsRegister();
989 return true;
990 }
991 }
992 virtual const char *getClobbers() const {
993 return "";
994 }
995};
996
997/// MBlazeTargetInfo::getTargetDefines - Return a set of the MBlaze-specific
998/// #defines that are not tied to a specific subtarget.
999void MBlazeTargetInfo::getTargetDefines(const LangOptions &Opts,
1000 MacroBuilder &Builder) const {
1001 // Target identification.
1002 Builder.defineMacro("__microblaze__");
1003 Builder.defineMacro("_ARCH_MICROBLAZE");
1004 Builder.defineMacro("__MICROBLAZE__");
1005
1006 // Target properties.
1007 Builder.defineMacro("_BIG_ENDIAN");
1008 Builder.defineMacro("__BIG_ENDIAN__");
1009
1010 // Subtarget options.
1011 Builder.defineMacro("__REGISTER_PREFIX__", "");
1012}
1013
1014
1015const char * const MBlazeTargetInfo::GCCRegNames[] = {
1016 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1017 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
1018 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
1019 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
1020 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
1021 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
1022 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
1023 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
1024 "hi", "lo", "accum","rmsr", "$fcc1","$fcc2","$fcc3","$fcc4",
1025 "$fcc5","$fcc6","$fcc7","$ap", "$rap", "$frp"
1026};
1027
1028void MBlazeTargetInfo::getGCCRegNames(const char * const *&Names,
1029 unsigned &NumNames) const {
1030 Names = GCCRegNames;
1031 NumNames = llvm::array_lengthof(GCCRegNames);
1032}
1033
1034const TargetInfo::GCCRegAlias MBlazeTargetInfo::GCCRegAliases[] = {
1035 { {"f0"}, "r0" },
1036 { {"f1"}, "r1" },
1037 { {"f2"}, "r2" },
1038 { {"f3"}, "r3" },
1039 { {"f4"}, "r4" },
1040 { {"f5"}, "r5" },
1041 { {"f6"}, "r6" },
1042 { {"f7"}, "r7" },
1043 { {"f8"}, "r8" },
1044 { {"f9"}, "r9" },
1045 { {"f10"}, "r10" },
1046 { {"f11"}, "r11" },
1047 { {"f12"}, "r12" },
1048 { {"f13"}, "r13" },
1049 { {"f14"}, "r14" },
1050 { {"f15"}, "r15" },
1051 { {"f16"}, "r16" },
1052 { {"f17"}, "r17" },
1053 { {"f18"}, "r18" },
1054 { {"f19"}, "r19" },
1055 { {"f20"}, "r20" },
1056 { {"f21"}, "r21" },
1057 { {"f22"}, "r22" },
1058 { {"f23"}, "r23" },
1059 { {"f24"}, "r24" },
1060 { {"f25"}, "r25" },
1061 { {"f26"}, "r26" },
1062 { {"f27"}, "r27" },
1063 { {"f28"}, "r28" },
1064 { {"f29"}, "r29" },
1065 { {"f30"}, "r30" },
1066 { {"f31"}, "r31" },
1067};
1068
1069void MBlazeTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
1070 unsigned &NumAliases) const {
1071 Aliases = GCCRegAliases;
1072 NumAliases = llvm::array_lengthof(GCCRegAliases);
1073}
1074} // end anonymous namespace.
1075
1076namespace {
Eli Friedman618234a2008-08-20 02:34:37 +00001077// Namespace for x86 abstract base class
1078const Builtin::Info BuiltinInfo[] = {
Fariborz Jahanian67aba812010-11-30 17:35:24 +00001079#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES, false },
1080#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
1081 ALL_LANGUAGES, false },
Chris Lattner6b15cdc2009-06-14 01:05:48 +00001082#include "clang/Basic/BuiltinsX86.def"
Eli Friedman618234a2008-08-20 02:34:37 +00001083};
Eli Friedman61538a72008-05-20 14:21:01 +00001084
Nuno Lopes2550d702009-12-23 17:49:57 +00001085static const char* const GCCRegNames[] = {
Eli Friedman618234a2008-08-20 02:34:37 +00001086 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
1087 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
1088 "argp", "flags", "fspr", "dirflag", "frame",
1089 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
1090 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
1091 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
Eric Christophercfd323d2011-06-21 00:05:20 +00001092 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15",
Eli Friedman618234a2008-08-20 02:34:37 +00001093};
1094
Eric Christophercfd323d2011-06-21 00:05:20 +00001095const TargetInfo::AddlRegName AddlRegNames[] = {
1096 { { "al", "ah", "eax", "rax" }, 0 },
1097 { { "bl", "bh", "ebx", "rbx" }, 3 },
1098 { { "cl", "ch", "ecx", "rcx" }, 2 },
1099 { { "dl", "dh", "edx", "rdx" }, 1 },
1100 { { "esi", "rsi" }, 4 },
1101 { { "edi", "rdi" }, 5 },
1102 { { "esp", "rsp" }, 7 },
1103 { { "ebp", "rbp" }, 6 },
Eli Friedman618234a2008-08-20 02:34:37 +00001104};
1105
1106// X86 target abstract base class; x86-32 and x86-64 are very close, so
1107// most of the implementation can be shared.
1108class X86TargetInfo : public TargetInfo {
Chris Lattner84f0ea82009-03-02 22:40:39 +00001109 enum X86SSEEnum {
1110 NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42
1111 } SSELevel;
Anders Carlsson9b0fb622010-01-27 03:47:49 +00001112 enum AMD3DNowEnum {
1113 NoAMD3DNow, AMD3DNow, AMD3DNowAthlon
1114 } AMD3DNowLevel;
1115
Eric Christophereea12d12010-04-02 23:50:19 +00001116 bool HasAES;
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +00001117 bool HasAVX;
1118
Eli Friedman618234a2008-08-20 02:34:37 +00001119public:
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001120 X86TargetInfo(const std::string& triple)
Eric Christophereea12d12010-04-02 23:50:19 +00001121 : TargetInfo(triple), SSELevel(NoMMXSSE), AMD3DNowLevel(NoAMD3DNow),
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +00001122 HasAES(false), HasAVX(false) {
Eli Friedman618234a2008-08-20 02:34:37 +00001123 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
Reid Spencer5f016e22007-07-11 17:01:13 +00001124 }
1125 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1126 unsigned &NumRecords) const {
Eli Friedman618234a2008-08-20 02:34:37 +00001127 Records = BuiltinInfo;
1128 NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
Reid Spencer5f016e22007-07-11 17:01:13 +00001129 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001130 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedman618234a2008-08-20 02:34:37 +00001131 unsigned &NumNames) const {
1132 Names = GCCRegNames;
1133 NumNames = llvm::array_lengthof(GCCRegNames);
Anders Carlsson3346ae62007-11-24 23:38:12 +00001134 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001135 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Anders Carlsson3346ae62007-11-24 23:38:12 +00001136 unsigned &NumAliases) const {
Eric Christophercfd323d2011-06-21 00:05:20 +00001137 Aliases = 0;
1138 NumAliases = 0;
1139 }
1140 virtual void getGCCAddlRegNames(const AddlRegName *&Names,
1141 unsigned &NumNames) const {
1142 Names = AddlRegNames;
1143 NumNames = llvm::array_lengthof(AddlRegNames);
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +00001144 }
Anders Carlsson066d2ea2009-02-28 17:11:49 +00001145 virtual bool validateAsmConstraint(const char *&Name,
Eli Friedman618234a2008-08-20 02:34:37 +00001146 TargetInfo::ConstraintInfo &info) const;
Stuart Hastings002333f2011-06-07 23:45:05 +00001147 virtual std::string convertConstraint(const char *&Constraint) const;
Anders Carlssond04c6e22007-11-27 04:11:28 +00001148 virtual const char *getClobbers() const {
Eli Friedman618234a2008-08-20 02:34:37 +00001149 return "~{dirflag},~{fpsr},~{flags}";
1150 }
Chris Lattner33328642009-03-20 15:52:06 +00001151 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001152 MacroBuilder &Builder) const;
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001153 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
1154 const std::string &Name,
1155 bool Enabled) const;
Mike Stump1eb44332009-09-09 15:08:12 +00001156 virtual void getDefaultFeatures(const std::string &CPU,
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001157 llvm::StringMap<bool> &Features) const;
Daniel Dunbarb93292a2009-12-19 03:30:57 +00001158 virtual void HandleTargetFeatures(std::vector<std::string> &Features);
Reid Spencer5f016e22007-07-11 17:01:13 +00001159};
Chris Lattner3daed522009-03-02 22:20:04 +00001160
Mike Stump1eb44332009-09-09 15:08:12 +00001161void X86TargetInfo::getDefaultFeatures(const std::string &CPU,
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001162 llvm::StringMap<bool> &Features) const {
Daniel Dunbar868bd0a2009-05-06 03:16:41 +00001163 // FIXME: This should not be here.
1164 Features["3dnow"] = false;
1165 Features["3dnowa"] = false;
1166 Features["mmx"] = false;
1167 Features["sse"] = false;
1168 Features["sse2"] = false;
1169 Features["sse3"] = false;
1170 Features["ssse3"] = false;
1171 Features["sse41"] = false;
1172 Features["sse42"] = false;
Eric Christophereea12d12010-04-02 23:50:19 +00001173 Features["aes"] = false;
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +00001174 Features["avx"] = false;
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001175
Daniel Dunbar868bd0a2009-05-06 03:16:41 +00001176 // LLVM does not currently recognize this.
1177 // Features["sse4a"] = false;
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001178
Daniel Dunbar868bd0a2009-05-06 03:16:41 +00001179 // FIXME: This *really* should not be here.
1180
1181 // X86_64 always has SSE2.
1182 if (PointerWidth == 64)
1183 Features["sse2"] = Features["sse"] = Features["mmx"] = true;
1184
Daniel Dunbar3ac79042009-05-06 21:56:32 +00001185 if (CPU == "generic" || CPU == "i386" || CPU == "i486" || CPU == "i586" ||
1186 CPU == "pentium" || CPU == "i686" || CPU == "pentiumpro")
1187 ;
1188 else if (CPU == "pentium-mmx" || CPU == "pentium2")
1189 setFeatureEnabled(Features, "mmx", true);
Daniel Dunbarcb65de12011-05-03 15:34:01 +00001190 else if (CPU == "pentium3")
Daniel Dunbar3ac79042009-05-06 21:56:32 +00001191 setFeatureEnabled(Features, "sse", true);
Daniel Dunbarcb65de12011-05-03 15:34:01 +00001192 else if (CPU == "pentium-m" || CPU == "pentium4" || CPU == "x86-64")
Daniel Dunbar3ac79042009-05-06 21:56:32 +00001193 setFeatureEnabled(Features, "sse2", true);
Daniel Dunbarcb65de12011-05-03 15:34:01 +00001194 else if (CPU == "yonah" || CPU == "prescott" || CPU == "nocona")
Daniel Dunbar3ac79042009-05-06 21:56:32 +00001195 setFeatureEnabled(Features, "sse3", true);
Daniel Dunbarcb65de12011-05-03 15:34:01 +00001196 else if (CPU == "core2")
Daniel Dunbar3ac79042009-05-06 21:56:32 +00001197 setFeatureEnabled(Features, "ssse3", true);
Daniel Dunbarcb65de12011-05-03 15:34:01 +00001198 else if (CPU == "penryn") {
1199 setFeatureEnabled(Features, "sse4", true);
1200 Features["sse42"] = false;
1201 } else if (CPU == "atom")
Daniel Dunbar3ac79042009-05-06 21:56:32 +00001202 setFeatureEnabled(Features, "sse3", true);
Daniel Dunbarcb65de12011-05-03 15:34:01 +00001203 else if (CPU == "corei7") {
Daniel Dunbar3ac79042009-05-06 21:56:32 +00001204 setFeatureEnabled(Features, "sse4", true);
Eric Christophereea12d12010-04-02 23:50:19 +00001205 setFeatureEnabled(Features, "aes", true);
Benjamin Kramerb65b6722011-05-20 15:11:23 +00001206 } else if (CPU == "corei7-avx") {
Roman Divackybcaa3b82011-04-05 20:32:44 +00001207 setFeatureEnabled(Features, "sse4", true);
1208 setFeatureEnabled(Features, "aes", true);
1209// setFeatureEnabled(Features, "avx", true);
1210 } else if (CPU == "k6" || CPU == "winchip-c6")
Daniel Dunbar3ac79042009-05-06 21:56:32 +00001211 setFeatureEnabled(Features, "mmx", true);
Mike Stump1eb44332009-09-09 15:08:12 +00001212 else if (CPU == "k6-2" || CPU == "k6-3" || CPU == "athlon" ||
Daniel Dunbar3ac79042009-05-06 21:56:32 +00001213 CPU == "athlon-tbird" || CPU == "winchip2" || CPU == "c3") {
1214 setFeatureEnabled(Features, "mmx", true);
1215 setFeatureEnabled(Features, "3dnow", true);
1216 } else if (CPU == "athlon-4" || CPU == "athlon-xp" || CPU == "athlon-mp") {
1217 setFeatureEnabled(Features, "sse", true);
1218 setFeatureEnabled(Features, "3dnowa", true);
1219 } else if (CPU == "k8" || CPU == "opteron" || CPU == "athlon64" ||
1220 CPU == "athlon-fx") {
Mike Stump1eb44332009-09-09 15:08:12 +00001221 setFeatureEnabled(Features, "sse2", true);
Daniel Dunbar3ac79042009-05-06 21:56:32 +00001222 setFeatureEnabled(Features, "3dnowa", true);
Roman Divackyc8b09a12010-12-29 13:28:29 +00001223 } else if (CPU == "k8-sse3") {
1224 setFeatureEnabled(Features, "sse3", true);
1225 setFeatureEnabled(Features, "3dnowa", true);
Daniel Dunbar3ac79042009-05-06 21:56:32 +00001226 } else if (CPU == "c3-2")
1227 setFeatureEnabled(Features, "sse", true);
Daniel Dunbar868bd0a2009-05-06 03:16:41 +00001228}
1229
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001230bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
Mike Stump1eb44332009-09-09 15:08:12 +00001231 const std::string &Name,
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001232 bool Enabled) const {
Eric Christopherd39ebe22010-03-04 02:26:37 +00001233 // FIXME: This *really* should not be here. We need some way of translating
1234 // options into llvm subtarget features.
1235 if (!Features.count(Name) &&
1236 (Name != "sse4" && Name != "sse4.2" && Name != "sse4.1"))
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001237 return false;
1238
1239 if (Enabled) {
1240 if (Name == "mmx")
1241 Features["mmx"] = true;
1242 else if (Name == "sse")
Daniel Dunbarcb65de12011-05-03 15:34:01 +00001243 Features["mmx"] = Features["sse"] = true;
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001244 else if (Name == "sse2")
Daniel Dunbarcb65de12011-05-03 15:34:01 +00001245 Features["mmx"] = Features["sse"] = Features["sse2"] = true;
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001246 else if (Name == "sse3")
Daniel Dunbarcb65de12011-05-03 15:34:01 +00001247 Features["mmx"] = Features["sse"] = Features["sse2"] =
1248 Features["sse3"] = true;
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001249 else if (Name == "ssse3")
Daniel Dunbarcb65de12011-05-03 15:34:01 +00001250 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001251 Features["ssse3"] = true;
Eric Christopherd39ebe22010-03-04 02:26:37 +00001252 else if (Name == "sse4" || Name == "sse4.2")
Daniel Dunbarcb65de12011-05-03 15:34:01 +00001253 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001254 Features["ssse3"] = Features["sse41"] = Features["sse42"] = true;
Eric Christopherd39ebe22010-03-04 02:26:37 +00001255 else if (Name == "sse4.1")
Daniel Dunbarcb65de12011-05-03 15:34:01 +00001256 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Eric Christopherd39ebe22010-03-04 02:26:37 +00001257 Features["ssse3"] = Features["sse41"] = true;
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001258 else if (Name == "3dnow")
Daniel Dunbarcb65de12011-05-03 15:34:01 +00001259 Features["3dnowa"] = true;
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001260 else if (Name == "3dnowa")
Daniel Dunbarcb65de12011-05-03 15:34:01 +00001261 Features["3dnow"] = Features["3dnowa"] = true;
Eric Christophereea12d12010-04-02 23:50:19 +00001262 else if (Name == "aes")
Daniel Dunbarcb65de12011-05-03 15:34:01 +00001263 Features["aes"] = true;
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +00001264 else if (Name == "avx")
Daniel Dunbarcb65de12011-05-03 15:34:01 +00001265 Features["avx"] = true;
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001266 } else {
1267 if (Name == "mmx")
Daniel Dunbarcb65de12011-05-03 15:34:01 +00001268 Features["mmx"] = Features["3dnow"] = Features["3dnowa"] =
1269 Features["sse"] = Features["sse2"] = Features["sse3"] =
1270 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001271 else if (Name == "sse")
Mike Stump1eb44332009-09-09 15:08:12 +00001272 Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbarcb65de12011-05-03 15:34:01 +00001273 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001274 else if (Name == "sse2")
Mike Stump1eb44332009-09-09 15:08:12 +00001275 Features["sse2"] = Features["sse3"] = Features["ssse3"] =
Daniel Dunbarcb65de12011-05-03 15:34:01 +00001276 Features["sse41"] = Features["sse42"] = false;
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001277 else if (Name == "sse3")
Mike Stump1eb44332009-09-09 15:08:12 +00001278 Features["sse3"] = Features["ssse3"] = Features["sse41"] =
Daniel Dunbarcb65de12011-05-03 15:34:01 +00001279 Features["sse42"] = false;
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001280 else if (Name == "ssse3")
Daniel Dunbarcb65de12011-05-03 15:34:01 +00001281 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
Michael J. Spencerb24bac92011-04-17 19:22:03 +00001282 else if (Name == "sse4" || Name == "sse4.1")
Daniel Dunbarcb65de12011-05-03 15:34:01 +00001283 Features["sse41"] = Features["sse42"] = false;
Eric Christopherd41b4ec2010-03-04 02:31:44 +00001284 else if (Name == "sse4.2")
Daniel Dunbarcb65de12011-05-03 15:34:01 +00001285 Features["sse42"] = false;
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001286 else if (Name == "3dnow")
1287 Features["3dnow"] = Features["3dnowa"] = false;
1288 else if (Name == "3dnowa")
1289 Features["3dnowa"] = false;
Eric Christophereea12d12010-04-02 23:50:19 +00001290 else if (Name == "aes")
1291 Features["aes"] = false;
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +00001292 else if (Name == "avx")
1293 Features["avx"] = false;
Daniel Dunbar17ca3632009-05-06 21:07:50 +00001294 }
1295
1296 return true;
1297}
1298
Daniel Dunbar868bd0a2009-05-06 03:16:41 +00001299/// HandleTargetOptions - Perform initialization based on the user
1300/// configured set of features.
Daniel Dunbarb93292a2009-12-19 03:30:57 +00001301void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) {
Daniel Dunbar29a790b2009-11-11 09:38:56 +00001302 // Remember the maximum enabled sselevel.
1303 for (unsigned i = 0, e = Features.size(); i !=e; ++i) {
1304 // Ignore disabled features.
1305 if (Features[i][0] == '-')
1306 continue;
1307
Eric Christophereea12d12010-04-02 23:50:19 +00001308 if (Features[i].substr(1) == "aes") {
1309 HasAES = true;
1310 continue;
1311 }
1312
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +00001313 // FIXME: Not sure yet how to treat AVX in regard to SSE levels.
1314 // For now let it be enabled together with other SSE levels.
1315 if (Features[i].substr(1) == "avx") {
1316 HasAVX = true;
1317 continue;
1318 }
1319
Daniel Dunbar29a790b2009-11-11 09:38:56 +00001320 assert(Features[i][0] == '+' && "Invalid target feature!");
1321 X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Features[i].substr(1))
1322 .Case("sse42", SSE42)
1323 .Case("sse41", SSE41)
1324 .Case("ssse3", SSSE3)
Nuno Lopes33d3bca2010-03-12 10:20:09 +00001325 .Case("sse3", SSE3)
Daniel Dunbar29a790b2009-11-11 09:38:56 +00001326 .Case("sse2", SSE2)
1327 .Case("sse", SSE1)
1328 .Case("mmx", MMX)
1329 .Default(NoMMXSSE);
1330 SSELevel = std::max(SSELevel, Level);
Michael J. Spencer20249a12010-10-21 03:16:25 +00001331
1332 AMD3DNowEnum ThreeDNowLevel =
Anders Carlsson9b0fb622010-01-27 03:47:49 +00001333 llvm::StringSwitch<AMD3DNowEnum>(Features[i].substr(1))
1334 .Case("3dnowa", AMD3DNowAthlon)
1335 .Case("3dnow", AMD3DNow)
1336 .Default(NoAMD3DNow);
Michael J. Spencer20249a12010-10-21 03:16:25 +00001337
Anders Carlsson9b0fb622010-01-27 03:47:49 +00001338 AMD3DNowLevel = std::max(AMD3DNowLevel, ThreeDNowLevel);
Daniel Dunbar29a790b2009-11-11 09:38:56 +00001339 }
Chris Lattner3daed522009-03-02 22:20:04 +00001340}
Chris Lattnerc0f59212009-03-02 22:27:17 +00001341
1342/// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines
1343/// that are not tied to a specific subtarget.
Chris Lattner33328642009-03-20 15:52:06 +00001344void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001345 MacroBuilder &Builder) const {
Chris Lattnerc0f59212009-03-02 22:27:17 +00001346 // Target identification.
1347 if (PointerWidth == 64) {
Benjamin Kramera9992772010-01-09 17:55:51 +00001348 Builder.defineMacro("_LP64");
1349 Builder.defineMacro("__LP64__");
1350 Builder.defineMacro("__amd64__");
1351 Builder.defineMacro("__amd64");
1352 Builder.defineMacro("__x86_64");
1353 Builder.defineMacro("__x86_64__");
Chris Lattnerc0f59212009-03-02 22:27:17 +00001354 } else {
Benjamin Kramera9992772010-01-09 17:55:51 +00001355 DefineStd(Builder, "i386", Opts);
Chris Lattnerc0f59212009-03-02 22:27:17 +00001356 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001357
Eric Christophereea12d12010-04-02 23:50:19 +00001358 if (HasAES)
1359 Builder.defineMacro("__AES__");
1360
Bruno Cardoso Lopes7377ed92010-08-04 22:29:13 +00001361 if (HasAVX)
1362 Builder.defineMacro("__AVX__");
1363
Chris Lattnerc0f59212009-03-02 22:27:17 +00001364 // Target properties.
Benjamin Kramera9992772010-01-09 17:55:51 +00001365 Builder.defineMacro("__LITTLE_ENDIAN__");
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001366
Chris Lattnerc0f59212009-03-02 22:27:17 +00001367 // Subtarget options.
Benjamin Kramera9992772010-01-09 17:55:51 +00001368 Builder.defineMacro("__nocona");
1369 Builder.defineMacro("__nocona__");
1370 Builder.defineMacro("__tune_nocona__");
1371 Builder.defineMacro("__REGISTER_PREFIX__", "");
Chris Lattner84f0ea82009-03-02 22:40:39 +00001372
Chris Lattner54175442009-04-19 17:32:33 +00001373 // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline
1374 // functions in glibc header files that use FP Stack inline asm which the
1375 // backend can't deal with (PR879).
Benjamin Kramera9992772010-01-09 17:55:51 +00001376 Builder.defineMacro("__NO_MATH_INLINES");
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001377
Chris Lattner84f0ea82009-03-02 22:40:39 +00001378 // Each case falls through to the previous one here.
1379 switch (SSELevel) {
1380 case SSE42:
Benjamin Kramera9992772010-01-09 17:55:51 +00001381 Builder.defineMacro("__SSE4_2__");
Chris Lattner84f0ea82009-03-02 22:40:39 +00001382 case SSE41:
Benjamin Kramera9992772010-01-09 17:55:51 +00001383 Builder.defineMacro("__SSE4_1__");
Chris Lattner84f0ea82009-03-02 22:40:39 +00001384 case SSSE3:
Benjamin Kramera9992772010-01-09 17:55:51 +00001385 Builder.defineMacro("__SSSE3__");
Chris Lattner84f0ea82009-03-02 22:40:39 +00001386 case SSE3:
Benjamin Kramera9992772010-01-09 17:55:51 +00001387 Builder.defineMacro("__SSE3__");
Chris Lattner84f0ea82009-03-02 22:40:39 +00001388 case SSE2:
Benjamin Kramera9992772010-01-09 17:55:51 +00001389 Builder.defineMacro("__SSE2__");
1390 Builder.defineMacro("__SSE2_MATH__"); // -mfp-math=sse always implied.
Chris Lattner84f0ea82009-03-02 22:40:39 +00001391 case SSE1:
Benjamin Kramera9992772010-01-09 17:55:51 +00001392 Builder.defineMacro("__SSE__");
1393 Builder.defineMacro("__SSE_MATH__"); // -mfp-math=sse always implied.
Chris Lattner84f0ea82009-03-02 22:40:39 +00001394 case MMX:
Benjamin Kramera9992772010-01-09 17:55:51 +00001395 Builder.defineMacro("__MMX__");
Chris Lattner84f0ea82009-03-02 22:40:39 +00001396 case NoMMXSSE:
1397 break;
1398 }
Michael J. Spencer237cf582010-10-18 07:10:59 +00001399
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001400 if (Opts.Microsoft && PointerWidth == 32) {
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001401 switch (SSELevel) {
Michael J. Spencera764e832010-10-21 08:22:51 +00001402 case SSE42:
1403 case SSE41:
1404 case SSSE3:
1405 case SSE3:
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001406 case SSE2:
1407 Builder.defineMacro("_M_IX86_FP", llvm::Twine(2));
1408 break;
1409 case SSE1:
1410 Builder.defineMacro("_M_IX86_FP", llvm::Twine(1));
1411 break;
1412 default:
1413 Builder.defineMacro("_M_IX86_FP", llvm::Twine(0));
1414 }
1415 }
1416
Anders Carlsson9b0fb622010-01-27 03:47:49 +00001417 // Each case falls through to the previous one here.
1418 switch (AMD3DNowLevel) {
1419 case AMD3DNowAthlon:
1420 Builder.defineMacro("__3dNOW_A__");
1421 case AMD3DNow:
1422 Builder.defineMacro("__3dNOW__");
1423 case NoAMD3DNow:
1424 break;
1425 }
Chris Lattnerc0f59212009-03-02 22:27:17 +00001426}
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001427
1428
Eli Friedman618234a2008-08-20 02:34:37 +00001429bool
Anders Carlsson066d2ea2009-02-28 17:11:49 +00001430X86TargetInfo::validateAsmConstraint(const char *&Name,
Chris Lattner44def072009-04-26 07:16:29 +00001431 TargetInfo::ConstraintInfo &Info) const {
Anders Carlsson066d2ea2009-02-28 17:11:49 +00001432 switch (*Name) {
Eli Friedman618234a2008-08-20 02:34:37 +00001433 default: return false;
Dale Johannesen545be512010-08-24 22:33:12 +00001434 case 'Y': // first letter of a pair:
1435 switch (*(Name+1)) {
1436 default: return false;
1437 case '0': // First SSE register.
1438 case 't': // Any SSE register, when SSE2 is enabled.
1439 case 'i': // Any SSE register, when SSE2 and inter-unit moves enabled.
1440 case 'm': // any MMX register, when inter-unit moves enabled.
1441 break; // falls through to setAllowsRegister.
1442 }
Eli Friedman618234a2008-08-20 02:34:37 +00001443 case 'a': // eax.
1444 case 'b': // ebx.
1445 case 'c': // ecx.
1446 case 'd': // edx.
1447 case 'S': // esi.
1448 case 'D': // edi.
1449 case 'A': // edx:eax.
Dale Johannesen545be512010-08-24 22:33:12 +00001450 case 'f': // any x87 floating point stack register.
Eli Friedman618234a2008-08-20 02:34:37 +00001451 case 't': // top of floating point stack.
1452 case 'u': // second from top of floating point stack.
1453 case 'q': // Any register accessible as [r]l: a, b, c, and d.
Anders Carlssonfce09342008-10-06 00:41:45 +00001454 case 'y': // Any MMX register.
Anders Carlssona7406d42008-10-06 19:17:39 +00001455 case 'x': // Any SSE register.
Eli Friedman618234a2008-08-20 02:34:37 +00001456 case 'Q': // Any register accessible as [r]h: a, b, c, and d.
Dale Johannesen545be512010-08-24 22:33:12 +00001457 case 'R': // "Legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
1458 case 'l': // "Index" registers: any general register that can be used as an
1459 // index in a base+index memory access.
1460 Info.setAllowsRegister();
1461 return true;
1462 case 'C': // SSE floating point constant.
1463 case 'G': // x87 floating point constant.
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001464 case 'e': // 32-bit signed integer constant for use with zero-extending
Anders Carlsson79bc64c2009-01-24 18:03:09 +00001465 // x86_64 instructions.
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001466 case 'Z': // 32-bit unsigned integer constant for use with zero-extending
Anders Carlsson79bc64c2009-01-24 18:03:09 +00001467 // x86_64 instructions.
Eli Friedman618234a2008-08-20 02:34:37 +00001468 return true;
1469 }
Dale Johannesen545be512010-08-24 22:33:12 +00001470 return false;
Eli Friedman618234a2008-08-20 02:34:37 +00001471}
1472
Dale Johannesenf6e2c202010-10-29 23:12:32 +00001473
Eli Friedman618234a2008-08-20 02:34:37 +00001474std::string
Stuart Hastings002333f2011-06-07 23:45:05 +00001475X86TargetInfo::convertConstraint(const char *&Constraint) const {
1476 switch (*Constraint) {
Eli Friedman618234a2008-08-20 02:34:37 +00001477 case 'a': return std::string("{ax}");
1478 case 'b': return std::string("{bx}");
1479 case 'c': return std::string("{cx}");
1480 case 'd': return std::string("{dx}");
1481 case 'S': return std::string("{si}");
1482 case 'D': return std::string("{di}");
Dale Johannesencee55012010-10-22 21:07:10 +00001483 case 'p': // address
1484 return std::string("im");
Eli Friedman618234a2008-08-20 02:34:37 +00001485 case 't': // top of floating point stack.
1486 return std::string("{st}");
1487 case 'u': // second from top of floating point stack.
1488 return std::string("{st(1)}"); // second from top of floating point stack.
1489 default:
Stuart Hastings002333f2011-06-07 23:45:05 +00001490 return std::string(1, *Constraint);
Eli Friedman618234a2008-08-20 02:34:37 +00001491 }
1492}
Eli Friedman618234a2008-08-20 02:34:37 +00001493} // end anonymous namespace
Reid Spencer5f016e22007-07-11 17:01:13 +00001494
1495namespace {
Eli Friedman618234a2008-08-20 02:34:37 +00001496// X86-32 generic target
1497class X86_32TargetInfo : public X86TargetInfo {
Reid Spencer5f016e22007-07-11 17:01:13 +00001498public:
Eli Friedman618234a2008-08-20 02:34:37 +00001499 X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
1500 DoubleAlign = LongLongAlign = 32;
1501 LongDoubleWidth = 96;
1502 LongDoubleAlign = 32;
Eli Friedmaned855cb2008-08-21 00:13:15 +00001503 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1504 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
Chris Lattner1932e122009-11-07 18:59:41 +00001505 "a0:0:64-f80:32:32-n8:16:32";
Eli Friedman1afabd92009-03-29 20:31:09 +00001506 SizeType = UnsignedInt;
1507 PtrDiffType = SignedInt;
1508 IntPtrType = SignedInt;
Anton Korobeynikov264a76c2009-04-03 23:38:25 +00001509 RegParmMax = 3;
Daniel Dunbardacf9dd2010-07-14 23:39:36 +00001510
1511 // Use fpret for all types.
1512 RealTypeUsesObjCFPRet = ((1 << TargetInfo::Float) |
1513 (1 << TargetInfo::Double) |
1514 (1 << TargetInfo::LongDouble));
Eli Friedman618234a2008-08-20 02:34:37 +00001515 }
1516 virtual const char *getVAListDeclaration() const {
Eli Friedman01b86682008-08-20 07:28:14 +00001517 return "typedef char* __builtin_va_list;";
Eli Friedman618234a2008-08-20 02:34:37 +00001518 }
Michael J. Spencer20249a12010-10-21 03:16:25 +00001519
Chris Lattner21fb98e2009-09-23 06:06:36 +00001520 int getEHDataRegisterNumber(unsigned RegNo) const {
1521 if (RegNo == 0) return 0;
1522 if (RegNo == 1) return 2;
1523 return -1;
1524 }
Eli Friedman618234a2008-08-20 02:34:37 +00001525};
1526} // end anonymous namespace
1527
1528namespace {
Eli Friedman624c1462009-07-05 18:47:56 +00001529class OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> {
1530public:
1531 OpenBSDI386TargetInfo(const std::string& triple) :
1532 OpenBSDTargetInfo<X86_32TargetInfo>(triple) {
1533 SizeType = UnsignedLong;
1534 IntPtrType = SignedLong;
Eli Friedman6036ebe2009-07-05 22:31:18 +00001535 PtrDiffType = SignedLong;
Eli Friedman624c1462009-07-05 18:47:56 +00001536 }
1537};
1538} // end anonymous namespace
1539
1540namespace {
Torok Edwin5f6c1942009-06-30 17:10:35 +00001541class DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> {
Eli Friedman618234a2008-08-20 02:34:37 +00001542public:
Torok Edwin5f6c1942009-06-30 17:10:35 +00001543 DarwinI386TargetInfo(const std::string& triple) :
1544 DarwinTargetInfo<X86_32TargetInfo>(triple) {
Eli Friedman618234a2008-08-20 02:34:37 +00001545 LongDoubleWidth = 128;
1546 LongDoubleAlign = 128;
Eli Friedman1afabd92009-03-29 20:31:09 +00001547 SizeType = UnsignedLong;
1548 IntPtrType = SignedLong;
Eli Friedmaned855cb2008-08-21 00:13:15 +00001549 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1550 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
Chris Lattner1932e122009-11-07 18:59:41 +00001551 "a0:0:64-f80:128:128-n8:16:32";
Daniel Dunbar613fd672010-05-27 00:35:16 +00001552 HasAlignMac68kSupport = true;
Torok Edwinb0a5b242009-06-30 17:00:25 +00001553 }
1554
Eli Friedman618234a2008-08-20 02:34:37 +00001555};
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +00001556} // end anonymous namespace
1557
1558namespace {
Eli Friedman29a30502008-08-21 01:40:19 +00001559// x86-32 Windows target
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001560class WindowsX86_32TargetInfo : public WindowsTargetInfo<X86_32TargetInfo> {
Eli Friedman29a30502008-08-21 01:40:19 +00001561public:
1562 WindowsX86_32TargetInfo(const std::string& triple)
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001563 : WindowsTargetInfo<X86_32TargetInfo>(triple) {
Eli Friedmanb030f022009-04-19 21:38:35 +00001564 TLSSupported = false;
Chris Lattner85de9e72009-06-24 17:12:15 +00001565 WCharType = UnsignedShort;
Eli Friedman9c2f84e2009-06-08 21:16:17 +00001566 DoubleAlign = LongLongAlign = 64;
1567 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
Anton Korobeynikovb3814412009-12-19 02:05:07 +00001568 "i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-"
1569 "v128:128:128-a0:0:64-f80:32:32-n8:16:32";
Eli Friedman29a30502008-08-21 01:40:19 +00001570 }
Michael J. Spencera764e832010-10-21 08:22:51 +00001571 virtual void getTargetDefines(const LangOptions &Opts,
1572 MacroBuilder &Builder) const {
1573 WindowsTargetInfo<X86_32TargetInfo>::getTargetDefines(Opts, Builder);
1574 }
1575};
1576} // end anonymous namespace
1577
1578namespace {
1579
1580// x86-32 Windows Visual Studio target
1581class VisualStudioWindowsX86_32TargetInfo : public WindowsX86_32TargetInfo {
1582public:
1583 VisualStudioWindowsX86_32TargetInfo(const std::string& triple)
1584 : WindowsX86_32TargetInfo(triple) {
Eli Friedmand9c3fa32011-03-22 21:25:11 +00001585 LongDoubleWidth = LongDoubleAlign = 64;
Michael J. Spencera764e832010-10-21 08:22:51 +00001586 LongDoubleFormat = &llvm::APFloat::IEEEdouble;
1587 }
1588 virtual void getTargetDefines(const LangOptions &Opts,
1589 MacroBuilder &Builder) const {
1590 WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
1591 WindowsX86_32TargetInfo::getVisualStudioDefines(Opts, Builder);
1592 // The value of the following reflects processor type.
1593 // 300=386, 400=486, 500=Pentium, 600=Blend (default)
1594 // We lost the original triple, so we use the default.
1595 Builder.defineMacro("_M_IX86", "600");
1596 }
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001597};
1598} // end anonymous namespace
1599
1600namespace {
1601// x86-32 MinGW target
1602class MinGWX86_32TargetInfo : public WindowsX86_32TargetInfo {
1603public:
1604 MinGWX86_32TargetInfo(const std::string& triple)
1605 : WindowsX86_32TargetInfo(triple) {
1606 }
1607 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001608 MacroBuilder &Builder) const {
1609 WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
Michael J. Spencera764e832010-10-21 08:22:51 +00001610 DefineStd(Builder, "WIN32", Opts);
1611 DefineStd(Builder, "WINNT", Opts);
1612 Builder.defineMacro("_X86_");
Benjamin Kramera9992772010-01-09 17:55:51 +00001613 Builder.defineMacro("__MSVCRT__");
1614 Builder.defineMacro("__MINGW32__");
NAKAMURA Takumi853134a2011-03-15 02:32:50 +00001615
1616 // mingw32-gcc provides __declspec(a) as alias of __attribute__((a)).
1617 // In contrast, clang-cc1 provides __declspec(a) with -fms-extensions.
1618 if (Opts.Microsoft)
1619 // Provide "as-is" __declspec.
1620 Builder.defineMacro("__declspec", "__declspec");
1621 else
1622 // Provide alias of __attribute__ like mingw32-gcc.
1623 Builder.defineMacro("__declspec(a)", "__attribute__((a))");
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001624 }
1625};
1626} // end anonymous namespace
1627
1628namespace {
1629// x86-32 Cygwin target
1630class CygwinX86_32TargetInfo : public X86_32TargetInfo {
1631public:
1632 CygwinX86_32TargetInfo(const std::string& triple)
1633 : X86_32TargetInfo(triple) {
1634 TLSSupported = false;
1635 WCharType = UnsignedShort;
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001636 DoubleAlign = LongLongAlign = 64;
1637 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1638 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
Chris Lattner1932e122009-11-07 18:59:41 +00001639 "a0:0:64-f80:32:32-n8:16:32";
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001640 }
1641 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001642 MacroBuilder &Builder) const {
1643 X86_32TargetInfo::getTargetDefines(Opts, Builder);
1644 Builder.defineMacro("__CYGWIN__");
1645 Builder.defineMacro("__CYGWIN32__");
1646 DefineStd(Builder, "unix", Opts);
Douglas Gregor2b003fd2010-04-21 05:52:38 +00001647 if (Opts.CPlusPlus)
1648 Builder.defineMacro("_GNU_SOURCE");
Eli Friedmanabc4e322009-06-08 06:11:14 +00001649 }
Eli Friedman29a30502008-08-21 01:40:19 +00001650};
1651} // end anonymous namespace
1652
1653namespace {
Chris Lattner86ed3a32010-04-11 19:29:39 +00001654// x86-32 Haiku target
1655class HaikuX86_32TargetInfo : public X86_32TargetInfo {
1656public:
1657 HaikuX86_32TargetInfo(const std::string& triple)
1658 : X86_32TargetInfo(triple) {
1659 SizeType = UnsignedLong;
Chris Lattnerfe1ea7b2010-04-22 17:48:00 +00001660 IntPtrType = SignedLong;
1661 PtrDiffType = SignedLong;
Rafael Espindola19ddda82010-11-09 16:41:02 +00001662 this->UserLabelPrefix = "";
Eli Friedmana7e68452010-08-22 01:00:03 +00001663 }
Chris Lattner86ed3a32010-04-11 19:29:39 +00001664 virtual void getTargetDefines(const LangOptions &Opts,
1665 MacroBuilder &Builder) const {
1666 X86_32TargetInfo::getTargetDefines(Opts, Builder);
1667 Builder.defineMacro("__INTEL__");
1668 Builder.defineMacro("__HAIKU__");
1669 }
1670};
1671} // end anonymous namespace
1672
Douglas Gregordca52262011-07-01 22:41:14 +00001673// RTEMS Target
1674template<typename Target>
1675class RTEMSTargetInfo : public OSTargetInfo<Target> {
1676protected:
1677 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
1678 MacroBuilder &Builder) const {
1679 // RTEMS defines; list based off of gcc output
1680
1681 // FIXME: Move version number handling to llvm::Triple.
1682 llvm::StringRef Release = Triple.getOSName().substr(strlen("rtems"), 1);
1683
1684 Builder.defineMacro("__rtems__");
1685 Builder.defineMacro("__ELF__");
1686 }
1687public:
1688 RTEMSTargetInfo(const std::string &triple)
1689 : OSTargetInfo<Target>(triple) {
1690 this->UserLabelPrefix = "";
1691
1692 llvm::Triple Triple(triple);
1693 switch (Triple.getArch()) {
1694 default:
1695 case llvm::Triple::x86:
1696 // this->MCountName = ".mcount";
1697 break;
1698 case llvm::Triple::mips:
1699 case llvm::Triple::mipsel:
1700 case llvm::Triple::ppc:
1701 case llvm::Triple::ppc64:
1702 // this->MCountName = "_mcount";
1703 break;
1704 case llvm::Triple::arm:
1705 // this->MCountName = "__mcount";
1706 break;
1707 }
1708
1709 }
1710};
1711
1712namespace {
1713// x86-32 RTEMS target
1714class RTEMSX86_32TargetInfo : public X86_32TargetInfo {
1715public:
1716 RTEMSX86_32TargetInfo(const std::string& triple)
1717 : X86_32TargetInfo(triple) {
1718 SizeType = UnsignedLong;
1719 IntPtrType = SignedLong;
1720 PtrDiffType = SignedLong;
1721 this->UserLabelPrefix = "";
1722 }
1723 virtual void getTargetDefines(const LangOptions &Opts,
1724 MacroBuilder &Builder) const {
1725 X86_32TargetInfo::getTargetDefines(Opts, Builder);
1726 Builder.defineMacro("__INTEL__");
1727 Builder.defineMacro("__rtems__");
1728 }
1729};
1730} // end anonymous namespace
1731
Chris Lattner86ed3a32010-04-11 19:29:39 +00001732namespace {
Eli Friedman618234a2008-08-20 02:34:37 +00001733// x86-64 generic target
1734class X86_64TargetInfo : public X86TargetInfo {
1735public:
Chris Lattner33328642009-03-20 15:52:06 +00001736 X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) {
Chris Lattnerf291b102008-05-09 06:17:04 +00001737 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedman61538a72008-05-20 14:21:01 +00001738 LongDoubleWidth = 128;
1739 LongDoubleAlign = 128;
Rafael Espindola6deecb02010-06-04 23:15:27 +00001740 LargeArrayMinWidth = 128;
1741 LargeArrayAlign = 128;
Chris Lattner06ebe862009-02-05 07:32:46 +00001742 IntMaxType = SignedLong;
1743 UIntMaxType = UnsignedLong;
Eli Friedman3c7b6e42009-07-01 03:36:11 +00001744 Int64Type = SignedLong;
Anton Korobeynikov264a76c2009-04-03 23:38:25 +00001745 RegParmMax = 6;
Chris Lattner06ebe862009-02-05 07:32:46 +00001746
Eli Friedmaned855cb2008-08-21 00:13:15 +00001747 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1748 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
Chris Lattner1932e122009-11-07 18:59:41 +00001749 "a0:0:64-s0:64:64-f80:128:128-n8:16:32:64";
Daniel Dunbardacf9dd2010-07-14 23:39:36 +00001750
1751 // Use fpret only for long double.
1752 RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble);
Reid Spencer5f016e22007-07-11 17:01:13 +00001753 }
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +00001754 virtual const char *getVAListDeclaration() const {
Eli Friedman01b86682008-08-20 07:28:14 +00001755 return "typedef struct __va_list_tag {"
1756 " unsigned gp_offset;"
1757 " unsigned fp_offset;"
1758 " void* overflow_arg_area;"
1759 " void* reg_save_area;"
John McCall2b7baf02010-05-28 18:25:28 +00001760 "} __va_list_tag;"
Eli Friedmandc043162009-07-03 00:45:06 +00001761 "typedef __va_list_tag __builtin_va_list[1];";
Anders Carlsson3346ae62007-11-24 23:38:12 +00001762 }
Michael J. Spencer237cf582010-10-18 07:10:59 +00001763
Chris Lattner21fb98e2009-09-23 06:06:36 +00001764 int getEHDataRegisterNumber(unsigned RegNo) const {
1765 if (RegNo == 0) return 0;
1766 if (RegNo == 1) return 1;
1767 return -1;
1768 }
Eli Friedman618234a2008-08-20 02:34:37 +00001769};
1770} // end anonymous namespace
1771
1772namespace {
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001773// x86-64 Windows target
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001774class WindowsX86_64TargetInfo : public WindowsTargetInfo<X86_64TargetInfo> {
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001775public:
1776 WindowsX86_64TargetInfo(const std::string& triple)
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001777 : WindowsTargetInfo<X86_64TargetInfo>(triple) {
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001778 TLSSupported = false;
1779 WCharType = UnsignedShort;
Mike Stumpa55cce82009-10-08 23:00:00 +00001780 LongWidth = LongAlign = 32;
Michael J. Spencer237cf582010-10-18 07:10:59 +00001781 DoubleAlign = LongLongAlign = 64;
Nate Begemandbf8ea42010-07-21 02:02:56 +00001782 IntMaxType = SignedLongLong;
1783 UIntMaxType = UnsignedLongLong;
1784 Int64Type = SignedLongLong;
Cameron Esfahani1484e0d2010-09-15 00:28:12 +00001785 SizeType = UnsignedLongLong;
1786 PtrDiffType = SignedLongLong;
1787 IntPtrType = SignedLongLong;
NAKAMURA Takumi8c959d92011-01-17 22:56:08 +00001788 this->UserLabelPrefix = "";
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001789 }
1790 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001791 MacroBuilder &Builder) const {
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001792 WindowsTargetInfo<X86_64TargetInfo>::getTargetDefines(Opts, Builder);
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001793 Builder.defineMacro("_WIN64");
Michael J. Spencera764e832010-10-21 08:22:51 +00001794 }
NAKAMURA Takumi79521992011-01-17 22:56:23 +00001795 virtual const char *getVAListDeclaration() const {
1796 return "typedef char* __builtin_va_list;";
1797 }
Michael J. Spencera764e832010-10-21 08:22:51 +00001798};
1799} // end anonymous namespace
1800
1801namespace {
1802// x86-64 Windows Visual Studio target
1803class VisualStudioWindowsX86_64TargetInfo : public WindowsX86_64TargetInfo {
1804public:
1805 VisualStudioWindowsX86_64TargetInfo(const std::string& triple)
1806 : WindowsX86_64TargetInfo(triple) {
Eli Friedmand9c3fa32011-03-22 21:25:11 +00001807 LongDoubleWidth = LongDoubleAlign = 64;
1808 LongDoubleFormat = &llvm::APFloat::IEEEdouble;
Michael J. Spencera764e832010-10-21 08:22:51 +00001809 }
1810 virtual void getTargetDefines(const LangOptions &Opts,
1811 MacroBuilder &Builder) const {
1812 WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
1813 WindowsX86_64TargetInfo::getVisualStudioDefines(Opts, Builder);
Benjamin Kramera9992772010-01-09 17:55:51 +00001814 Builder.defineMacro("_M_X64");
Michael J. Spencerdae4ac42010-10-21 05:21:48 +00001815 Builder.defineMacro("_M_AMD64");
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001816 }
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001817};
1818} // end anonymous namespace
1819
1820namespace {
1821// x86-64 MinGW target
1822class MinGWX86_64TargetInfo : public WindowsX86_64TargetInfo {
1823public:
1824 MinGWX86_64TargetInfo(const std::string& triple)
1825 : WindowsX86_64TargetInfo(triple) {
1826 }
1827 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00001828 MacroBuilder &Builder) const {
1829 WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
Michael J. Spencera764e832010-10-21 08:22:51 +00001830 DefineStd(Builder, "WIN64", Opts);
Benjamin Kramera9992772010-01-09 17:55:51 +00001831 Builder.defineMacro("__MSVCRT__");
NAKAMURA Takumi17c964a2011-03-08 12:06:46 +00001832 Builder.defineMacro("__MINGW32__");
Benjamin Kramera9992772010-01-09 17:55:51 +00001833 Builder.defineMacro("__MINGW64__");
NAKAMURA Takumi853134a2011-03-15 02:32:50 +00001834
1835 // mingw32-gcc provides __declspec(a) as alias of __attribute__((a)).
1836 // In contrast, clang-cc1 provides __declspec(a) with -fms-extensions.
1837 if (Opts.Microsoft)
1838 // Provide "as-is" __declspec.
1839 Builder.defineMacro("__declspec", "__declspec");
1840 else
1841 // Provide alias of __attribute__ like mingw32-gcc.
1842 Builder.defineMacro("__declspec(a)", "__attribute__((a))");
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00001843 }
1844};
1845} // end anonymous namespace
1846
1847namespace {
Eli Friedman3c7b6e42009-07-01 03:36:11 +00001848class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> {
1849public:
Mike Stump1eb44332009-09-09 15:08:12 +00001850 DarwinX86_64TargetInfo(const std::string& triple)
Eli Friedman3c7b6e42009-07-01 03:36:11 +00001851 : DarwinTargetInfo<X86_64TargetInfo>(triple) {
1852 Int64Type = SignedLongLong;
1853 }
1854};
1855} // end anonymous namespace
1856
1857namespace {
Eli Friedman6036ebe2009-07-05 22:31:18 +00001858class OpenBSDX86_64TargetInfo : public OpenBSDTargetInfo<X86_64TargetInfo> {
1859public:
Mike Stump1eb44332009-09-09 15:08:12 +00001860 OpenBSDX86_64TargetInfo(const std::string& triple)
Eli Friedman6036ebe2009-07-05 22:31:18 +00001861 : OpenBSDTargetInfo<X86_64TargetInfo>(triple) {
1862 IntMaxType = SignedLongLong;
1863 UIntMaxType = UnsignedLongLong;
1864 Int64Type = SignedLongLong;
1865 }
1866};
1867} // end anonymous namespace
1868
1869namespace {
Eli Friedmana9f54962008-08-20 07:44:10 +00001870class ARMTargetInfo : public TargetInfo {
Daniel Dunbara91320b2009-12-21 23:28:17 +00001871 // Possible FPU choices.
1872 enum FPUMode {
1873 NoFPU,
1874 VFP2FPU,
1875 VFP3FPU,
1876 NeonFPU
1877 };
1878
1879 static bool FPUModeIsVFP(FPUMode Mode) {
1880 return Mode >= VFP2FPU && Mode <= NeonFPU;
1881 }
1882
1883 static const TargetInfo::GCCRegAlias GCCRegAliases[];
1884 static const char * const GCCRegNames[];
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00001885
Daniel Dunbareac7c532009-12-18 18:42:37 +00001886 std::string ABI, CPU;
Daniel Dunbara91320b2009-12-21 23:28:17 +00001887
1888 unsigned FPU : 3;
1889
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001890 unsigned IsThumb : 1;
1891
1892 // Initialized via features.
1893 unsigned SoftFloat : 1;
1894 unsigned SoftFloatABI : 1;
Daniel Dunbar018ba5a2009-09-14 00:35:03 +00001895
Chris Lattner2752c012010-03-03 19:03:45 +00001896 static const Builtin::Info BuiltinInfo[];
1897
Chris Lattner393ff042008-04-21 18:56:49 +00001898public:
Daniel Dunbare1f63b32009-09-17 16:21:10 +00001899 ARMTargetInfo(const std::string &TripleStr)
Daniel Dunbareac7c532009-12-18 18:42:37 +00001900 : TargetInfo(TripleStr), ABI("aapcs-linux"), CPU("arm1136j-s")
Daniel Dunbar018ba5a2009-09-14 00:35:03 +00001901 {
Daniel Dunbara2a41612009-09-14 00:02:24 +00001902 SizeType = UnsignedInt;
1903 PtrDiffType = SignedInt;
Daniel Dunbare1f63b32009-09-17 16:21:10 +00001904
Chris Lattner9bffb072010-04-23 16:29:58 +00001905 // {} in inline assembly are neon specifiers, not assembly variant
1906 // specifiers.
1907 NoAsmVariants = true;
Michael J. Spencer20249a12010-10-21 03:16:25 +00001908
Daniel Dunbareac7c532009-12-18 18:42:37 +00001909 // FIXME: Should we just treat this as a feature?
Daniel Dunbar0791aa52009-12-18 19:57:13 +00001910 IsThumb = getTriple().getArchName().startswith("thumb");
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001911 if (IsThumb) {
Sandeep Patel3a41d142011-04-04 22:58:12 +00001912 // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
1913 // so set preferred for small types to 32.
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001914 DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
1915 "i64:64:64-f32:32:32-f64:64:64-"
Bob Wilsoncd5ce092011-04-04 16:53:11 +00001916 "v64:64:64-v128:64:128-a0:0:32-n32");
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001917 } else {
1918 DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1919 "i64:64:64-f32:32:32-f64:64:64-"
Bob Wilsoncd5ce092011-04-04 16:53:11 +00001920 "v64:64:64-v128:64:128-a0:0:64-n32");
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001921 }
John McCallee79a4c2010-08-21 22:46:04 +00001922
1923 // ARM targets default to using the ARM C++ ABI.
1924 CXXABI = CXXABI_ARM;
Eli Friedman61538a72008-05-20 14:21:01 +00001925 }
Daniel Dunbar018ba5a2009-09-14 00:35:03 +00001926 virtual const char *getABI() const { return ABI.c_str(); }
Daniel Dunbara2a41612009-09-14 00:02:24 +00001927 virtual bool setABI(const std::string &Name) {
Daniel Dunbar018ba5a2009-09-14 00:35:03 +00001928 ABI = Name;
1929
Daniel Dunbara2a41612009-09-14 00:02:24 +00001930 // The defaults (above) are for AAPCS, check if we need to change them.
1931 //
1932 // FIXME: We need support for -meabi... we could just mangle it into the
1933 // name.
1934 if (Name == "apcs-gnu") {
Daniel Dunbard410fa22010-01-27 20:23:08 +00001935 DoubleAlign = LongLongAlign = LongDoubleAlign = 32;
Daniel Dunbara2a41612009-09-14 00:02:24 +00001936 SizeType = UnsignedLong;
1937
Daniel Dunbar684de632010-04-22 16:14:54 +00001938 // Do not respect the alignment of bit-field types when laying out
1939 // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
1940 UseBitFieldTypeAlignment = false;
1941
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001942 if (IsThumb) {
Sandeep Patel3a41d142011-04-04 22:58:12 +00001943 // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
1944 // so set preferred for small types to 32.
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001945 DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
Bob Wilson949fd1a2011-06-29 16:09:20 +00001946 "i64:32:64-f32:32:32-f64:32:64-"
Bob Wilsoncd5ce092011-04-04 16:53:11 +00001947 "v64:32:64-v128:32:128-a0:0:32-n32");
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001948 } else {
1949 DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
Bob Wilsoncd5ce092011-04-04 16:53:11 +00001950 "i64:32:64-f32:32:32-f64:32:64-"
1951 "v64:32:64-v128:32:128-a0:0:32-n32");
Daniel Dunbardff10dc2009-09-22 21:44:58 +00001952 }
1953
Daniel Dunbara2a41612009-09-14 00:02:24 +00001954 // FIXME: Override "preferred align" for double and long long.
1955 } else if (Name == "aapcs") {
1956 // FIXME: Enumerated types are variable width in straight AAPCS.
1957 } else if (Name == "aapcs-linux") {
1958 ;
1959 } else
1960 return false;
1961
1962 return true;
1963 }
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001964
Daniel Dunbara91320b2009-12-21 23:28:17 +00001965 void getDefaultFeatures(const std::string &CPU,
1966 llvm::StringMap<bool> &Features) const {
1967 // FIXME: This should not be here.
1968 Features["vfp2"] = false;
1969 Features["vfp3"] = false;
1970 Features["neon"] = false;
1971
1972 if (CPU == "arm1136jf-s" || CPU == "arm1176jzf-s" || CPU == "mpcore")
1973 Features["vfp2"] = true;
1974 else if (CPU == "cortex-a8" || CPU == "cortex-a9")
1975 Features["neon"] = true;
1976 }
Michael J. Spencer20249a12010-10-21 03:16:25 +00001977
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001978 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
1979 const std::string &Name,
1980 bool Enabled) const {
Daniel Dunbara91320b2009-12-21 23:28:17 +00001981 if (Name == "soft-float" || Name == "soft-float-abi") {
1982 Features[Name] = Enabled;
1983 } else if (Name == "vfp2" || Name == "vfp3" || Name == "neon") {
1984 // These effectively are a single option, reset them when any is enabled.
1985 if (Enabled)
1986 Features["vfp2"] = Features["vfp3"] = Features["neon"] = false;
1987 Features[Name] = Enabled;
1988 } else
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001989 return false;
1990
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001991 return true;
1992 }
1993
1994 virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
Daniel Dunbara91320b2009-12-21 23:28:17 +00001995 FPU = NoFPU;
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00001996 SoftFloat = SoftFloatABI = false;
1997 for (unsigned i = 0, e = Features.size(); i != e; ++i) {
1998 if (Features[i] == "+soft-float")
1999 SoftFloat = true;
2000 else if (Features[i] == "+soft-float-abi")
2001 SoftFloatABI = true;
Daniel Dunbara91320b2009-12-21 23:28:17 +00002002 else if (Features[i] == "+vfp2")
2003 FPU = VFP2FPU;
2004 else if (Features[i] == "+vfp3")
2005 FPU = VFP3FPU;
2006 else if (Features[i] == "+neon")
2007 FPU = NeonFPU;
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00002008 }
2009
2010 // Remove front-end specific options which the backend handles differently.
2011 std::vector<std::string>::iterator it;
2012 it = std::find(Features.begin(), Features.end(), "+soft-float");
2013 if (it != Features.end())
2014 Features.erase(it);
2015 it = std::find(Features.begin(), Features.end(), "+soft-float-abi");
2016 if (it != Features.end())
2017 Features.erase(it);
2018 }
2019
Daniel Dunbareac7c532009-12-18 18:42:37 +00002020 static const char *getCPUDefineSuffix(llvm::StringRef Name) {
2021 return llvm::StringSwitch<const char*>(Name)
2022 .Cases("arm8", "arm810", "4")
2023 .Cases("strongarm", "strongarm110", "strongarm1100", "strongarm1110", "4")
2024 .Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "arm720t", "arm9", "4T")
2025 .Cases("arm9tdmi", "arm920", "arm920t", "arm922t", "arm940t", "4T")
2026 .Case("ep9312", "4T")
2027 .Cases("arm10tdmi", "arm1020t", "5T")
2028 .Cases("arm9e", "arm946e-s", "arm966e-s", "arm968e-s", "5TE")
2029 .Case("arm926ej-s", "5TEJ")
2030 .Cases("arm10e", "arm1020e", "arm1022e", "5TE")
2031 .Cases("xscale", "iwmmxt", "5TE")
Daniel Dunbara91320b2009-12-21 23:28:17 +00002032 .Case("arm1136j-s", "6J")
Daniel Dunbareac7c532009-12-18 18:42:37 +00002033 .Cases("arm1176jz-s", "arm1176jzf-s", "6ZK")
Daniel Dunbara91320b2009-12-21 23:28:17 +00002034 .Cases("arm1136jf-s", "mpcorenovfp", "mpcore", "6K")
Daniel Dunbareac7c532009-12-18 18:42:37 +00002035 .Cases("arm1156t2-s", "arm1156t2f-s", "6T2")
2036 .Cases("cortex-a8", "cortex-a9", "7A")
Bob Wilson06f45632011-01-06 16:57:20 +00002037 .Case("cortex-m3", "7M")
Bob Wilsona291d5f2011-03-21 21:55:25 +00002038 .Case("cortex-m0", "6M")
Daniel Dunbareac7c532009-12-18 18:42:37 +00002039 .Default(0);
2040 }
2041 virtual bool setCPU(const std::string &Name) {
2042 if (!getCPUDefineSuffix(Name))
2043 return false;
2044
2045 CPU = Name;
2046 return true;
2047 }
Chris Lattner33328642009-03-20 15:52:06 +00002048 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002049 MacroBuilder &Builder) const {
Chris Lattnerc0f59212009-03-02 22:27:17 +00002050 // Target identification.
Benjamin Kramera9992772010-01-09 17:55:51 +00002051 Builder.defineMacro("__arm");
2052 Builder.defineMacro("__arm__");
Anton Korobeynikova7c47172009-05-03 13:42:53 +00002053
Chris Lattnerc0f59212009-03-02 22:27:17 +00002054 // Target properties.
Benjamin Kramera9992772010-01-09 17:55:51 +00002055 Builder.defineMacro("__ARMEL__");
2056 Builder.defineMacro("__LITTLE_ENDIAN__");
2057 Builder.defineMacro("__REGISTER_PREFIX__", "");
Daniel Dunbareac7c532009-12-18 18:42:37 +00002058
2059 llvm::StringRef CPUArch = getCPUDefineSuffix(CPU);
Benjamin Kramera9992772010-01-09 17:55:51 +00002060 Builder.defineMacro("__ARM_ARCH_" + CPUArch + "__");
Anton Korobeynikova7c47172009-05-03 13:42:53 +00002061
Mike Stump437bb4b2009-04-08 02:07:04 +00002062 // Subtarget options.
Daniel Dunbare1f63b32009-09-17 16:21:10 +00002063
Daniel Dunbareac7c532009-12-18 18:42:37 +00002064 // FIXME: It's more complicated than this and we don't really support
2065 // interworking.
2066 if ('5' <= CPUArch[0] && CPUArch[0] <= '7')
Benjamin Kramera9992772010-01-09 17:55:51 +00002067 Builder.defineMacro("__THUMB_INTERWORK__");
Daniel Dunbareac7c532009-12-18 18:42:37 +00002068
Daniel Dunbareac7c532009-12-18 18:42:37 +00002069 if (ABI == "aapcs" || ABI == "aapcs-linux")
Benjamin Kramera9992772010-01-09 17:55:51 +00002070 Builder.defineMacro("__ARM_EABI__");
Daniel Dunbareac7c532009-12-18 18:42:37 +00002071
Daniel Dunbar97f52ac2009-12-19 04:15:38 +00002072 if (SoftFloat)
Benjamin Kramera9992772010-01-09 17:55:51 +00002073 Builder.defineMacro("__SOFTFP__");
Daniel Dunbareac7c532009-12-18 18:42:37 +00002074
2075 if (CPU == "xscale")
Benjamin Kramera9992772010-01-09 17:55:51 +00002076 Builder.defineMacro("__XSCALE__");
Daniel Dunbare1f63b32009-09-17 16:21:10 +00002077
Bob Wilson84f95cf2011-05-13 18:56:03 +00002078 bool IsARMv7 = CPUArch.startswith("7");
Daniel Dunbare1f63b32009-09-17 16:21:10 +00002079 if (IsThumb) {
Benjamin Kramera9992772010-01-09 17:55:51 +00002080 Builder.defineMacro("__THUMBEL__");
2081 Builder.defineMacro("__thumb__");
Bob Wilson84f95cf2011-05-13 18:56:03 +00002082 if (CPUArch == "6T2" || IsARMv7)
Benjamin Kramera9992772010-01-09 17:55:51 +00002083 Builder.defineMacro("__thumb2__");
Daniel Dunbare1f63b32009-09-17 16:21:10 +00002084 }
2085
2086 // Note, this is always on in gcc, even though it doesn't make sense.
Benjamin Kramera9992772010-01-09 17:55:51 +00002087 Builder.defineMacro("__APCS_32__");
Daniel Dunbara91320b2009-12-21 23:28:17 +00002088
2089 if (FPUModeIsVFP((FPUMode) FPU))
Benjamin Kramera9992772010-01-09 17:55:51 +00002090 Builder.defineMacro("__VFP_FP__");
Daniel Dunbara91320b2009-12-21 23:28:17 +00002091
2092 // This only gets set when Neon instructions are actually available, unlike
2093 // the VFP define, hence the soft float and arch check. This is subtly
2094 // different from gcc, we follow the intent which was that it should be set
2095 // when Neon instructions are actually available.
Bob Wilson84f95cf2011-05-13 18:56:03 +00002096 if (FPU == NeonFPU && !SoftFloat && IsARMv7)
Benjamin Kramera9992772010-01-09 17:55:51 +00002097 Builder.defineMacro("__ARM_NEON__");
Chris Lattner393ff042008-04-21 18:56:49 +00002098 }
2099 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2100 unsigned &NumRecords) const {
Chris Lattner2752c012010-03-03 19:03:45 +00002101 Records = BuiltinInfo;
2102 NumRecords = clang::ARM::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner393ff042008-04-21 18:56:49 +00002103 }
2104 virtual const char *getVAListDeclaration() const {
John McCall0e9972c2011-05-09 02:19:37 +00002105 return "typedef void* __builtin_va_list;";
Chris Lattner393ff042008-04-21 18:56:49 +00002106 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +00002107 virtual void getGCCRegNames(const char * const *&Names,
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00002108 unsigned &NumNames) const;
Anton Korobeynikova7c47172009-05-03 13:42:53 +00002109 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00002110 unsigned &NumAliases) const;
Anders Carlsson066d2ea2009-02-28 17:11:49 +00002111 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattner44def072009-04-26 07:16:29 +00002112 TargetInfo::ConstraintInfo &Info) const {
Eli Friedmana9f54962008-08-20 07:44:10 +00002113 // FIXME: Check if this is complete
Anders Carlsson066d2ea2009-02-28 17:11:49 +00002114 switch (*Name) {
Eli Friedmana9f54962008-08-20 07:44:10 +00002115 default:
Nate Begemanad487f42008-04-22 05:03:19 +00002116 case 'l': // r0-r7
2117 case 'h': // r8-r15
2118 case 'w': // VFP Floating point register single precision
2119 case 'P': // VFP Floating point register double precision
Chris Lattner44def072009-04-26 07:16:29 +00002120 Info.setAllowsRegister();
Nate Begemanad487f42008-04-22 05:03:19 +00002121 return true;
Stuart Hastings002333f2011-06-07 23:45:05 +00002122 case 'U': // a memory reference...
2123 switch (Name[1]) {
2124 case 'q': // ...ARMV4 ldrsb
2125 case 'v': // ...VFP load/store (reg+constant offset)
2126 case 'y': // ...iWMMXt load/store
Eric Christopherdda231a2011-06-17 01:40:49 +00002127 case 't': // address valid for load/store opaque types wider
2128 // than 128-bits
2129 case 'n': // valid address for Neon doubleword vector load/store
2130 case 'm': // valid address for Neon element and structure load/store
2131 case 's': // valid address for non-offset loads/stores of quad-word
2132 // values in four ARM registers
Stuart Hastings002333f2011-06-07 23:45:05 +00002133 Info.setAllowsMemory();
2134 Name++;
2135 return true;
2136 }
Nate Begemanad487f42008-04-22 05:03:19 +00002137 }
Chris Lattner393ff042008-04-21 18:56:49 +00002138 return false;
2139 }
Evan Cheng8bfa2572011-06-16 19:13:15 +00002140 virtual std::string convertConstraint(const char *&Constraint) const {
Stuart Hastings002333f2011-06-07 23:45:05 +00002141 std::string R;
2142 switch (*Constraint) {
2143 case 'U': // Two-character constraint; add "^" hint for later parsing.
Stuart Hastings6ce33d62011-06-08 16:06:31 +00002144 R = std::string("^") + std::string(Constraint, 2);
Stuart Hastings002333f2011-06-07 23:45:05 +00002145 Constraint++;
2146 break;
Eric Christopher283f4472011-06-17 00:40:18 +00002147 case 'p': // 'p' should be translated to 'r' by default.
2148 R = std::string("r");
2149 break;
Stuart Hastings002333f2011-06-07 23:45:05 +00002150 default:
2151 return std::string(1, *Constraint);
2152 }
2153 return R;
2154 }
Chris Lattner393ff042008-04-21 18:56:49 +00002155 virtual const char *getClobbers() const {
Eli Friedmana9f54962008-08-20 07:44:10 +00002156 // FIXME: Is this really right?
Chris Lattner393ff042008-04-21 18:56:49 +00002157 return "";
2158 }
2159};
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00002160
2161const char * const ARMTargetInfo::GCCRegNames[] = {
Daniel Dunbarbf3d5522010-08-11 02:17:20 +00002162 // Integer registers
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00002163 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
Daniel Dunbarbf3d5522010-08-11 02:17:20 +00002164 "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc",
2165
2166 // Float registers
2167 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2168 "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15",
2169 "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23",
Dale Johannesen20eb49b2010-10-27 23:34:42 +00002170 "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
Daniel Dunbarbf3d5522010-08-11 02:17:20 +00002171
Dale Johannesen20eb49b2010-10-27 23:34:42 +00002172 // Double registers
2173 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
2174 "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15",
Dale Johannesend1455352010-10-28 01:05:37 +00002175 "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23",
2176 "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
Dale Johannesen20eb49b2010-10-27 23:34:42 +00002177
2178 // Quad registers
Dale Johannesend1455352010-10-28 01:05:37 +00002179 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7",
2180 "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15"
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00002181};
2182
2183void ARMTargetInfo::getGCCRegNames(const char * const *&Names,
Daniel Dunbar1fd71712010-08-11 02:17:11 +00002184 unsigned &NumNames) const {
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00002185 Names = GCCRegNames;
2186 NumNames = llvm::array_lengthof(GCCRegNames);
2187}
2188
2189const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00002190 { { "a1" }, "r0" },
2191 { { "a2" }, "r1" },
2192 { { "a3" }, "r2" },
2193 { { "a4" }, "r3" },
2194 { { "v1" }, "r4" },
2195 { { "v2" }, "r5" },
2196 { { "v3" }, "r6" },
2197 { { "v4" }, "r7" },
2198 { { "v5" }, "r8" },
2199 { { "v6", "rfp" }, "r9" },
2200 { { "sl" }, "r10" },
2201 { { "fp" }, "r11" },
2202 { { "ip" }, "r12" },
Daniel Dunbar1fd71712010-08-11 02:17:11 +00002203 { { "r13" }, "sp" },
2204 { { "r14" }, "lr" },
2205 { { "r15" }, "pc" },
Dale Johannesen20eb49b2010-10-27 23:34:42 +00002206 // The S, D and Q registers overlap, but aren't really aliases; we
2207 // don't want to substitute one of these for a different-sized one.
Daniel Dunbarc1f2cdd2009-09-17 07:03:19 +00002208};
2209
2210void ARMTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
2211 unsigned &NumAliases) const {
2212 Aliases = GCCRegAliases;
2213 NumAliases = llvm::array_lengthof(GCCRegAliases);
2214}
Chris Lattner2752c012010-03-03 19:03:45 +00002215
2216const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
Fariborz Jahanian67aba812010-11-30 17:35:24 +00002217#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES, false },
2218#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
2219 ALL_LANGUAGES, false },
Chris Lattner2752c012010-03-03 19:03:45 +00002220#include "clang/Basic/BuiltinsARM.def"
2221};
Chris Lattner393ff042008-04-21 18:56:49 +00002222} // end anonymous namespace.
2223
Eli Friedmana9f54962008-08-20 07:44:10 +00002224
2225namespace {
Mike Stump1eb44332009-09-09 15:08:12 +00002226class DarwinARMTargetInfo :
Torok Edwin5f6c1942009-06-30 17:10:35 +00002227 public DarwinTargetInfo<ARMTargetInfo> {
2228protected:
Daniel Dunbar1752ee42009-08-24 09:10:05 +00002229 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Benjamin Kramera9992772010-01-09 17:55:51 +00002230 MacroBuilder &Builder) const {
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00002231 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
Eli Friedmanb030f022009-04-19 21:38:35 +00002232 }
Eli Friedmana9f54962008-08-20 07:44:10 +00002233
Torok Edwin5f6c1942009-06-30 17:10:35 +00002234public:
Mike Stump1eb44332009-09-09 15:08:12 +00002235 DarwinARMTargetInfo(const std::string& triple)
Daniel Dunbar350b9f32010-05-27 07:00:26 +00002236 : DarwinTargetInfo<ARMTargetInfo>(triple) {
2237 HasAlignMac68kSupport = true;
2238 }
Eli Friedmana9f54962008-08-20 07:44:10 +00002239};
2240} // end anonymous namespace.
2241
Reid Spencer5f016e22007-07-11 17:01:13 +00002242namespace {
Eli Friedman01b86682008-08-20 07:28:14 +00002243class SparcV8TargetInfo : public TargetInfo {
Chris Lattnere957f532009-01-27 01:58:38 +00002244 static const TargetInfo::GCCRegAlias GCCRegAliases[];
2245 static const char * const GCCRegNames[];
Bruno Cardoso Lopes9284d212010-11-09 17:21:19 +00002246 bool SoftFloat;
Gabor Greif26658672008-02-21 16:29:08 +00002247public:
Eli Friedman01b86682008-08-20 07:28:14 +00002248 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
2249 // FIXME: Support Sparc quad-precision long double?
Eli Friedmaned855cb2008-08-21 00:13:15 +00002250 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
Chris Lattner1932e122009-11-07 18:59:41 +00002251 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
Eli Friedman01b86682008-08-20 07:28:14 +00002252 }
Bruno Cardoso Lopes9284d212010-11-09 17:21:19 +00002253 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
2254 const std::string &Name,
2255 bool Enabled) const {
2256 if (Name == "soft-float")
2257 Features[Name] = Enabled;
2258 else
2259 return false;
2260
2261 return true;
2262 }
2263 virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
2264 SoftFloat = false;
2265 for (unsigned i = 0, e = Features.size(); i != e; ++i)
2266 if (Features[i] == "+soft-float")
2267 SoftFloat = true;
2268 }
Chris Lattner33328642009-03-20 15:52:06 +00002269 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002270 MacroBuilder &Builder) const {
2271 DefineStd(Builder, "sparc", Opts);
2272 Builder.defineMacro("__sparcv8");
2273 Builder.defineMacro("__REGISTER_PREFIX__", "");
Bruno Cardoso Lopes9284d212010-11-09 17:21:19 +00002274
2275 if (SoftFloat)
2276 Builder.defineMacro("SOFT_FLOAT", "1");
Gabor Greif26658672008-02-21 16:29:08 +00002277 }
2278 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2279 unsigned &NumRecords) const {
Eli Friedman01b86682008-08-20 07:28:14 +00002280 // FIXME: Implement!
Gabor Greif26658672008-02-21 16:29:08 +00002281 }
2282 virtual const char *getVAListDeclaration() const {
Eli Friedman01b86682008-08-20 07:28:14 +00002283 return "typedef void* __builtin_va_list;";
Gabor Greif26658672008-02-21 16:29:08 +00002284 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +00002285 virtual void getGCCRegNames(const char * const *&Names,
Chris Lattnere957f532009-01-27 01:58:38 +00002286 unsigned &NumNames) const;
Anton Korobeynikova7c47172009-05-03 13:42:53 +00002287 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattnere957f532009-01-27 01:58:38 +00002288 unsigned &NumAliases) const;
Anders Carlsson066d2ea2009-02-28 17:11:49 +00002289 virtual bool validateAsmConstraint(const char *&Name,
Gabor Greif26658672008-02-21 16:29:08 +00002290 TargetInfo::ConstraintInfo &info) const {
Eli Friedman01b86682008-08-20 07:28:14 +00002291 // FIXME: Implement!
2292 return false;
Gabor Greif26658672008-02-21 16:29:08 +00002293 }
2294 virtual const char *getClobbers() const {
Eli Friedman01b86682008-08-20 07:28:14 +00002295 // FIXME: Implement!
2296 return "";
Gabor Greif26658672008-02-21 16:29:08 +00002297 }
2298};
2299
Chris Lattnere957f532009-01-27 01:58:38 +00002300const char * const SparcV8TargetInfo::GCCRegNames[] = {
2301 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2302 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2303 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2304 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
2305};
2306
Anton Korobeynikova7c47172009-05-03 13:42:53 +00002307void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names,
Chris Lattnere957f532009-01-27 01:58:38 +00002308 unsigned &NumNames) const {
2309 Names = GCCRegNames;
2310 NumNames = llvm::array_lengthof(GCCRegNames);
2311}
2312
2313const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = {
Anton Korobeynikova7c47172009-05-03 13:42:53 +00002314 { { "g0" }, "r0" },
2315 { { "g1" }, "r1" },
2316 { { "g2" }, "r2" },
2317 { { "g3" }, "r3" },
2318 { { "g4" }, "r4" },
2319 { { "g5" }, "r5" },
2320 { { "g6" }, "r6" },
2321 { { "g7" }, "r7" },
2322 { { "o0" }, "r8" },
2323 { { "o1" }, "r9" },
2324 { { "o2" }, "r10" },
2325 { { "o3" }, "r11" },
2326 { { "o4" }, "r12" },
2327 { { "o5" }, "r13" },
2328 { { "o6", "sp" }, "r14" },
2329 { { "o7" }, "r15" },
2330 { { "l0" }, "r16" },
2331 { { "l1" }, "r17" },
2332 { { "l2" }, "r18" },
2333 { { "l3" }, "r19" },
2334 { { "l4" }, "r20" },
2335 { { "l5" }, "r21" },
2336 { { "l6" }, "r22" },
2337 { { "l7" }, "r23" },
2338 { { "i0" }, "r24" },
2339 { { "i1" }, "r25" },
2340 { { "i2" }, "r26" },
2341 { { "i3" }, "r27" },
2342 { { "i4" }, "r28" },
2343 { { "i5" }, "r29" },
2344 { { "i6", "fp" }, "r30" },
2345 { { "i7" }, "r31" },
Chris Lattnere957f532009-01-27 01:58:38 +00002346};
2347
Anton Korobeynikova7c47172009-05-03 13:42:53 +00002348void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattnere957f532009-01-27 01:58:38 +00002349 unsigned &NumAliases) const {
2350 Aliases = GCCRegAliases;
2351 NumAliases = llvm::array_lengthof(GCCRegAliases);
2352}
Gabor Greif26658672008-02-21 16:29:08 +00002353} // end anonymous namespace.
2354
Eli Friedman01b86682008-08-20 07:28:14 +00002355namespace {
Edward O'Callaghan991f9a72009-10-18 13:33:59 +00002356class AuroraUXSparcV8TargetInfo : public AuroraUXTargetInfo<SparcV8TargetInfo> {
2357public:
2358 AuroraUXSparcV8TargetInfo(const std::string& triple) :
2359 AuroraUXTargetInfo<SparcV8TargetInfo>(triple) {
2360 SizeType = UnsignedInt;
2361 PtrDiffType = SignedInt;
2362 }
2363};
Torok Edwin5f6c1942009-06-30 17:10:35 +00002364class SolarisSparcV8TargetInfo : public SolarisTargetInfo<SparcV8TargetInfo> {
Eli Friedman01b86682008-08-20 07:28:14 +00002365public:
2366 SolarisSparcV8TargetInfo(const std::string& triple) :
Torok Edwin5f6c1942009-06-30 17:10:35 +00002367 SolarisTargetInfo<SparcV8TargetInfo>(triple) {
Eli Friedmanf509d732008-11-02 02:43:55 +00002368 SizeType = UnsignedInt;
2369 PtrDiffType = SignedInt;
Eli Friedman01b86682008-08-20 07:28:14 +00002370 }
2371};
2372} // end anonymous namespace.
Reid Spencer5f016e22007-07-11 17:01:13 +00002373
Chris Lattner2621fd12008-05-08 05:58:21 +00002374namespace {
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002375 class MSP430TargetInfo : public TargetInfo {
2376 static const char * const GCCRegNames[];
2377 public:
2378 MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) {
2379 TLSSupported = false;
Anton Korobeynikov09f52a62010-01-30 12:55:11 +00002380 IntWidth = 16; IntAlign = 16;
2381 LongWidth = 32; LongLongWidth = 64;
2382 LongAlign = LongLongAlign = 16;
2383 PointerWidth = 16; PointerAlign = 16;
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002384 SizeType = UnsignedInt;
2385 IntMaxType = SignedLong;
2386 UIntMaxType = UnsignedLong;
2387 IntPtrType = SignedShort;
2388 PtrDiffType = SignedInt;
Edward O'Callaghan9cf910e2009-11-21 00:49:54 +00002389 SigAtomicType = SignedLong;
Anton Korobeynikov5d7c2512009-12-19 01:32:37 +00002390 DescriptionString = "e-p:16:16:16-i8:8:8-i16:16:16-i32:16:32-n8:16";
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002391 }
2392 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002393 MacroBuilder &Builder) const {
2394 Builder.defineMacro("MSP430");
2395 Builder.defineMacro("__MSP430__");
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002396 // FIXME: defines for different 'flavours' of MCU
2397 }
2398 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2399 unsigned &NumRecords) const {
2400 // FIXME: Implement.
2401 Records = 0;
2402 NumRecords = 0;
2403 }
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002404 virtual void getGCCRegNames(const char * const *&Names,
2405 unsigned &NumNames) const;
2406 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2407 unsigned &NumAliases) const {
2408 // No aliases.
2409 Aliases = 0;
2410 NumAliases = 0;
2411 }
2412 virtual bool validateAsmConstraint(const char *&Name,
2413 TargetInfo::ConstraintInfo &info) const {
Anton Korobeynikov03265b62009-10-15 23:17:13 +00002414 // No target constraints for now.
2415 return false;
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002416 }
2417 virtual const char *getClobbers() const {
2418 // FIXME: Is this really right?
2419 return "";
2420 }
2421 virtual const char *getVAListDeclaration() const {
2422 // FIXME: implement
Anton Korobeynikoveb716852009-05-08 18:24:57 +00002423 return "typedef char* __builtin_va_list;";
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00002424 }
2425 };
2426
2427 const char * const MSP430TargetInfo::GCCRegNames[] = {
2428 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2429 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
2430 };
2431
2432 void MSP430TargetInfo::getGCCRegNames(const char * const *&Names,
2433 unsigned &NumNames) const {
2434 Names = GCCRegNames;
2435 NumNames = llvm::array_lengthof(GCCRegNames);
2436 }
2437}
2438
2439
Anton Korobeynikov89e887f2009-07-16 20:09:57 +00002440namespace {
2441 class SystemZTargetInfo : public TargetInfo {
2442 static const char * const GCCRegNames[];
2443 public:
2444 SystemZTargetInfo(const std::string& triple) : TargetInfo(triple) {
2445 TLSSupported = false;
2446 IntWidth = IntAlign = 32;
2447 LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64;
2448 PointerWidth = PointerAlign = 64;
Chris Lattner1932e122009-11-07 18:59:41 +00002449 DescriptionString = "E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-"
2450 "i64:64:64-f32:32:32-f64:64:64-f128:128:128-a0:16:16-n32:64";
Anton Korobeynikov89e887f2009-07-16 20:09:57 +00002451 }
2452 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002453 MacroBuilder &Builder) const {
2454 Builder.defineMacro("__s390__");
2455 Builder.defineMacro("__s390x__");
Anton Korobeynikov89e887f2009-07-16 20:09:57 +00002456 }
2457 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2458 unsigned &NumRecords) const {
2459 // FIXME: Implement.
2460 Records = 0;
2461 NumRecords = 0;
2462 }
Anton Korobeynikov89e887f2009-07-16 20:09:57 +00002463
Anton Korobeynikov89e887f2009-07-16 20:09:57 +00002464 virtual void getGCCRegNames(const char * const *&Names,
2465 unsigned &NumNames) const;
2466 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2467 unsigned &NumAliases) const {
2468 // No aliases.
2469 Aliases = 0;
2470 NumAliases = 0;
2471 }
2472 virtual bool validateAsmConstraint(const char *&Name,
2473 TargetInfo::ConstraintInfo &info) const {
2474 // FIXME: implement
2475 return true;
2476 }
2477 virtual const char *getClobbers() const {
2478 // FIXME: Is this really right?
2479 return "";
2480 }
2481 virtual const char *getVAListDeclaration() const {
2482 // FIXME: implement
2483 return "typedef char* __builtin_va_list;";
2484 }
2485 };
2486
2487 const char * const SystemZTargetInfo::GCCRegNames[] = {
2488 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2489 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
2490 };
2491
2492 void SystemZTargetInfo::getGCCRegNames(const char * const *&Names,
2493 unsigned &NumNames) const {
2494 Names = GCCRegNames;
2495 NumNames = llvm::array_lengthof(GCCRegNames);
2496 }
2497}
2498
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00002499namespace {
2500 class BlackfinTargetInfo : public TargetInfo {
2501 static const char * const GCCRegNames[];
2502 public:
2503 BlackfinTargetInfo(const std::string& triple) : TargetInfo(triple) {
2504 TLSSupported = false;
2505 DoubleAlign = 32;
2506 LongLongAlign = 32;
2507 LongDoubleAlign = 32;
Chris Lattner1932e122009-11-07 18:59:41 +00002508 DescriptionString = "e-p:32:32-i64:32-f64:32-n32";
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00002509 }
2510
2511 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002512 MacroBuilder &Builder) const {
2513 DefineStd(Builder, "bfin", Opts);
2514 DefineStd(Builder, "BFIN", Opts);
2515 Builder.defineMacro("__ADSPBLACKFIN__");
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00002516 // FIXME: This one is really dependent on -mcpu
Benjamin Kramera9992772010-01-09 17:55:51 +00002517 Builder.defineMacro("__ADSPLPBLACKFIN__");
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00002518 // FIXME: Add cpu-dependent defines and __SILICON_REVISION__
2519 }
2520
2521 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2522 unsigned &NumRecords) const {
2523 // FIXME: Implement.
2524 Records = 0;
2525 NumRecords = 0;
2526 }
2527
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00002528 virtual void getGCCRegNames(const char * const *&Names,
2529 unsigned &NumNames) const;
2530
2531 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2532 unsigned &NumAliases) const {
2533 // No aliases.
2534 Aliases = 0;
2535 NumAliases = 0;
2536 }
2537
2538 virtual bool validateAsmConstraint(const char *&Name,
2539 TargetInfo::ConstraintInfo &Info) const {
2540 if (strchr("adzDWeABbvfcCtukxywZY", Name[0])) {
2541 Info.setAllowsRegister();
2542 return true;
2543 }
2544 return false;
2545 }
2546
2547 virtual const char *getClobbers() const {
2548 return "";
2549 }
2550
2551 virtual const char *getVAListDeclaration() const {
2552 return "typedef char* __builtin_va_list;";
2553 }
2554 };
2555
2556 const char * const BlackfinTargetInfo::GCCRegNames[] = {
2557 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2558 "p0", "p1", "p2", "p3", "p4", "p5", "sp", "fp",
2559 "i0", "i1", "i2", "i3", "b0", "b1", "b2", "b3",
2560 "l0", "l1", "l2", "l3", "m0", "m1", "m2", "m3",
2561 "a0", "a1", "cc",
2562 "rets", "reti", "retx", "retn", "rete", "astat", "seqstat", "usp",
2563 "argp", "lt0", "lt1", "lc0", "lc1", "lb0", "lb1"
2564 };
2565
2566 void BlackfinTargetInfo::getGCCRegNames(const char * const *&Names,
2567 unsigned &NumNames) const {
2568 Names = GCCRegNames;
2569 NumNames = llvm::array_lengthof(GCCRegNames);
2570 }
2571}
2572
Eli Friedmanb63decf2009-08-19 20:47:07 +00002573namespace {
2574
Mike Stump1eb44332009-09-09 15:08:12 +00002575 // LLVM and Clang cannot be used directly to output native binaries for
2576 // target, but is used to compile C code to llvm bitcode with correct
Eli Friedmanb63decf2009-08-19 20:47:07 +00002577 // type and alignment information.
Mike Stump1eb44332009-09-09 15:08:12 +00002578 //
2579 // TCE uses the llvm bitcode as input and uses it for generating customized
2580 // target processor and program binary. TCE co-design environment is
Eli Friedmanb63decf2009-08-19 20:47:07 +00002581 // publicly available in http://tce.cs.tut.fi
2582
2583 class TCETargetInfo : public TargetInfo{
2584 public:
2585 TCETargetInfo(const std::string& triple) : TargetInfo(triple) {
2586 TLSSupported = false;
2587 IntWidth = 32;
2588 LongWidth = LongLongWidth = 32;
Eli Friedmanb63decf2009-08-19 20:47:07 +00002589 PointerWidth = 32;
2590 IntAlign = 32;
2591 LongAlign = LongLongAlign = 32;
2592 PointerAlign = 32;
2593 SizeType = UnsignedInt;
2594 IntMaxType = SignedLong;
2595 UIntMaxType = UnsignedLong;
2596 IntPtrType = SignedInt;
2597 PtrDiffType = SignedInt;
2598 FloatWidth = 32;
2599 FloatAlign = 32;
2600 DoubleWidth = 32;
2601 DoubleAlign = 32;
2602 LongDoubleWidth = 32;
2603 LongDoubleAlign = 32;
2604 FloatFormat = &llvm::APFloat::IEEEsingle;
2605 DoubleFormat = &llvm::APFloat::IEEEsingle;
2606 LongDoubleFormat = &llvm::APFloat::IEEEsingle;
Chris Lattner3a47c4e2010-03-04 21:07:38 +00002607 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-"
2608 "i16:16:32-i32:32:32-i64:32:32-"
NAKAMURA Takumic9109292011-02-18 08:44:38 +00002609 "f32:32:32-f64:32:32-v64:32:32-"
2610 "v128:32:32-a0:0:32-n32";
Eli Friedmanb63decf2009-08-19 20:47:07 +00002611 }
2612
2613 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002614 MacroBuilder &Builder) const {
2615 DefineStd(Builder, "tce", Opts);
2616 Builder.defineMacro("__TCE__");
2617 Builder.defineMacro("__TCE_V1__");
Eli Friedmanb63decf2009-08-19 20:47:07 +00002618 }
2619 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2620 unsigned &NumRecords) const {}
Daniel Dunbar55cc2ed2009-08-24 09:54:37 +00002621 virtual const char *getClobbers() const {
2622 return "";
2623 }
Eli Friedmanb63decf2009-08-19 20:47:07 +00002624 virtual const char *getVAListDeclaration() const {
2625 return "typedef void* __builtin_va_list;";
2626 }
Eli Friedmanb63decf2009-08-19 20:47:07 +00002627 virtual void getGCCRegNames(const char * const *&Names,
2628 unsigned &NumNames) const {}
2629 virtual bool validateAsmConstraint(const char *&Name,
2630 TargetInfo::ConstraintInfo &info) const {
2631 return true;
2632 }
2633 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2634 unsigned &NumAliases) const {}
2635 };
2636}
2637
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002638namespace {
2639class MipsTargetInfo : public TargetInfo {
Eric Christophered734732010-03-02 02:41:08 +00002640 std::string ABI, CPU;
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002641 static const TargetInfo::GCCRegAlias GCCRegAliases[];
2642 static const char * const GCCRegNames[];
2643public:
Eric Christophered734732010-03-02 02:41:08 +00002644 MipsTargetInfo(const std::string& triple) : TargetInfo(triple), ABI("o32") {
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002645 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
Akira Hatanaka619e8872011-06-02 00:09:17 +00002646 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
2647 SizeType = UnsignedInt;
2648 PtrDiffType = SignedInt;
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002649 }
Eric Christophered734732010-03-02 02:41:08 +00002650 virtual const char *getABI() const { return ABI.c_str(); }
2651 virtual bool setABI(const std::string &Name) {
2652
2653 if ((Name == "o32") || (Name == "eabi")) {
2654 ABI = Name;
2655 return true;
2656 } else
2657 return false;
2658 }
2659 virtual bool setCPU(const std::string &Name) {
2660 CPU = Name;
2661 return true;
2662 }
2663 void getDefaultFeatures(const std::string &CPU,
2664 llvm::StringMap<bool> &Features) const {
2665 Features[ABI] = true;
2666 Features[CPU] = true;
2667 }
2668 virtual void getArchDefines(const LangOptions &Opts,
2669 MacroBuilder &Builder) const {
2670 if (ABI == "o32")
2671 Builder.defineMacro("__mips_o32");
2672 else if (ABI == "eabi")
2673 Builder.defineMacro("__mips_eabi");
2674 }
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002675 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002676 MacroBuilder &Builder) const {
2677 DefineStd(Builder, "mips", Opts);
2678 Builder.defineMacro("_mips");
2679 DefineStd(Builder, "MIPSEB", Opts);
2680 Builder.defineMacro("_MIPSEB");
2681 Builder.defineMacro("__REGISTER_PREFIX__", "");
Eric Christophered734732010-03-02 02:41:08 +00002682 getArchDefines(Opts, Builder);
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002683 }
2684 virtual void getTargetBuiltins(const Builtin::Info *&Records,
2685 unsigned &NumRecords) const {
2686 // FIXME: Implement!
2687 }
2688 virtual const char *getVAListDeclaration() const {
2689 return "typedef void* __builtin_va_list;";
2690 }
2691 virtual void getGCCRegNames(const char * const *&Names,
2692 unsigned &NumNames) const;
2693 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
2694 unsigned &NumAliases) const;
2695 virtual bool validateAsmConstraint(const char *&Name,
2696 TargetInfo::ConstraintInfo &Info) const {
2697 switch (*Name) {
2698 default:
2699 case 'r': // CPU registers.
2700 case 'd': // Equivalent to "r" unless generating MIPS16 code.
2701 case 'y': // Equivalent to "r", backwards compatibility only.
2702 case 'f': // floating-point registers.
2703 Info.setAllowsRegister();
2704 return true;
2705 }
2706 return false;
2707 }
2708
2709 virtual const char *getClobbers() const {
2710 // FIXME: Implement!
2711 return "";
2712 }
2713};
2714
2715const char * const MipsTargetInfo::GCCRegNames[] = {
Michael J. Spencer20249a12010-10-21 03:16:25 +00002716 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002717 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
2718 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
2719 "$24", "$25", "$26", "$27", "$28", "$sp", "$fp", "$31",
2720 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
2721 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
2722 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
2723 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
2724 "hi", "lo", "", "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
2725 "$fcc5","$fcc6","$fcc7"
2726};
2727
2728void MipsTargetInfo::getGCCRegNames(const char * const *&Names,
2729 unsigned &NumNames) const {
2730 Names = GCCRegNames;
2731 NumNames = llvm::array_lengthof(GCCRegNames);
2732}
2733
2734const TargetInfo::GCCRegAlias MipsTargetInfo::GCCRegAliases[] = {
2735 { { "at" }, "$1" },
2736 { { "v0" }, "$2" },
2737 { { "v1" }, "$3" },
2738 { { "a0" }, "$4" },
2739 { { "a1" }, "$5" },
2740 { { "a2" }, "$6" },
2741 { { "a3" }, "$7" },
2742 { { "t0" }, "$8" },
2743 { { "t1" }, "$9" },
2744 { { "t2" }, "$10" },
2745 { { "t3" }, "$11" },
2746 { { "t4" }, "$12" },
2747 { { "t5" }, "$13" },
2748 { { "t6" }, "$14" },
2749 { { "t7" }, "$15" },
2750 { { "s0" }, "$16" },
2751 { { "s1" }, "$17" },
2752 { { "s2" }, "$18" },
2753 { { "s3" }, "$19" },
2754 { { "s4" }, "$20" },
2755 { { "s5" }, "$21" },
2756 { { "s6" }, "$22" },
2757 { { "s7" }, "$23" },
2758 { { "t8" }, "$24" },
2759 { { "t9" }, "$25" },
2760 { { "k0" }, "$26" },
2761 { { "k1" }, "$27" },
2762 { { "gp" }, "$28" },
2763 { { "sp" }, "$29" },
2764 { { "fp" }, "$30" },
2765 { { "ra" }, "$31" }
2766};
2767
2768void MipsTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
2769 unsigned &NumAliases) const {
2770 Aliases = GCCRegAliases;
2771 NumAliases = llvm::array_lengthof(GCCRegAliases);
2772}
2773} // end anonymous namespace.
2774
2775namespace {
2776class MipselTargetInfo : public MipsTargetInfo {
2777public:
2778 MipselTargetInfo(const std::string& triple) : MipsTargetInfo(triple) {
2779 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
Akira Hatanaka619e8872011-06-02 00:09:17 +00002780 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002781 }
2782
2783 virtual void getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002784 MacroBuilder &Builder) const;
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002785};
2786
2787void MipselTargetInfo::getTargetDefines(const LangOptions &Opts,
Benjamin Kramera9992772010-01-09 17:55:51 +00002788 MacroBuilder &Builder) const {
2789 DefineStd(Builder, "mips", Opts);
2790 Builder.defineMacro("_mips");
2791 DefineStd(Builder, "MIPSEL", Opts);
2792 Builder.defineMacro("_MIPSEL");
2793 Builder.defineMacro("__REGISTER_PREFIX__", "");
Eric Christophered734732010-03-02 02:41:08 +00002794 getArchDefines(Opts, Builder);
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002795}
2796} // end anonymous namespace.
2797
Reid Spencer5f016e22007-07-11 17:01:13 +00002798//===----------------------------------------------------------------------===//
2799// Driver code
2800//===----------------------------------------------------------------------===//
2801
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002802static TargetInfo *AllocateTarget(const std::string &T) {
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002803 llvm::Triple Triple(T);
2804 llvm::Triple::OSType os = Triple.getOS();
Eli Friedman61538a72008-05-20 14:21:01 +00002805
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002806 switch (Triple.getArch()) {
2807 default:
2808 return NULL;
Eli Friedman61538a72008-05-20 14:21:01 +00002809
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002810 case llvm::Triple::arm:
Daniel Dunbarf4aa4f612009-09-11 01:14:50 +00002811 case llvm::Triple::thumb:
Daniel Dunbardb57a4c2011-04-19 21:43:27 +00002812 if (Triple.isOSDarwin())
2813 return new DarwinARMTargetInfo(T);
2814
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002815 switch (os) {
Rafael Espindola022a8a52010-06-10 00:46:51 +00002816 case llvm::Triple::Linux:
2817 return new LinuxTargetInfo<ARMTargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002818 case llvm::Triple::FreeBSD:
Torok Edwin5f6c1942009-06-30 17:10:35 +00002819 return new FreeBSDTargetInfo<ARMTargetInfo>(T);
Douglas Gregordca52262011-07-01 22:41:14 +00002820 case llvm::Triple::RTEMS:
2821 return new RTEMSTargetInfo<ARMTargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002822 default:
2823 return new ARMTargetInfo(T);
2824 }
Eli Friedman61538a72008-05-20 14:21:01 +00002825
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002826 case llvm::Triple::bfin:
Douglas Gregordca52262011-07-01 22:41:14 +00002827 if ( os == llvm::Triple::RTEMS )
2828 return new RTEMSTargetInfo<BlackfinTargetInfo>(T);
Jakob Stoklund Olesen1eb43432009-08-17 20:08:44 +00002829 return new BlackfinTargetInfo(T);
2830
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002831 case llvm::Triple::msp430:
2832 return new MSP430TargetInfo(T);
Eli Friedman61538a72008-05-20 14:21:01 +00002833
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002834 case llvm::Triple::mips:
2835 if (os == llvm::Triple::Psp)
2836 return new PSPTargetInfo<MipsTargetInfo>(T);
2837 if (os == llvm::Triple::Linux)
2838 return new LinuxTargetInfo<MipsTargetInfo>(T);
Douglas Gregordca52262011-07-01 22:41:14 +00002839 if (os == llvm::Triple::RTEMS)
2840 return new RTEMSTargetInfo<MipsTargetInfo>(T);
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002841 return new MipsTargetInfo(T);
2842
2843 case llvm::Triple::mipsel:
2844 if (os == llvm::Triple::Psp)
2845 return new PSPTargetInfo<MipselTargetInfo>(T);
2846 if (os == llvm::Triple::Linux)
2847 return new LinuxTargetInfo<MipselTargetInfo>(T);
Douglas Gregordca52262011-07-01 22:41:14 +00002848 if (os == llvm::Triple::RTEMS)
2849 return new RTEMSTargetInfo<MipselTargetInfo>(T);
Edward O'Callaghan84423a82009-11-15 10:22:07 +00002850 return new MipselTargetInfo(T);
2851
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002852 case llvm::Triple::ppc:
Daniel Dunbardb57a4c2011-04-19 21:43:27 +00002853 if (Triple.isOSDarwin())
Roman Divackyc81f2a22011-01-06 08:27:10 +00002854 return new DarwinPPC32TargetInfo(T);
Chris Lattnere03ae302010-02-16 18:14:57 +00002855 else if (os == llvm::Triple::FreeBSD)
2856 return new FreeBSDTargetInfo<PPC32TargetInfo>(T);
Douglas Gregordca52262011-07-01 22:41:14 +00002857 if ( os == llvm::Triple::RTEMS )
2858 return new RTEMSTargetInfo<PPC32TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002859 return new PPC32TargetInfo(T);
2860
2861 case llvm::Triple::ppc64:
Daniel Dunbardb57a4c2011-04-19 21:43:27 +00002862 if (Triple.isOSDarwin())
Daniel Dunbar4c6a2262010-05-30 00:07:30 +00002863 return new DarwinPPC64TargetInfo(T);
John Thompson3f6918a2009-11-19 17:18:50 +00002864 else if (os == llvm::Triple::Lv2)
2865 return new PS3PPUTargetInfo<PPC64TargetInfo>(T);
Chris Lattnere03ae302010-02-16 18:14:57 +00002866 else if (os == llvm::Triple::FreeBSD)
2867 return new FreeBSDTargetInfo<PPC64TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002868 return new PPC64TargetInfo(T);
2869
Justin Holewinski285dc652011-04-20 19:34:15 +00002870 case llvm::Triple::ptx32:
2871 return new PTX32TargetInfo(T);
2872 case llvm::Triple::ptx64:
2873 return new PTX64TargetInfo(T);
2874
Chris Lattner9cbeb632010-03-06 21:21:27 +00002875 case llvm::Triple::mblaze:
2876 return new MBlazeTargetInfo(T);
2877
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002878 case llvm::Triple::sparc:
Edward O'Callaghan991f9a72009-10-18 13:33:59 +00002879 if (os == llvm::Triple::AuroraUX)
2880 return new AuroraUXSparcV8TargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002881 if (os == llvm::Triple::Solaris)
2882 return new SolarisSparcV8TargetInfo(T);
Douglas Gregordca52262011-07-01 22:41:14 +00002883 if ( os == llvm::Triple::RTEMS )
2884 return new RTEMSTargetInfo<SparcV8TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002885 return new SparcV8TargetInfo(T);
2886
John Thompson3f6918a2009-11-19 17:18:50 +00002887 // FIXME: Need a real SPU target.
2888 case llvm::Triple::cellspu:
2889 return new PS3SPUTargetInfo<PPC64TargetInfo>(T);
2890
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002891 case llvm::Triple::systemz:
2892 return new SystemZTargetInfo(T);
2893
Eli Friedmanb63decf2009-08-19 20:47:07 +00002894 case llvm::Triple::tce:
2895 return new TCETargetInfo(T);
2896
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002897 case llvm::Triple::x86:
Daniel Dunbardb57a4c2011-04-19 21:43:27 +00002898 if (Triple.isOSDarwin())
2899 return new DarwinI386TargetInfo(T);
2900
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002901 switch (os) {
Edward O'Callaghan991f9a72009-10-18 13:33:59 +00002902 case llvm::Triple::AuroraUX:
2903 return new AuroraUXTargetInfo<X86_32TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002904 case llvm::Triple::Linux:
2905 return new LinuxTargetInfo<X86_32TargetInfo>(T);
2906 case llvm::Triple::DragonFly:
2907 return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(T);
2908 case llvm::Triple::NetBSD:
2909 return new NetBSDTargetInfo<X86_32TargetInfo>(T);
2910 case llvm::Triple::OpenBSD:
2911 return new OpenBSDI386TargetInfo(T);
2912 case llvm::Triple::FreeBSD:
2913 return new FreeBSDTargetInfo<X86_32TargetInfo>(T);
Chris Lattner38e317d2010-07-07 16:01:42 +00002914 case llvm::Triple::Minix:
2915 return new MinixTargetInfo<X86_32TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002916 case llvm::Triple::Solaris:
2917 return new SolarisTargetInfo<X86_32TargetInfo>(T);
2918 case llvm::Triple::Cygwin:
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00002919 return new CygwinX86_32TargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002920 case llvm::Triple::MinGW32:
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00002921 return new MinGWX86_32TargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002922 case llvm::Triple::Win32:
Michael J. Spencera764e832010-10-21 08:22:51 +00002923 return new VisualStudioWindowsX86_32TargetInfo(T);
Chris Lattner86ed3a32010-04-11 19:29:39 +00002924 case llvm::Triple::Haiku:
2925 return new HaikuX86_32TargetInfo(T);
Douglas Gregordca52262011-07-01 22:41:14 +00002926 case llvm::Triple::RTEMS:
2927 return new RTEMSX86_32TargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002928 default:
2929 return new X86_32TargetInfo(T);
2930 }
2931
2932 case llvm::Triple::x86_64:
Daniel Dunbardb57a4c2011-04-19 21:43:27 +00002933 if (Triple.isOSDarwin() || Triple.getEnvironment() == llvm::Triple::MachO)
2934 return new DarwinX86_64TargetInfo(T);
2935
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002936 switch (os) {
Edward O'Callaghan991f9a72009-10-18 13:33:59 +00002937 case llvm::Triple::AuroraUX:
2938 return new AuroraUXTargetInfo<X86_64TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002939 case llvm::Triple::Linux:
2940 return new LinuxTargetInfo<X86_64TargetInfo>(T);
Chris Lattner7a7ca282010-01-09 05:41:14 +00002941 case llvm::Triple::DragonFly:
2942 return new DragonFlyBSDTargetInfo<X86_64TargetInfo>(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002943 case llvm::Triple::NetBSD:
2944 return new NetBSDTargetInfo<X86_64TargetInfo>(T);
2945 case llvm::Triple::OpenBSD:
2946 return new OpenBSDX86_64TargetInfo(T);
2947 case llvm::Triple::FreeBSD:
2948 return new FreeBSDTargetInfo<X86_64TargetInfo>(T);
2949 case llvm::Triple::Solaris:
2950 return new SolarisTargetInfo<X86_64TargetInfo>(T);
NAKAMURA Takumi0aa20572011-02-17 08:51:38 +00002951 case llvm::Triple::MinGW32:
Daniel Dunbar9fe4a5d2009-09-23 07:31:35 +00002952 return new MinGWX86_64TargetInfo(T);
2953 case llvm::Triple::Win32: // This is what Triple.h supports now.
Daniel Dunbardb57a4c2011-04-19 21:43:27 +00002954 return new VisualStudioWindowsX86_64TargetInfo(T);
Daniel Dunbar9d6fa612009-08-18 05:47:58 +00002955 default:
2956 return new X86_64TargetInfo(T);
2957 }
2958 }
Reid Spencer5f016e22007-07-11 17:01:13 +00002959}
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002960
2961/// CreateTargetInfo - Return the target info object for the specified target
2962/// triple.
2963TargetInfo *TargetInfo::CreateTargetInfo(Diagnostic &Diags,
Daniel Dunbarb93292a2009-12-19 03:30:57 +00002964 TargetOptions &Opts) {
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002965 llvm::Triple Triple(Opts.Triple);
2966
2967 // Construct the target
2968 llvm::OwningPtr<TargetInfo> Target(AllocateTarget(Triple.str()));
2969 if (!Target) {
2970 Diags.Report(diag::err_target_unknown_triple) << Triple.str();
2971 return 0;
2972 }
2973
Daniel Dunbareac7c532009-12-18 18:42:37 +00002974 // Set the target CPU if specified.
2975 if (!Opts.CPU.empty() && !Target->setCPU(Opts.CPU)) {
2976 Diags.Report(diag::err_target_unknown_cpu) << Opts.CPU;
2977 return 0;
2978 }
2979
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002980 // Set the target ABI if specified.
2981 if (!Opts.ABI.empty() && !Target->setABI(Opts.ABI)) {
2982 Diags.Report(diag::err_target_unknown_abi) << Opts.ABI;
2983 return 0;
2984 }
2985
Charles Davis98b7c5c2010-06-11 01:06:47 +00002986 // Set the target C++ ABI.
John McCallee79a4c2010-08-21 22:46:04 +00002987 if (!Opts.CXXABI.empty() && !Target->setCXXABI(Opts.CXXABI)) {
Charles Davis98b7c5c2010-06-11 01:06:47 +00002988 Diags.Report(diag::err_target_unknown_cxxabi) << Opts.CXXABI;
2989 return 0;
2990 }
2991
Daniel Dunbard58c03f2009-11-15 06:48:46 +00002992 // Compute the default target features, we need the target to handle this
2993 // because features may have dependencies on one another.
2994 llvm::StringMap<bool> Features;
2995 Target->getDefaultFeatures(Opts.CPU, Features);
2996
2997 // Apply the user specified deltas.
2998 for (std::vector<std::string>::const_iterator it = Opts.Features.begin(),
2999 ie = Opts.Features.end(); it != ie; ++it) {
3000 const char *Name = it->c_str();
3001
3002 // Apply the feature via the target.
3003 if ((Name[0] != '-' && Name[0] != '+') ||
3004 !Target->setFeatureEnabled(Features, Name + 1, (Name[0] == '+'))) {
3005 Diags.Report(diag::err_target_invalid_feature) << Name;
3006 return 0;
3007 }
3008 }
3009
3010 // Add the features to the compile options.
3011 //
3012 // FIXME: If we are completely confident that we have the right set, we only
3013 // need to pass the minuses.
Daniel Dunbarb93292a2009-12-19 03:30:57 +00003014 Opts.Features.clear();
Daniel Dunbard58c03f2009-11-15 06:48:46 +00003015 for (llvm::StringMap<bool>::const_iterator it = Features.begin(),
3016 ie = Features.end(); it != ie; ++it)
Daniel Dunbarb93292a2009-12-19 03:30:57 +00003017 Opts.Features.push_back(std::string(it->second ? "+" : "-") + it->first());
3018 Target->HandleTargetFeatures(Opts.Features);
Daniel Dunbard58c03f2009-11-15 06:48:46 +00003019
3020 return Target.take();
3021}