blob: 029a9f79f3bedd25012ae32e6b00896c744065b5 [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
Douglas Gregorb1152d82009-02-16 21:58:21 +000015// FIXME: Layering violation
Reid Spencer5f016e22007-07-11 17:01:13 +000016#include "clang/AST/Builtins.h"
Anders Carlsson564f1de2007-12-09 23:17:02 +000017#include "clang/AST/TargetBuiltins.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000018#include "clang/Basic/TargetInfo.h"
Chris Lattner8fc4dfb2008-12-04 22:54:33 +000019#include "clang/Basic/LangOptions.h"
Anders Carlsson3346ae62007-11-24 23:38:12 +000020#include "llvm/ADT/STLExtras.h"
Eli Friedman25531262008-05-20 14:27:34 +000021#include "llvm/ADT/APFloat.h"
Chris Lattnerca45cff2009-03-20 16:06:38 +000022#include "llvm/ADT/SmallString.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000023using namespace clang;
24
Reid Spencer5f016e22007-07-11 17:01:13 +000025//===----------------------------------------------------------------------===//
26// Common code shared among targets.
27//===----------------------------------------------------------------------===//
28
Chris Lattnerd15fa822007-10-06 06:57:34 +000029static void Define(std::vector<char> &Buf, const char *Macro,
30 const char *Val = "1") {
31 const char *Def = "#define ";
32 Buf.insert(Buf.end(), Def, Def+strlen(Def));
33 Buf.insert(Buf.end(), Macro, Macro+strlen(Macro));
34 Buf.push_back(' ');
35 Buf.insert(Buf.end(), Val, Val+strlen(Val));
36 Buf.push_back('\n');
37}
38
Chris Lattnerca45cff2009-03-20 16:06:38 +000039/// DefineStd - Define a macro name and standard variants. For example if
40/// MacroName is "unix", then this will define "__unix", "__unix__", and "unix"
41/// when in GNU mode.
Anton Korobeynikova7c47172009-05-03 13:42:53 +000042static void DefineStd(std::vector<char> &Buf, const char *MacroName,
Chris Lattnerca45cff2009-03-20 16:06:38 +000043 const LangOptions &Opts) {
44 assert(MacroName[0] != '_' && "Identifier should be in the user's namespace");
Anton Korobeynikova7c47172009-05-03 13:42:53 +000045
Chris Lattnerca45cff2009-03-20 16:06:38 +000046 // If in GNU mode (e.g. -std=gnu99 but not -std=c99) define the raw identifier
47 // in the user's namespace.
48 if (Opts.GNUMode)
49 Define(Buf, MacroName);
Anton Korobeynikova7c47172009-05-03 13:42:53 +000050
Chris Lattnerca45cff2009-03-20 16:06:38 +000051 // Define __unix.
52 llvm::SmallString<20> TmpStr;
53 TmpStr = "__";
54 TmpStr += MacroName;
55 Define(Buf, TmpStr.c_str());
Anton Korobeynikova7c47172009-05-03 13:42:53 +000056
Chris Lattnerca45cff2009-03-20 16:06:38 +000057 // Define __unix__.
58 TmpStr += "__";
59 Define(Buf, TmpStr.c_str());
60}
61
Chris Lattnerd29b6302008-10-05 21:50:58 +000062//===----------------------------------------------------------------------===//
63// Defines specific to certain operating systems.
64//===----------------------------------------------------------------------===//
65
Eli Friedman01b86682008-08-20 07:28:14 +000066static void getSolarisDefines(std::vector<char> &Defs) {
67 Define(Defs, "__SUN__");
68 Define(Defs, "__SOLARIS__");
69}
Reid Spencer5f016e22007-07-11 17:01:13 +000070
Chris Lattner318ca712009-03-20 15:55:34 +000071static void getFreeBSDDefines(const LangOptions &Opts, bool is64Bit,
72 const char *Triple, std::vector<char> &Defs) {
Chris Lattnerfd0269d2008-10-16 17:04:31 +000073 // FreeBSD defines; list based off of gcc output
74
75 const char *FreeBSD = strstr(Triple, "-freebsd");
76 FreeBSD += strlen("-freebsd");
77 char release[] = "X";
78 release[0] = FreeBSD[0];
79 char version[] = "X00001";
80 version[0] = FreeBSD[0];
81
82 Define(Defs, "__FreeBSD__", release);
83 Define(Defs, "__FreeBSD_cc_version", version);
84 Define(Defs, "__KPRINTF_ATTRIBUTE__");
Chris Lattnerca45cff2009-03-20 16:06:38 +000085 DefineStd(Defs, "unix", Opts);
Anton Korobeynikov2793bda2009-02-14 16:42:50 +000086 Define(Defs, "__ELF__", "1");
Chris Lattnerfd0269d2008-10-16 17:04:31 +000087 if (is64Bit) {
88 Define(Defs, "__LP64__");
89 }
90}
91
Chris Lattner318ca712009-03-20 15:55:34 +000092static void getDragonFlyDefines(const LangOptions &Opts,
93 std::vector<char> &Defs) {
Chris Lattnerd29b6302008-10-05 21:50:58 +000094 // DragonFly defines; list based off of gcc output
95 Define(Defs, "__DragonFly__");
96 Define(Defs, "__DragonFly_cc_version", "100001");
97 Define(Defs, "__ELF__");
98 Define(Defs, "__KPRINTF_ATTRIBUTE__");
99 Define(Defs, "__tune_i386__");
Chris Lattnerca45cff2009-03-20 16:06:38 +0000100 DefineStd(Defs, "unix", Opts);
Chris Lattnerd29b6302008-10-05 21:50:58 +0000101}
102
Chris Lattner318ca712009-03-20 15:55:34 +0000103static void getLinuxDefines(const LangOptions &Opts, std::vector<char> &Defs) {
Chris Lattnerd29b6302008-10-05 21:50:58 +0000104 // Linux defines; list based off of gcc output
Chris Lattnerca45cff2009-03-20 16:06:38 +0000105 DefineStd(Defs, "unix", Opts);
106 DefineStd(Defs, "linux", Opts);
Chris Lattnerd29b6302008-10-05 21:50:58 +0000107 Define(Defs, "__gnu_linux__");
Argyrios Kyrtzidis487cdee2009-02-14 15:02:45 +0000108 Define(Defs, "__ELF__", "1");
Chris Lattnerd29b6302008-10-05 21:50:58 +0000109}
110
Chris Lattnerae0ee032008-12-04 23:20:07 +0000111/// getDarwinNumber - Parse the 'darwin number' out of the specific targe
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000112/// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is
Chris Lattnerae0ee032008-12-04 23:20:07 +0000113/// not defined, return 0's. Return true if we have -darwin in the string or
114/// false otherwise.
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000115static bool getDarwinNumber(const char *Triple, unsigned &Maj, unsigned &Min, unsigned &Revision) {
116 Maj = Min = Revision = 0;
Chris Lattnerae0ee032008-12-04 23:20:07 +0000117 const char *Darwin = strstr(Triple, "-darwin");
118 if (Darwin == 0) return false;
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000119
Chris Lattnerae0ee032008-12-04 23:20:07 +0000120 Darwin += strlen("-darwin");
121 if (Darwin[0] < '0' || Darwin[0] > '9')
122 return true;
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000123
Chris Lattnerae0ee032008-12-04 23:20:07 +0000124 Maj = Darwin[0]-'0';
125 ++Darwin;
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000126
Chris Lattnerae0ee032008-12-04 23:20:07 +0000127 // Handle "darwin11".
128 if (Maj == 1 && Darwin[0] >= '0' && Darwin[0] <= '9') {
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000129 Maj = Maj*10 + (Darwin[0] - '0');
Chris Lattnerae0ee032008-12-04 23:20:07 +0000130 ++Darwin;
131 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000132
Chris Lattnerae0ee032008-12-04 23:20:07 +0000133 // Handle minor version: 10.4.9 -> darwin8.9 -> "1049"
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000134 if (Darwin[0] != '.')
135 return true;
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000136
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000137 ++Darwin;
138 if (Darwin[0] < '0' || Darwin[0] > '9')
139 return true;
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000140
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000141 Min = Darwin[0]-'0';
142 ++Darwin;
143
144 // Handle 10.4.11 -> darwin8.11
145 if (Min == 1 && Darwin[0] >= '0' && Darwin[0] <= '9') {
146 Min = Min*10 + (Darwin[0] - '0');
147 ++Darwin;
148 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000149
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000150 // Handle revision darwin8.9.1
151 if (Darwin[0] != '.')
152 return true;
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000153
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000154 ++Darwin;
155 if (Darwin[0] < '0' || Darwin[0] > '9')
156 return true;
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000157
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000158 Revision = Darwin[0]-'0';
159 ++Darwin;
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000160
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000161 if (Revision == 1 && Darwin[0] >= '0' && Darwin[0] <= '9') {
162 Revision = Revision*10 + (Darwin[0] - '0');
163 ++Darwin;
164 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000165
Chris Lattnerae0ee032008-12-04 23:20:07 +0000166 return true;
167}
168
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000169static void getDarwinDefines(std::vector<char> &Defs, const LangOptions &Opts) {
Eli Friedman618234a2008-08-20 02:34:37 +0000170 Define(Defs, "__APPLE__");
171 Define(Defs, "__MACH__");
Chris Lattnerd427ad42009-02-05 07:19:24 +0000172 Define(Defs, "OBJC_NEW_PROPERTIES");
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000173
Chris Lattner10d24272009-04-07 16:50:40 +0000174 // __weak is always defined, for use in blocks and with objc pointers.
175 Define(Defs, "__weak", "__attribute__((objc_gc(weak)))");
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000176
Chris Lattner10d24272009-04-07 16:50:40 +0000177 // Darwin defines __strong even in C mode (just to nothing).
178 if (!Opts.ObjC1 || Opts.getGCMode() == LangOptions::NonGC)
Chris Lattner3a5cbd32009-04-07 04:48:21 +0000179 Define(Defs, "__strong", "");
Chris Lattner10d24272009-04-07 16:50:40 +0000180 else
Chris Lattner3a5cbd32009-04-07 04:48:21 +0000181 Define(Defs, "__strong", "__attribute__((objc_gc(strong)))");
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000182}
183
184static void getDarwinOSXDefines(std::vector<char> &Defs, const char *Triple) {
Chris Lattner8b30c412008-09-30 01:00:25 +0000185 // Figure out which "darwin number" the target triple is. "darwin9" -> 10.5.
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000186 unsigned Maj, Min, Rev;
187 if (getDarwinNumber(Triple, Maj, Min, Rev)) {
188 char MacOSXStr[] = "1000";
Chris Lattnerae0ee032008-12-04 23:20:07 +0000189 if (Maj >= 4 && Maj <= 13) { // 10.0-10.9
190 // darwin7 -> 1030, darwin8 -> 1040, darwin9 -> 1050, etc.
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000191 MacOSXStr[2] = '0' + Maj-4;
192 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000193
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000194 // Handle minor version: 10.4.9 -> darwin8.9 -> "1049"
195 // Cap 10.4.11 -> darwin8.11 -> "1049"
196 MacOSXStr[3] = std::min(Min, 9U)+'0';
197 Define(Defs, "__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", MacOSXStr);
198 }
199}
200
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000201static void getDarwinIPhoneOSDefines(std::vector<char> &Defs,
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000202 const char *Triple) {
203 // Figure out which "darwin number" the target triple is. "darwin9" -> 10.5.
204 unsigned Maj, Min, Rev;
205 if (getDarwinNumber(Triple, Maj, Min, Rev)) {
206 // When targetting iPhone OS, interpret the minor version and
207 // revision as the iPhone OS version
208 char iPhoneOSStr[] = "10000";
209 if (Min >= 2 && Min <= 9) { // iPhone OS 2.0-9.0
210 // darwin9.2.0 -> 20000, darwin9.3.0 -> 30000, etc.
211 iPhoneOSStr[0] = '0' + Min;
Chris Lattner8b30c412008-09-30 01:00:25 +0000212 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000213
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000214 // Handle minor version: 2.2 -> darwin9.2.2 -> 20200
215 iPhoneOSStr[2] = std::min(Rev, 9U)+'0';
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000216 Define(Defs, "__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__",
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000217 iPhoneOSStr);
Chris Lattner8b30c412008-09-30 01:00:25 +0000218 }
Eli Friedman618234a2008-08-20 02:34:37 +0000219}
Reid Spencer5f016e22007-07-11 17:01:13 +0000220
Chris Lattnerae0ee032008-12-04 23:20:07 +0000221/// GetDarwinLanguageOptions - Set the default language options for darwin.
222static void GetDarwinLanguageOptions(LangOptions &Opts,
223 const char *Triple) {
224 Opts.NeXTRuntime = true;
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000225
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000226 unsigned Maj, Min, Rev;
227 if (!getDarwinNumber(Triple, Maj, Min, Rev))
Chris Lattnerae0ee032008-12-04 23:20:07 +0000228 return;
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000229
Chris Lattnerae0ee032008-12-04 23:20:07 +0000230 // Blocks default to on for 10.6 (darwin10) and beyond.
Fariborz Jahaniana30b17b2009-02-12 17:54:33 +0000231 // As does nonfragile-abi for 64bit mode
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000232 if (Maj > 9)
Chris Lattnerae0ee032008-12-04 23:20:07 +0000233 Opts.Blocks = 1;
Fariborz Jahanian66a5c2c2009-02-24 23:34:44 +0000234
Fariborz Jahanian84d01332009-02-24 23:38:42 +0000235 if (Maj >= 9 && Opts.ObjC1 && !strncmp(Triple, "x86_64", 6))
236 Opts.ObjCNonFragileABI = 1;
Chris Lattnerae0ee032008-12-04 23:20:07 +0000237}
238
239
Chris Lattnerd29b6302008-10-05 21:50:58 +0000240//===----------------------------------------------------------------------===//
Eli Friedmane4277982008-08-20 23:11:40 +0000241// Specific target implementations.
242//===----------------------------------------------------------------------===//
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000243
Eli Friedmane4277982008-08-20 23:11:40 +0000244namespace {
245// PPC abstract base class
246class PPCTargetInfo : public TargetInfo {
247 static const Builtin::Info BuiltinInfo[];
248 static const char * const GCCRegNames[];
249 static const TargetInfo::GCCRegAlias GCCRegAliases[];
250
251public:
252 PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {
253 CharIsSigned = false;
254 }
255 virtual void getTargetBuiltins(const Builtin::Info *&Records,
256 unsigned &NumRecords) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000257 Records = BuiltinInfo;
Eli Friedmane4277982008-08-20 23:11:40 +0000258 NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
Reid Spencer5f016e22007-07-11 17:01:13 +0000259 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000260
Chris Lattner33328642009-03-20 15:52:06 +0000261 virtual void getTargetDefines(const LangOptions &Opts,
262 std::vector<char> &Defines) const;
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000263
Eli Friedmane4277982008-08-20 23:11:40 +0000264 virtual const char *getVAListDeclaration() const {
Chris Lattnerd5998502008-10-27 01:11:29 +0000265 return "typedef char* __builtin_va_list;";
266 // This is the right definition for ABI/V4: System V.4/eabi.
267 /*return "typedef struct __va_list_tag {"
Eli Friedmane4277982008-08-20 23:11:40 +0000268 " unsigned char gpr;"
269 " unsigned char fpr;"
270 " unsigned short reserved;"
271 " void* overflow_arg_area;"
272 " void* reg_save_area;"
Chris Lattnerd5998502008-10-27 01:11:29 +0000273 "} __builtin_va_list[1];";*/
Anders Carlsson3346ae62007-11-24 23:38:12 +0000274 }
Eli Friedmane4277982008-08-20 23:11:40 +0000275 virtual const char *getTargetPrefix() const {
276 return "ppc";
Anders Carlssond04c6e22007-11-27 04:11:28 +0000277 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000278 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedmane4277982008-08-20 23:11:40 +0000279 unsigned &NumNames) const;
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000280 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Eli Friedmane4277982008-08-20 23:11:40 +0000281 unsigned &NumAliases) const;
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000282 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattner44def072009-04-26 07:16:29 +0000283 TargetInfo::ConstraintInfo &Info) const {
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000284 switch (*Name) {
Anders Carlssond04c6e22007-11-27 04:11:28 +0000285 default: return false;
286 case 'O': // Zero
287 return true;
288 case 'b': // Base register
289 case 'f': // Floating point register
Chris Lattner44def072009-04-26 07:16:29 +0000290 Info.setAllowsRegister();
Anders Carlssond04c6e22007-11-27 04:11:28 +0000291 return true;
292 }
293 }
Eli Friedmane4277982008-08-20 23:11:40 +0000294 virtual const char *getClobbers() const {
295 return "";
Anders Carlssond04c6e22007-11-27 04:11:28 +0000296 }
Eli Friedmane4277982008-08-20 23:11:40 +0000297};
Anders Carlssond04c6e22007-11-27 04:11:28 +0000298
Eli Friedmane4277982008-08-20 23:11:40 +0000299const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
Douglas Gregorb1152d82009-02-16 21:58:21 +0000300#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
301#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
Eli Friedmane4277982008-08-20 23:11:40 +0000302#include "clang/AST/PPCBuiltins.def"
303};
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000304
305
Chris Lattnerc0f59212009-03-02 22:27:17 +0000306/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
307/// #defines that are not tied to a specific subtarget.
Chris Lattner33328642009-03-20 15:52:06 +0000308void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
309 std::vector<char> &Defs) const {
Chris Lattnerc0f59212009-03-02 22:27:17 +0000310 // Target identification.
311 Define(Defs, "__ppc__");
312 Define(Defs, "_ARCH_PPC");
313 Define(Defs, "__POWERPC__");
314 if (PointerWidth == 64) {
315 Define(Defs, "_ARCH_PPC64");
316 Define(Defs, "_LP64");
317 Define(Defs, "__LP64__");
318 Define(Defs, "__ppc64__");
319 } else {
320 Define(Defs, "__ppc__");
321 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000322
Chris Lattnerc0f59212009-03-02 22:27:17 +0000323 // Target properties.
324 Define(Defs, "_BIG_ENDIAN");
325 Define(Defs, "__BIG_ENDIAN__");
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000326
Chris Lattnerc0f59212009-03-02 22:27:17 +0000327 // Subtarget options.
328 Define(Defs, "__NATURAL_ALIGNMENT__");
329 Define(Defs, "__REGISTER_PREFIX__", "");
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000330
Chris Lattnerc0f59212009-03-02 22:27:17 +0000331 // FIXME: Should be controlled by command line option.
332 Define(Defs, "__LONG_DOUBLE_128__");
333}
334
Chris Lattner393ff042008-04-21 18:56:49 +0000335
Eli Friedmane4277982008-08-20 23:11:40 +0000336const char * const PPCTargetInfo::GCCRegNames[] = {
337 "0", "1", "2", "3", "4", "5", "6", "7",
338 "8", "9", "10", "11", "12", "13", "14", "15",
339 "16", "17", "18", "19", "20", "21", "22", "23",
340 "24", "25", "26", "27", "28", "29", "30", "31",
341 "0", "1", "2", "3", "4", "5", "6", "7",
342 "8", "9", "10", "11", "12", "13", "14", "15",
343 "16", "17", "18", "19", "20", "21", "22", "23",
344 "24", "25", "26", "27", "28", "29", "30", "31",
345 "mq", "lr", "ctr", "ap",
346 "0", "1", "2", "3", "4", "5", "6", "7",
347 "xer",
348 "0", "1", "2", "3", "4", "5", "6", "7",
349 "8", "9", "10", "11", "12", "13", "14", "15",
350 "16", "17", "18", "19", "20", "21", "22", "23",
351 "24", "25", "26", "27", "28", "29", "30", "31",
352 "vrsave", "vscr",
353 "spe_acc", "spefscr",
354 "sfp"
355};
Reid Spencer5f016e22007-07-11 17:01:13 +0000356
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000357void PPCTargetInfo::getGCCRegNames(const char * const *&Names,
Eli Friedmane4277982008-08-20 23:11:40 +0000358 unsigned &NumNames) const {
359 Names = GCCRegNames;
360 NumNames = llvm::array_lengthof(GCCRegNames);
361}
Reid Spencer5f016e22007-07-11 17:01:13 +0000362
Eli Friedmane4277982008-08-20 23:11:40 +0000363const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
364 // While some of these aliases do map to different registers
365 // they still share the same register name.
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000366 { { "cc", "cr0", "fr0", "r0", "v0"}, "0" },
367 { { "cr1", "fr1", "r1", "sp", "v1"}, "1" },
368 { { "cr2", "fr2", "r2", "toc", "v2"}, "2" },
369 { { "cr3", "fr3", "r3", "v3"}, "3" },
370 { { "cr4", "fr4", "r4", "v4"}, "4" },
371 { { "cr5", "fr5", "r5", "v5"}, "5" },
372 { { "cr6", "fr6", "r6", "v6"}, "6" },
373 { { "cr7", "fr7", "r7", "v7"}, "7" },
374 { { "fr8", "r8", "v8"}, "8" },
375 { { "fr9", "r9", "v9"}, "9" },
376 { { "fr10", "r10", "v10"}, "10" },
377 { { "fr11", "r11", "v11"}, "11" },
378 { { "fr12", "r12", "v12"}, "12" },
379 { { "fr13", "r13", "v13"}, "13" },
380 { { "fr14", "r14", "v14"}, "14" },
381 { { "fr15", "r15", "v15"}, "15" },
382 { { "fr16", "r16", "v16"}, "16" },
383 { { "fr17", "r17", "v17"}, "17" },
384 { { "fr18", "r18", "v18"}, "18" },
385 { { "fr19", "r19", "v19"}, "19" },
386 { { "fr20", "r20", "v20"}, "20" },
387 { { "fr21", "r21", "v21"}, "21" },
388 { { "fr22", "r22", "v22"}, "22" },
389 { { "fr23", "r23", "v23"}, "23" },
390 { { "fr24", "r24", "v24"}, "24" },
391 { { "fr25", "r25", "v25"}, "25" },
392 { { "fr26", "r26", "v26"}, "26" },
393 { { "fr27", "r27", "v27"}, "27" },
394 { { "fr28", "r28", "v28"}, "28" },
395 { { "fr29", "r29", "v29"}, "29" },
396 { { "fr30", "r30", "v30"}, "30" },
397 { { "fr31", "r31", "v31"}, "31" },
Eli Friedmane4277982008-08-20 23:11:40 +0000398};
399
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000400void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
Eli Friedmane4277982008-08-20 23:11:40 +0000401 unsigned &NumAliases) const {
402 Aliases = GCCRegAliases;
403 NumAliases = llvm::array_lengthof(GCCRegAliases);
404}
405} // end anonymous namespace.
Reid Spencer5f016e22007-07-11 17:01:13 +0000406
407namespace {
Eli Friedmane4277982008-08-20 23:11:40 +0000408class PPC32TargetInfo : public PPCTargetInfo {
Reid Spencer5f016e22007-07-11 17:01:13 +0000409public:
Eli Friedmaned855cb2008-08-21 00:13:15 +0000410 PPC32TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
411 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
412 "i64:64:64-f32:32:32-f64:64:64-v128:128:128";
413 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000414};
415} // end anonymous namespace.
416
417namespace {
Eli Friedmane4277982008-08-20 23:11:40 +0000418class PPC64TargetInfo : public PPCTargetInfo {
Reid Spencer5f016e22007-07-11 17:01:13 +0000419public:
Eli Friedmane4277982008-08-20 23:11:40 +0000420 PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
Chris Lattnerf291b102008-05-09 06:17:04 +0000421 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedmaned855cb2008-08-21 00:13:15 +0000422 DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
423 "i64:64:64-f32:32:32-f64:64:64-v128:128:128";
Chris Lattnerf291b102008-05-09 06:17:04 +0000424 }
Eli Friedmane4277982008-08-20 23:11:40 +0000425};
426} // end anonymous namespace.
427
Chris Lattnerae0ee032008-12-04 23:20:07 +0000428
Eli Friedmane4277982008-08-20 23:11:40 +0000429namespace {
430class DarwinPPCTargetInfo : public PPC32TargetInfo {
431public:
432 DarwinPPCTargetInfo(const std::string& triple) : PPC32TargetInfo(triple) {}
Chris Lattner33328642009-03-20 15:52:06 +0000433 virtual void getTargetDefines(const LangOptions &Opts,
434 std::vector<char> &Defines) const {
435 PPC32TargetInfo::getTargetDefines(Opts, Defines);
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000436 getDarwinDefines(Defines, Opts);
437 getDarwinOSXDefines(Defines, getTargetTriple());
Reid Spencer5f016e22007-07-11 17:01:13 +0000438 }
Daniel Dunbardcb4a1a2008-08-23 08:43:39 +0000439
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000440 /// getDefaultLangOptions - Allow the target to specify default settings for
441 /// various language options. These may be overridden by command line
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000442 /// options.
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000443 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattnerae0ee032008-12-04 23:20:07 +0000444 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000445 }
Eli Friedmane4277982008-08-20 23:11:40 +0000446};
447} // end anonymous namespace.
448
449namespace {
450class DarwinPPC64TargetInfo : public PPC64TargetInfo {
451public:
452 DarwinPPC64TargetInfo(const std::string& triple) : PPC64TargetInfo(triple) {}
Chris Lattner33328642009-03-20 15:52:06 +0000453 virtual void getTargetDefines(const LangOptions &Opts,
454 std::vector<char> &Defines) const {
455 PPC64TargetInfo::getTargetDefines(Opts, Defines);
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000456 getDarwinDefines(Defines, Opts);
457 getDarwinOSXDefines(Defines, getTargetTriple());
Anders Carlsson3346ae62007-11-24 23:38:12 +0000458 }
Daniel Dunbardcb4a1a2008-08-23 08:43:39 +0000459
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000460 /// getDefaultLangOptions - Allow the target to specify default settings for
461 /// various language options. These may be overridden by command line
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000462 /// options.
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000463 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattnerae0ee032008-12-04 23:20:07 +0000464 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000465 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000466};
467} // end anonymous namespace.
468
469namespace {
Eli Friedman618234a2008-08-20 02:34:37 +0000470// Namespace for x86 abstract base class
471const Builtin::Info BuiltinInfo[] = {
Douglas Gregorb1152d82009-02-16 21:58:21 +0000472#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
473#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
Eli Friedman618234a2008-08-20 02:34:37 +0000474#include "clang/AST/X86Builtins.def"
475};
Eli Friedman61538a72008-05-20 14:21:01 +0000476
Eli Friedman618234a2008-08-20 02:34:37 +0000477const char *GCCRegNames[] = {
478 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
479 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
480 "argp", "flags", "fspr", "dirflag", "frame",
481 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
482 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
483 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
484 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
485};
486
487const TargetInfo::GCCRegAlias GCCRegAliases[] = {
488 { { "al", "ah", "eax", "rax" }, "ax" },
489 { { "bl", "bh", "ebx", "rbx" }, "bx" },
490 { { "cl", "ch", "ecx", "rcx" }, "cx" },
491 { { "dl", "dh", "edx", "rdx" }, "dx" },
492 { { "esi", "rsi" }, "si" },
493 { { "edi", "rdi" }, "di" },
494 { { "esp", "rsp" }, "sp" },
495 { { "ebp", "rbp" }, "bp" },
496};
497
498// X86 target abstract base class; x86-32 and x86-64 are very close, so
499// most of the implementation can be shared.
500class X86TargetInfo : public TargetInfo {
Chris Lattner84f0ea82009-03-02 22:40:39 +0000501 enum X86SSEEnum {
502 NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42
503 } SSELevel;
Eli Friedman618234a2008-08-20 02:34:37 +0000504public:
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000505 X86TargetInfo(const std::string& triple)
Daniel Dunbar868bd0a2009-05-06 03:16:41 +0000506 : TargetInfo(triple), SSELevel(NoMMXSSE) {
Eli Friedman618234a2008-08-20 02:34:37 +0000507 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
Reid Spencer5f016e22007-07-11 17:01:13 +0000508 }
509 virtual void getTargetBuiltins(const Builtin::Info *&Records,
510 unsigned &NumRecords) const {
Eli Friedman618234a2008-08-20 02:34:37 +0000511 Records = BuiltinInfo;
512 NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
Reid Spencer5f016e22007-07-11 17:01:13 +0000513 }
Anders Carlsson44fe49c2007-12-08 19:32:57 +0000514 virtual const char *getTargetPrefix() const {
Eli Friedman618234a2008-08-20 02:34:37 +0000515 return "x86";
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000516 }
517 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedman618234a2008-08-20 02:34:37 +0000518 unsigned &NumNames) const {
519 Names = GCCRegNames;
520 NumNames = llvm::array_lengthof(GCCRegNames);
Anders Carlsson3346ae62007-11-24 23:38:12 +0000521 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000522 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Anders Carlsson3346ae62007-11-24 23:38:12 +0000523 unsigned &NumAliases) const {
Eli Friedman618234a2008-08-20 02:34:37 +0000524 Aliases = GCCRegAliases;
525 NumAliases = llvm::array_lengthof(GCCRegAliases);
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000526 }
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000527 virtual bool validateAsmConstraint(const char *&Name,
Eli Friedman618234a2008-08-20 02:34:37 +0000528 TargetInfo::ConstraintInfo &info) const;
529 virtual std::string convertConstraint(const char Constraint) const;
Anders Carlssond04c6e22007-11-27 04:11:28 +0000530 virtual const char *getClobbers() const {
Eli Friedman618234a2008-08-20 02:34:37 +0000531 return "~{dirflag},~{fpsr},~{flags}";
532 }
Chris Lattner33328642009-03-20 15:52:06 +0000533 virtual void getTargetDefines(const LangOptions &Opts,
534 std::vector<char> &Defines) const;
Daniel Dunbar17ca3632009-05-06 21:07:50 +0000535 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
536 const std::string &Name,
537 bool Enabled) const;
Daniel Dunbar868bd0a2009-05-06 03:16:41 +0000538 virtual void getDefaultFeatures(const std::string &CPU,
Daniel Dunbar17ca3632009-05-06 21:07:50 +0000539 llvm::StringMap<bool> &Features) const;
Daniel Dunbar868bd0a2009-05-06 03:16:41 +0000540 virtual void HandleTargetFeatures(const llvm::StringMap<bool> &Features);
Reid Spencer5f016e22007-07-11 17:01:13 +0000541};
Chris Lattner3daed522009-03-02 22:20:04 +0000542
Daniel Dunbar868bd0a2009-05-06 03:16:41 +0000543void X86TargetInfo::getDefaultFeatures(const std::string &CPU,
Daniel Dunbar17ca3632009-05-06 21:07:50 +0000544 llvm::StringMap<bool> &Features) const {
Daniel Dunbar868bd0a2009-05-06 03:16:41 +0000545 // FIXME: This should not be here.
546 Features["3dnow"] = false;
547 Features["3dnowa"] = false;
548 Features["mmx"] = false;
549 Features["sse"] = false;
550 Features["sse2"] = false;
551 Features["sse3"] = false;
552 Features["ssse3"] = false;
553 Features["sse41"] = false;
554 Features["sse42"] = false;
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000555
Daniel Dunbar868bd0a2009-05-06 03:16:41 +0000556 // LLVM does not currently recognize this.
557 // Features["sse4a"] = false;
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000558
Daniel Dunbar868bd0a2009-05-06 03:16:41 +0000559 // FIXME: This *really* should not be here.
560
561 // X86_64 always has SSE2.
562 if (PointerWidth == 64)
563 Features["sse2"] = Features["sse"] = Features["mmx"] = true;
564
Daniel Dunbar3ac79042009-05-06 21:56:32 +0000565 if (CPU == "generic" || CPU == "i386" || CPU == "i486" || CPU == "i586" ||
566 CPU == "pentium" || CPU == "i686" || CPU == "pentiumpro")
567 ;
568 else if (CPU == "pentium-mmx" || CPU == "pentium2")
569 setFeatureEnabled(Features, "mmx", true);
570 else if (CPU == "pentium3")
571 setFeatureEnabled(Features, "sse", true);
572 else if (CPU == "pentium-m" || CPU == "pentium4" || CPU == "x86-64")
573 setFeatureEnabled(Features, "sse2", true);
574 else if (CPU == "yonah" || CPU == "prescott" || CPU == "nocona")
575 setFeatureEnabled(Features, "sse3", true);
576 else if (CPU == "core2")
577 setFeatureEnabled(Features, "ssse3", true);
578 else if (CPU == "penryn") {
579 setFeatureEnabled(Features, "sse4", true);
580 Features["sse42"] = false;
581 } else if (CPU == "atom")
582 setFeatureEnabled(Features, "sse3", true);
583 else if (CPU == "corei7")
584 setFeatureEnabled(Features, "sse4", true);
585 else if (CPU == "k6" || CPU == "winchip-c6")
586 setFeatureEnabled(Features, "mmx", true);
587 else if (CPU == "k6-2" || CPU == "k6-3" || CPU == "athlon" ||
588 CPU == "athlon-tbird" || CPU == "winchip2" || CPU == "c3") {
589 setFeatureEnabled(Features, "mmx", true);
590 setFeatureEnabled(Features, "3dnow", true);
591 } else if (CPU == "athlon-4" || CPU == "athlon-xp" || CPU == "athlon-mp") {
592 setFeatureEnabled(Features, "sse", true);
593 setFeatureEnabled(Features, "3dnowa", true);
594 } else if (CPU == "k8" || CPU == "opteron" || CPU == "athlon64" ||
595 CPU == "athlon-fx") {
596 setFeatureEnabled(Features, "sse2", true);
597 setFeatureEnabled(Features, "3dnowa", true);
598 } else if (CPU == "c3-2")
599 setFeatureEnabled(Features, "sse", true);
Daniel Dunbar868bd0a2009-05-06 03:16:41 +0000600}
601
Daniel Dunbar17ca3632009-05-06 21:07:50 +0000602bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
603 const std::string &Name,
604 bool Enabled) const {
605 // FIXME: This *really* should not be here.
606 if (!Features.count(Name) && Name != "sse4")
607 return false;
608
609 if (Enabled) {
610 if (Name == "mmx")
611 Features["mmx"] = true;
612 else if (Name == "sse")
613 Features["mmx"] = Features["sse"] = true;
614 else if (Name == "sse2")
615 Features["mmx"] = Features["sse"] = Features["sse2"] = true;
616 else if (Name == "sse3")
617 Features["mmx"] = Features["sse"] = Features["sse2"] =
618 Features["sse3"] = true;
619 else if (Name == "ssse3")
620 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
621 Features["ssse3"] = true;
622 else if (Name == "sse4")
623 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
624 Features["ssse3"] = Features["sse41"] = Features["sse42"] = true;
625 else if (Name == "3dnow")
626 Features["3dnowa"] = true;
627 else if (Name == "3dnowa")
628 Features["3dnow"] = Features["3dnowa"] = true;
629 } else {
630 if (Name == "mmx")
631 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
632 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
633 else if (Name == "sse")
634 Features["sse"] = Features["sse2"] = Features["sse3"] =
635 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
636 else if (Name == "sse2")
637 Features["sse2"] = Features["sse3"] = Features["ssse3"] =
638 Features["sse41"] = Features["sse42"] = false;
639 else if (Name == "sse3")
640 Features["sse3"] = Features["ssse3"] = Features["sse41"] =
641 Features["sse42"] = false;
642 else if (Name == "ssse3")
643 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
644 else if (Name == "sse4")
645 Features["sse41"] = Features["sse42"] = false;
646 else if (Name == "3dnow")
647 Features["3dnow"] = Features["3dnowa"] = false;
648 else if (Name == "3dnowa")
649 Features["3dnowa"] = false;
650 }
651
652 return true;
653}
654
Daniel Dunbar868bd0a2009-05-06 03:16:41 +0000655/// HandleTargetOptions - Perform initialization based on the user
656/// configured set of features.
657void X86TargetInfo::HandleTargetFeatures(const llvm::StringMap<bool>&Features) {
658 if (Features.lookup("sse42"))
659 SSELevel = SSE42;
660 else if (Features.lookup("sse41"))
661 SSELevel = SSE41;
662 else if (Features.lookup("ssse3"))
663 SSELevel = SSSE3;
664 else if (Features.lookup("sse3"))
665 SSELevel = SSE3;
666 else if (Features.lookup("sse2"))
667 SSELevel = SSE2;
668 else if (Features.lookup("sse"))
669 SSELevel = SSE1;
670 else if (Features.lookup("mmx"))
671 SSELevel = MMX;
Chris Lattner3daed522009-03-02 22:20:04 +0000672}
Chris Lattnerc0f59212009-03-02 22:27:17 +0000673
674/// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines
675/// that are not tied to a specific subtarget.
Chris Lattner33328642009-03-20 15:52:06 +0000676void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
677 std::vector<char> &Defs) const {
Chris Lattnerc0f59212009-03-02 22:27:17 +0000678 // Target identification.
679 if (PointerWidth == 64) {
680 Define(Defs, "_LP64");
681 Define(Defs, "__LP64__");
682 Define(Defs, "__amd64__");
683 Define(Defs, "__amd64");
684 Define(Defs, "__x86_64");
685 Define(Defs, "__x86_64__");
Chris Lattnerc0f59212009-03-02 22:27:17 +0000686 } else {
Chris Lattnerca45cff2009-03-20 16:06:38 +0000687 DefineStd(Defs, "i386", Opts);
Chris Lattnerc0f59212009-03-02 22:27:17 +0000688 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000689
Chris Lattnerc0f59212009-03-02 22:27:17 +0000690 // Target properties.
691 Define(Defs, "__LITTLE_ENDIAN__");
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000692
Chris Lattnerc0f59212009-03-02 22:27:17 +0000693 // Subtarget options.
694 Define(Defs, "__nocona");
695 Define(Defs, "__nocona__");
696 Define(Defs, "__tune_nocona__");
Chris Lattnerc0f59212009-03-02 22:27:17 +0000697 Define(Defs, "__REGISTER_PREFIX__", "");
Chris Lattner84f0ea82009-03-02 22:40:39 +0000698
Chris Lattner54175442009-04-19 17:32:33 +0000699 // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline
700 // functions in glibc header files that use FP Stack inline asm which the
701 // backend can't deal with (PR879).
702 Define(Defs, "__NO_MATH_INLINES");
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000703
Chris Lattner84f0ea82009-03-02 22:40:39 +0000704 // Each case falls through to the previous one here.
705 switch (SSELevel) {
706 case SSE42:
707 Define(Defs, "__SSE4_2__");
708 case SSE41:
709 Define(Defs, "__SSE4_1__");
710 case SSSE3:
711 Define(Defs, "__SSSE3__");
712 case SSE3:
713 Define(Defs, "__SSE3__");
714 case SSE2:
715 Define(Defs, "__SSE2__");
716 Define(Defs, "__SSE2_MATH__"); // -mfp-math=sse always implied.
717 case SSE1:
718 Define(Defs, "__SSE__");
719 Define(Defs, "__SSE_MATH__"); // -mfp-math=sse always implied.
720 case MMX:
721 Define(Defs, "__MMX__");
722 case NoMMXSSE:
723 break;
724 }
Chris Lattnerc0f59212009-03-02 22:27:17 +0000725}
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000726
727
Eli Friedman618234a2008-08-20 02:34:37 +0000728bool
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000729X86TargetInfo::validateAsmConstraint(const char *&Name,
Chris Lattner44def072009-04-26 07:16:29 +0000730 TargetInfo::ConstraintInfo &Info) const {
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000731 switch (*Name) {
Eli Friedman618234a2008-08-20 02:34:37 +0000732 default: return false;
733 case 'a': // eax.
734 case 'b': // ebx.
735 case 'c': // ecx.
736 case 'd': // edx.
737 case 'S': // esi.
738 case 'D': // edi.
739 case 'A': // edx:eax.
740 case 't': // top of floating point stack.
741 case 'u': // second from top of floating point stack.
742 case 'q': // Any register accessible as [r]l: a, b, c, and d.
Anders Carlssonfce09342008-10-06 00:41:45 +0000743 case 'y': // Any MMX register.
Anders Carlssona7406d42008-10-06 19:17:39 +0000744 case 'x': // Any SSE register.
Eli Friedman618234a2008-08-20 02:34:37 +0000745 case 'Q': // Any register accessible as [r]h: a, b, c, and d.
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000746 case 'e': // 32-bit signed integer constant for use with zero-extending
Anders Carlsson79bc64c2009-01-24 18:03:09 +0000747 // x86_64 instructions.
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000748 case 'Z': // 32-bit unsigned integer constant for use with zero-extending
Anders Carlsson79bc64c2009-01-24 18:03:09 +0000749 // x86_64 instructions.
Eli Friedman618234a2008-08-20 02:34:37 +0000750 case 'N': // unsigned 8-bit integer constant for use with in and out
751 // instructions.
Chris Lattner44def072009-04-26 07:16:29 +0000752 Info.setAllowsRegister();
Eli Friedman618234a2008-08-20 02:34:37 +0000753 return true;
754 }
755}
756
757std::string
758X86TargetInfo::convertConstraint(const char Constraint) const {
759 switch (Constraint) {
760 case 'a': return std::string("{ax}");
761 case 'b': return std::string("{bx}");
762 case 'c': return std::string("{cx}");
763 case 'd': return std::string("{dx}");
764 case 'S': return std::string("{si}");
765 case 'D': return std::string("{di}");
766 case 't': // top of floating point stack.
767 return std::string("{st}");
768 case 'u': // second from top of floating point stack.
769 return std::string("{st(1)}"); // second from top of floating point stack.
770 default:
771 return std::string(1, Constraint);
772 }
773}
Eli Friedman618234a2008-08-20 02:34:37 +0000774} // end anonymous namespace
Reid Spencer5f016e22007-07-11 17:01:13 +0000775
776namespace {
Eli Friedman618234a2008-08-20 02:34:37 +0000777// X86-32 generic target
778class X86_32TargetInfo : public X86TargetInfo {
Reid Spencer5f016e22007-07-11 17:01:13 +0000779public:
Eli Friedman618234a2008-08-20 02:34:37 +0000780 X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
781 DoubleAlign = LongLongAlign = 32;
782 LongDoubleWidth = 96;
783 LongDoubleAlign = 32;
Eli Friedmaned855cb2008-08-21 00:13:15 +0000784 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
785 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
786 "a0:0:64-f80:32:32";
Eli Friedman1afabd92009-03-29 20:31:09 +0000787 SizeType = UnsignedInt;
788 PtrDiffType = SignedInt;
789 IntPtrType = SignedInt;
Anton Korobeynikov264a76c2009-04-03 23:38:25 +0000790 RegParmMax = 3;
Eli Friedman618234a2008-08-20 02:34:37 +0000791 }
792 virtual const char *getVAListDeclaration() const {
Eli Friedman01b86682008-08-20 07:28:14 +0000793 return "typedef char* __builtin_va_list;";
Eli Friedman618234a2008-08-20 02:34:37 +0000794 }
Eli Friedman618234a2008-08-20 02:34:37 +0000795};
796} // end anonymous namespace
797
798namespace {
799// x86-32 Darwin (OS X) target
800class DarwinI386TargetInfo : public X86_32TargetInfo {
801public:
802 DarwinI386TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
803 LongDoubleWidth = 128;
804 LongDoubleAlign = 128;
Eli Friedman1afabd92009-03-29 20:31:09 +0000805 SizeType = UnsignedLong;
806 IntPtrType = SignedLong;
Eli Friedmaned855cb2008-08-21 00:13:15 +0000807 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
808 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
809 "a0:0:64-f80:128:128";
Eli Friedmanb030f022009-04-19 21:38:35 +0000810 TLSSupported = false;
Eli Friedman618234a2008-08-20 02:34:37 +0000811 }
Daniel Dunbar8e5c2b82009-03-31 23:42:16 +0000812
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000813 virtual const char *getStringSymbolPrefix(bool IsConstant) const {
Daniel Dunbar8e5c2b82009-03-31 23:42:16 +0000814 return IsConstant ? "\01LC" : "\01lC";
815 }
816
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000817 virtual const char *getUnicodeStringSymbolPrefix() const {
Daniel Dunbara9668e02009-04-03 00:57:44 +0000818 return "__utf16_string_";
819 }
820
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000821 virtual const char *getUnicodeStringSection() const {
Daniel Dunbara9668e02009-04-03 00:57:44 +0000822 return "__TEXT,__ustring";
823 }
824
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000825 virtual const char *getCFStringSymbolPrefix() const {
Daniel Dunbar8e5c2b82009-03-31 23:42:16 +0000826 return "\01LC";
827 }
828
Chris Lattner33328642009-03-20 15:52:06 +0000829 virtual void getTargetDefines(const LangOptions &Opts,
830 std::vector<char> &Defines) const {
831 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000832 getDarwinDefines(Defines, Opts);
833 getDarwinOSXDefines(Defines, getTargetTriple());
Eli Friedman618234a2008-08-20 02:34:37 +0000834 }
Daniel Dunbar8e5c2b82009-03-31 23:42:16 +0000835
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000836 /// getDefaultLangOptions - Allow the target to specify default settings for
837 /// various language options. These may be overridden by command line
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000838 /// options.
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000839 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattnerae0ee032008-12-04 23:20:07 +0000840 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000841 }
Eli Friedman618234a2008-08-20 02:34:37 +0000842};
843} // end anonymous namespace
844
845namespace {
Chris Lattnerfd0269d2008-10-16 17:04:31 +0000846// x86-32 FreeBSD target
847class FreeBSDX86_32TargetInfo : public X86_32TargetInfo {
848public:
Eli Friedmanf509d732008-11-02 02:43:55 +0000849 FreeBSDX86_32TargetInfo(const std::string& triple) :
Eli Friedman1afabd92009-03-29 20:31:09 +0000850 X86_32TargetInfo(triple) { }
Chris Lattner33328642009-03-20 15:52:06 +0000851 virtual void getTargetDefines(const LangOptions &Opts,
852 std::vector<char> &Defines) const {
853 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattner318ca712009-03-20 15:55:34 +0000854 getFreeBSDDefines(Opts, 0, getTargetTriple(), Defines);
Chris Lattnerfd0269d2008-10-16 17:04:31 +0000855 }
856};
857} // end anonymous namespace
858
859namespace {
Chris Lattnereac7aee2008-08-23 18:23:14 +0000860// x86-32 DragonFly target
861class DragonFlyX86_32TargetInfo : public X86_32TargetInfo {
862public:
Eli Friedmanf509d732008-11-02 02:43:55 +0000863 DragonFlyX86_32TargetInfo(const std::string& triple) :
Eli Friedman1afabd92009-03-29 20:31:09 +0000864 X86_32TargetInfo(triple) { }
Chris Lattner33328642009-03-20 15:52:06 +0000865 virtual void getTargetDefines(const LangOptions &Opts,
866 std::vector<char> &Defines) const {
867 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattner318ca712009-03-20 15:55:34 +0000868 getDragonFlyDefines(Opts, Defines);
Chris Lattnereac7aee2008-08-23 18:23:14 +0000869 }
870};
871} // end anonymous namespace
872
873namespace {
Eli Friedman0d4047b2008-08-21 00:24:02 +0000874// x86-32 Linux target
875class LinuxX86_32TargetInfo : public X86_32TargetInfo {
876public:
877 LinuxX86_32TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
Chris Lattner9b533162008-10-05 19:44:25 +0000878 UserLabelPrefix = "";
Eli Friedman0d4047b2008-08-21 00:24:02 +0000879 }
Chris Lattner33328642009-03-20 15:52:06 +0000880 virtual void getTargetDefines(const LangOptions &Opts,
881 std::vector<char> &Defines) const {
882 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattner318ca712009-03-20 15:55:34 +0000883 getLinuxDefines(Opts, Defines);
Eli Friedman0d4047b2008-08-21 00:24:02 +0000884 }
885};
886} // end anonymous namespace
887
888namespace {
Eli Friedman29a30502008-08-21 01:40:19 +0000889// x86-32 Windows target
890class WindowsX86_32TargetInfo : public X86_32TargetInfo {
891public:
892 WindowsX86_32TargetInfo(const std::string& triple)
893 : X86_32TargetInfo(triple) {
Eli Friedmanb030f022009-04-19 21:38:35 +0000894 TLSSupported = false;
Eli Friedman29a30502008-08-21 01:40:19 +0000895 // FIXME: Fix wchar_t.
896 // FIXME: We should probably enable -fms-extensions by default for
897 // this target.
898 }
Chris Lattner33328642009-03-20 15:52:06 +0000899 virtual void getTargetDefines(const LangOptions &Opts,
900 std::vector<char> &Defines) const {
901 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Eli Friedman29a30502008-08-21 01:40:19 +0000902 // This list is based off of the the list of things MingW defines
Eli Friedman29a30502008-08-21 01:40:19 +0000903 Define(Defines, "_WIN32");
Chris Lattnerca45cff2009-03-20 16:06:38 +0000904 DefineStd(Defines, "WIN32", Opts);
905 DefineStd(Defines, "WINNT", Opts);
Eli Friedman29a30502008-08-21 01:40:19 +0000906 Define(Defines, "_X86_");
907 Define(Defines, "__MSVCRT__");
908 }
909};
910} // end anonymous namespace
911
912namespace {
Eli Friedman618234a2008-08-20 02:34:37 +0000913// x86-64 generic target
914class X86_64TargetInfo : public X86TargetInfo {
915public:
Chris Lattner33328642009-03-20 15:52:06 +0000916 X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) {
Chris Lattnerf291b102008-05-09 06:17:04 +0000917 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Chris Lattner778601f2009-01-28 06:58:19 +0000918 DoubleAlign = LongLongAlign = 64;
Eli Friedman61538a72008-05-20 14:21:01 +0000919 LongDoubleWidth = 128;
920 LongDoubleAlign = 128;
Chris Lattner06ebe862009-02-05 07:32:46 +0000921 IntMaxType = SignedLong;
922 UIntMaxType = UnsignedLong;
Anton Korobeynikov264a76c2009-04-03 23:38:25 +0000923 RegParmMax = 6;
Chris Lattner06ebe862009-02-05 07:32:46 +0000924
Eli Friedmaned855cb2008-08-21 00:13:15 +0000925 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
926 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
927 "a0:0:64-f80:128:128";
Reid Spencer5f016e22007-07-11 17:01:13 +0000928 }
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000929 virtual const char *getVAListDeclaration() const {
Eli Friedman01b86682008-08-20 07:28:14 +0000930 return "typedef struct __va_list_tag {"
931 " unsigned gp_offset;"
932 " unsigned fp_offset;"
933 " void* overflow_arg_area;"
934 " void* reg_save_area;"
935 "} __builtin_va_list[1];";
Anders Carlsson3346ae62007-11-24 23:38:12 +0000936 }
Eli Friedman618234a2008-08-20 02:34:37 +0000937};
938} // end anonymous namespace
939
940namespace {
Chris Lattnerfd0269d2008-10-16 17:04:31 +0000941// x86-64 FreeBSD target
942class FreeBSDX86_64TargetInfo : public X86_64TargetInfo {
943public:
Chris Lattner33328642009-03-20 15:52:06 +0000944 FreeBSDX86_64TargetInfo(const std::string &triple)
945 : X86_64TargetInfo(triple) {}
946 virtual void getTargetDefines(const LangOptions &Opts,
947 std::vector<char> &Defines) const {
948 X86_64TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattner318ca712009-03-20 15:55:34 +0000949 getFreeBSDDefines(Opts, 1, getTargetTriple(), Defines);
Chris Lattnerfd0269d2008-10-16 17:04:31 +0000950 }
951};
952} // end anonymous namespace
953
954namespace {
Daniel Dunbarb55a42b2008-09-23 17:37:57 +0000955// x86-64 Linux target
956class LinuxX86_64TargetInfo : public X86_64TargetInfo {
957public:
958 LinuxX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) {
Chris Lattner9b533162008-10-05 19:44:25 +0000959 UserLabelPrefix = "";
Daniel Dunbarb55a42b2008-09-23 17:37:57 +0000960 }
Chris Lattner33328642009-03-20 15:52:06 +0000961 virtual void getTargetDefines(const LangOptions &Opts,
962 std::vector<char> &Defines) const {
963 X86_64TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattner318ca712009-03-20 15:55:34 +0000964 getLinuxDefines(Opts, Defines);
Daniel Dunbarb55a42b2008-09-23 17:37:57 +0000965 }
966};
967} // end anonymous namespace
968
969namespace {
Eli Friedman618234a2008-08-20 02:34:37 +0000970// x86-64 Darwin (OS X) target
971class DarwinX86_64TargetInfo : public X86_64TargetInfo {
972public:
Eli Friedmanb030f022009-04-19 21:38:35 +0000973 DarwinX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) {
974 TLSSupported = false;
975 }
Eli Friedman618234a2008-08-20 02:34:37 +0000976
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000977 virtual const char *getStringSymbolPrefix(bool IsConstant) const {
Daniel Dunbar8e5c2b82009-03-31 23:42:16 +0000978 return IsConstant ? "\01LC" : "\01lC";
979 }
980
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000981 virtual const char *getUnicodeStringSymbolPrefix() const {
Daniel Dunbara9668e02009-04-03 00:57:44 +0000982 return "__utf16_string_";
983 }
984
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000985 virtual const char *getUnicodeStringSection() const {
Daniel Dunbara9668e02009-04-03 00:57:44 +0000986 return "__TEXT,__ustring";
987 }
988
Anton Korobeynikova7c47172009-05-03 13:42:53 +0000989 virtual const char *getCFStringSymbolPrefix() const {
Daniel Dunbar8e5c2b82009-03-31 23:42:16 +0000990 return "\01L_unnamed_cfstring_";
991 }
992
Chris Lattner33328642009-03-20 15:52:06 +0000993 virtual void getTargetDefines(const LangOptions &Opts,
994 std::vector<char> &Defines) const {
995 X86_64TargetInfo::getTargetDefines(Opts, Defines);
Daniel Dunbar8d33cd72009-04-10 19:52:24 +0000996 getDarwinDefines(Defines, Opts);
997 getDarwinOSXDefines(Defines, getTargetTriple());
Anders Carlsson3346ae62007-11-24 23:38:12 +0000998 }
Daniel Dunbardcb4a1a2008-08-23 08:43:39 +0000999
Chris Lattner8fc4dfb2008-12-04 22:54:33 +00001000 /// getDefaultLangOptions - Allow the target to specify default settings for
1001 /// various language options. These may be overridden by command line
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001002 /// options.
Chris Lattner8fc4dfb2008-12-04 22:54:33 +00001003 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattnerae0ee032008-12-04 23:20:07 +00001004 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattner8fc4dfb2008-12-04 22:54:33 +00001005 }
Reid Spencer5f016e22007-07-11 17:01:13 +00001006};
1007} // end anonymous namespace.
1008
Chris Lattner393ff042008-04-21 18:56:49 +00001009namespace {
Eli Friedmana9f54962008-08-20 07:44:10 +00001010class ARMTargetInfo : public TargetInfo {
Mike Stump437bb4b2009-04-08 02:07:04 +00001011 enum {
1012 Armv4t,
1013 Armv5,
1014 Armv6,
1015 XScale
1016 } ArmArch;
Chris Lattner393ff042008-04-21 18:56:49 +00001017public:
Eli Friedmana9f54962008-08-20 07:44:10 +00001018 ARMTargetInfo(const std::string& triple) : TargetInfo(triple) {
1019 // FIXME: Are the defaults correct for ARM?
Eli Friedmaned855cb2008-08-21 00:13:15 +00001020 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1021 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:64";
Chris Lattner5b37dc02009-04-23 04:22:04 +00001022 if (triple.find("arm-") == 0 || triple.find("armv6-") == 0)
Mike Stump437bb4b2009-04-08 02:07:04 +00001023 ArmArch = Armv6;
Chris Lattner5b37dc02009-04-23 04:22:04 +00001024 else if (triple.find("armv5-") == 0)
Mike Stump437bb4b2009-04-08 02:07:04 +00001025 ArmArch = Armv5;
Chris Lattner5b37dc02009-04-23 04:22:04 +00001026 else if (triple.find("armv4t-") == 0)
Mike Stump437bb4b2009-04-08 02:07:04 +00001027 ArmArch = Armv4t;
Chris Lattner5b37dc02009-04-23 04:22:04 +00001028 else if (triple.find("xscale-") == 0)
Mike Stump437bb4b2009-04-08 02:07:04 +00001029 ArmArch = XScale;
Chris Lattner5b37dc02009-04-23 04:22:04 +00001030 else if (triple.find("armv") == 0) {
1031 // FIXME: fuzzy match for other random weird arm triples. This is useful
1032 // for the static analyzer and other clients, but probably should be
1033 // re-evaluated when codegen is brought up.
1034 ArmArch = Armv6;
1035 }
Eli Friedman61538a72008-05-20 14:21:01 +00001036 }
Chris Lattner33328642009-03-20 15:52:06 +00001037 virtual void getTargetDefines(const LangOptions &Opts,
1038 std::vector<char> &Defs) const {
Chris Lattnerc0f59212009-03-02 22:27:17 +00001039 // Target identification.
1040 Define(Defs, "__arm");
1041 Define(Defs, "__arm__");
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001042
Chris Lattnerc0f59212009-03-02 22:27:17 +00001043 // Target properties.
1044 Define(Defs, "__LITTLE_ENDIAN__");
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001045
Mike Stump437bb4b2009-04-08 02:07:04 +00001046 // Subtarget options.
1047 if (ArmArch == Armv6) {
1048 Define(Defs, "__ARM_ARCH_6K__");
1049 Define(Defs, "__THUMB_INTERWORK__");
1050 } else if (ArmArch == Armv5) {
1051 Define(Defs, "__ARM_ARCH_5TEJ__");
1052 Define(Defs, "__THUMB_INTERWORK__");
1053 Define(Defs, "__SOFTFP__");
1054 } else if (ArmArch == Armv4t) {
1055 Define(Defs, "__ARM_ARCH_4T__");
1056 Define(Defs, "__SOFTFP__");
1057 } else if (ArmArch == XScale) {
1058 Define(Defs, "__ARM_ARCH_5TE__");
1059 Define(Defs, "__XSCALE__");
1060 Define(Defs, "__SOFTFP__");
1061 }
Chris Lattnerc0f59212009-03-02 22:27:17 +00001062 Define(Defs, "__ARMEL__");
Chris Lattner393ff042008-04-21 18:56:49 +00001063 }
1064 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1065 unsigned &NumRecords) const {
Eli Friedmana9f54962008-08-20 07:44:10 +00001066 // FIXME: Implement.
1067 Records = 0;
Chris Lattner393ff042008-04-21 18:56:49 +00001068 NumRecords = 0;
1069 }
1070 virtual const char *getVAListDeclaration() const {
Eli Friedmana9f54962008-08-20 07:44:10 +00001071 return "typedef char* __builtin_va_list;";
Chris Lattner393ff042008-04-21 18:56:49 +00001072 }
1073 virtual const char *getTargetPrefix() const {
Eli Friedmana9f54962008-08-20 07:44:10 +00001074 return "arm";
Chris Lattner393ff042008-04-21 18:56:49 +00001075 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001076 virtual void getGCCRegNames(const char * const *&Names,
Chris Lattner393ff042008-04-21 18:56:49 +00001077 unsigned &NumNames) const {
Eli Friedmana9f54962008-08-20 07:44:10 +00001078 // FIXME: Implement.
1079 Names = 0;
Chris Lattner393ff042008-04-21 18:56:49 +00001080 NumNames = 0;
1081 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001082 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattner393ff042008-04-21 18:56:49 +00001083 unsigned &NumAliases) const {
Eli Friedmana9f54962008-08-20 07:44:10 +00001084 // FIXME: Implement.
1085 Aliases = 0;
Chris Lattner393ff042008-04-21 18:56:49 +00001086 NumAliases = 0;
1087 }
Anders Carlsson066d2ea2009-02-28 17:11:49 +00001088 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattner44def072009-04-26 07:16:29 +00001089 TargetInfo::ConstraintInfo &Info) const {
Eli Friedmana9f54962008-08-20 07:44:10 +00001090 // FIXME: Check if this is complete
Anders Carlsson066d2ea2009-02-28 17:11:49 +00001091 switch (*Name) {
Eli Friedmana9f54962008-08-20 07:44:10 +00001092 default:
Nate Begemanad487f42008-04-22 05:03:19 +00001093 case 'l': // r0-r7
1094 case 'h': // r8-r15
1095 case 'w': // VFP Floating point register single precision
1096 case 'P': // VFP Floating point register double precision
Chris Lattner44def072009-04-26 07:16:29 +00001097 Info.setAllowsRegister();
Nate Begemanad487f42008-04-22 05:03:19 +00001098 return true;
1099 }
Chris Lattner393ff042008-04-21 18:56:49 +00001100 return false;
1101 }
1102 virtual const char *getClobbers() const {
Eli Friedmana9f54962008-08-20 07:44:10 +00001103 // FIXME: Is this really right?
Chris Lattner393ff042008-04-21 18:56:49 +00001104 return "";
1105 }
1106};
1107} // end anonymous namespace.
1108
Eli Friedmana9f54962008-08-20 07:44:10 +00001109
1110namespace {
1111class DarwinARMTargetInfo : public ARMTargetInfo {
1112public:
Eli Friedmanb030f022009-04-19 21:38:35 +00001113 DarwinARMTargetInfo(const std::string& triple) : ARMTargetInfo(triple) {
1114 TLSSupported = false;
1115 }
Eli Friedmana9f54962008-08-20 07:44:10 +00001116
Chris Lattner33328642009-03-20 15:52:06 +00001117 virtual void getTargetDefines(const LangOptions &Opts,
1118 std::vector<char> &Defines) const {
1119 ARMTargetInfo::getTargetDefines(Opts, Defines);
Daniel Dunbar8d33cd72009-04-10 19:52:24 +00001120 getDarwinDefines(Defines, Opts);
1121 getDarwinIPhoneOSDefines(Defines, getTargetTriple());
Eli Friedmana9f54962008-08-20 07:44:10 +00001122 }
1123};
1124} // end anonymous namespace.
1125
Reid Spencer5f016e22007-07-11 17:01:13 +00001126namespace {
Daniel Dunbar1e0107a2009-03-23 16:09:04 +00001127// arm FreeBSD target
1128class FreeBSDARMTargetInfo : public ARMTargetInfo {
1129public:
1130 FreeBSDARMTargetInfo(const std::string& triple) : ARMTargetInfo(triple) {}
1131 virtual void getTargetDefines(const LangOptions &Opts,
1132 std::vector<char> &Defines) const {
1133 ARMTargetInfo::getTargetDefines(Opts, Defines);
1134 getFreeBSDDefines(Opts, 0, getTargetTriple(), Defines);
1135 }
1136};
1137} // end anonymous namespace
1138
1139namespace {
Eli Friedman01b86682008-08-20 07:28:14 +00001140class SparcV8TargetInfo : public TargetInfo {
Chris Lattnere957f532009-01-27 01:58:38 +00001141 static const TargetInfo::GCCRegAlias GCCRegAliases[];
1142 static const char * const GCCRegNames[];
Gabor Greif26658672008-02-21 16:29:08 +00001143public:
Eli Friedman01b86682008-08-20 07:28:14 +00001144 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
1145 // FIXME: Support Sparc quad-precision long double?
Eli Friedmaned855cb2008-08-21 00:13:15 +00001146 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1147 "i64:64:64-f32:32:32-f64:64:64-v64:64:64";
Eli Friedman01b86682008-08-20 07:28:14 +00001148 }
Chris Lattner33328642009-03-20 15:52:06 +00001149 virtual void getTargetDefines(const LangOptions &Opts,
1150 std::vector<char> &Defines) const {
Eli Friedman01b86682008-08-20 07:28:14 +00001151 // FIXME: This is missing a lot of important defines; some of the
1152 // missing stuff is likely to break system headers.
Gabor Greif26658672008-02-21 16:29:08 +00001153 Define(Defines, "__sparc");
Eli Friedmanbf0c9bd2008-05-25 05:26:09 +00001154 Define(Defines, "__sparc__");
Gabor Greif26658672008-02-21 16:29:08 +00001155 Define(Defines, "__sparcv8");
1156 }
1157 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1158 unsigned &NumRecords) const {
Eli Friedman01b86682008-08-20 07:28:14 +00001159 // FIXME: Implement!
Gabor Greif26658672008-02-21 16:29:08 +00001160 }
1161 virtual const char *getVAListDeclaration() const {
Eli Friedman01b86682008-08-20 07:28:14 +00001162 return "typedef void* __builtin_va_list;";
Gabor Greif26658672008-02-21 16:29:08 +00001163 }
1164 virtual const char *getTargetPrefix() const {
Eli Friedman01b86682008-08-20 07:28:14 +00001165 return "sparc";
Gabor Greif26658672008-02-21 16:29:08 +00001166 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001167 virtual void getGCCRegNames(const char * const *&Names,
Chris Lattnere957f532009-01-27 01:58:38 +00001168 unsigned &NumNames) const;
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001169 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattnere957f532009-01-27 01:58:38 +00001170 unsigned &NumAliases) const;
Anders Carlsson066d2ea2009-02-28 17:11:49 +00001171 virtual bool validateAsmConstraint(const char *&Name,
Gabor Greif26658672008-02-21 16:29:08 +00001172 TargetInfo::ConstraintInfo &info) const {
Eli Friedman01b86682008-08-20 07:28:14 +00001173 // FIXME: Implement!
1174 return false;
Gabor Greif26658672008-02-21 16:29:08 +00001175 }
1176 virtual const char *getClobbers() const {
Eli Friedman01b86682008-08-20 07:28:14 +00001177 // FIXME: Implement!
1178 return "";
Gabor Greif26658672008-02-21 16:29:08 +00001179 }
1180};
1181
Chris Lattnere957f532009-01-27 01:58:38 +00001182const char * const SparcV8TargetInfo::GCCRegNames[] = {
1183 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1184 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
1185 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
1186 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
1187};
1188
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001189void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names,
Chris Lattnere957f532009-01-27 01:58:38 +00001190 unsigned &NumNames) const {
1191 Names = GCCRegNames;
1192 NumNames = llvm::array_lengthof(GCCRegNames);
1193}
1194
1195const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = {
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001196 { { "g0" }, "r0" },
1197 { { "g1" }, "r1" },
1198 { { "g2" }, "r2" },
1199 { { "g3" }, "r3" },
1200 { { "g4" }, "r4" },
1201 { { "g5" }, "r5" },
1202 { { "g6" }, "r6" },
1203 { { "g7" }, "r7" },
1204 { { "o0" }, "r8" },
1205 { { "o1" }, "r9" },
1206 { { "o2" }, "r10" },
1207 { { "o3" }, "r11" },
1208 { { "o4" }, "r12" },
1209 { { "o5" }, "r13" },
1210 { { "o6", "sp" }, "r14" },
1211 { { "o7" }, "r15" },
1212 { { "l0" }, "r16" },
1213 { { "l1" }, "r17" },
1214 { { "l2" }, "r18" },
1215 { { "l3" }, "r19" },
1216 { { "l4" }, "r20" },
1217 { { "l5" }, "r21" },
1218 { { "l6" }, "r22" },
1219 { { "l7" }, "r23" },
1220 { { "i0" }, "r24" },
1221 { { "i1" }, "r25" },
1222 { { "i2" }, "r26" },
1223 { { "i3" }, "r27" },
1224 { { "i4" }, "r28" },
1225 { { "i5" }, "r29" },
1226 { { "i6", "fp" }, "r30" },
1227 { { "i7" }, "r31" },
Chris Lattnere957f532009-01-27 01:58:38 +00001228};
1229
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001230void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattnere957f532009-01-27 01:58:38 +00001231 unsigned &NumAliases) const {
1232 Aliases = GCCRegAliases;
1233 NumAliases = llvm::array_lengthof(GCCRegAliases);
1234}
Gabor Greif26658672008-02-21 16:29:08 +00001235} // end anonymous namespace.
1236
Eli Friedman01b86682008-08-20 07:28:14 +00001237namespace {
1238class SolarisSparcV8TargetInfo : public SparcV8TargetInfo {
1239public:
1240 SolarisSparcV8TargetInfo(const std::string& triple) :
Eli Friedmanf509d732008-11-02 02:43:55 +00001241 SparcV8TargetInfo(triple) {
1242 SizeType = UnsignedInt;
1243 PtrDiffType = SignedInt;
1244 }
Eli Friedman01b86682008-08-20 07:28:14 +00001245
Chris Lattner33328642009-03-20 15:52:06 +00001246 virtual void getTargetDefines(const LangOptions &Opts,
1247 std::vector<char> &Defines) const {
1248 SparcV8TargetInfo::getTargetDefines(Opts, Defines);
Eli Friedman01b86682008-08-20 07:28:14 +00001249 getSolarisDefines(Defines);
1250 }
1251};
1252} // end anonymous namespace.
Reid Spencer5f016e22007-07-11 17:01:13 +00001253
Chris Lattner2621fd12008-05-08 05:58:21 +00001254namespace {
1255 class PIC16TargetInfo : public TargetInfo{
1256 public:
1257 PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) {
Eli Friedmanb030f022009-04-19 21:38:35 +00001258 TLSSupported = false;
Sanjiv Gupta31fc07d2008-10-31 09:52:39 +00001259 IntWidth = 16;
1260 LongWidth = LongLongWidth = 32;
1261 PointerWidth = 16;
1262 IntAlign = 8;
1263 LongAlign = LongLongAlign = 8;
Eli Friedman61538a72008-05-20 14:21:01 +00001264 PointerAlign = 8;
Sanjiv Gupta31fc07d2008-10-31 09:52:39 +00001265 SizeType = UnsignedInt;
1266 IntMaxType = SignedLong;
1267 UIntMaxType = UnsignedLong;
Chris Lattner6ad474f2009-02-13 22:28:55 +00001268 IntPtrType = SignedShort;
Eli Friedmanf509d732008-11-02 02:43:55 +00001269 PtrDiffType = SignedInt;
Sanjiv Gupta364af812008-08-18 10:05:22 +00001270 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8";
Chris Lattner2621fd12008-05-08 05:58:21 +00001271 }
Chris Lattner927686f2008-05-09 06:08:39 +00001272 virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; }
1273 virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; }
Chris Lattner33328642009-03-20 15:52:06 +00001274 virtual void getTargetDefines(const LangOptions &Opts,
1275 std::vector<char> &Defines) const {
Chris Lattner2621fd12008-05-08 05:58:21 +00001276 Define(Defines, "__pic16");
1277 }
1278 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1279 unsigned &NumRecords) const {}
1280 virtual const char *getVAListDeclaration() const { return "";}
1281 virtual const char *getClobbers() const {return "";}
Sanjiv Gupta70aa5f92009-04-21 06:01:16 +00001282 virtual const char *getTargetPrefix() const {return "pic16";}
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001283 virtual void getGCCRegNames(const char * const *&Names,
1284 unsigned &NumNames) const {}
1285 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattner2621fd12008-05-08 05:58:21 +00001286 TargetInfo::ConstraintInfo &info) const {
1287 return true;
1288 }
Anton Korobeynikova7c47172009-05-03 13:42:53 +00001289 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattner2621fd12008-05-08 05:58:21 +00001290 unsigned &NumAliases) const {}
1291 virtual bool useGlobalsForAutomaticVariables() const {return true;}
1292 };
1293}
1294
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00001295namespace {
1296 class MSP430TargetInfo : public TargetInfo {
1297 static const char * const GCCRegNames[];
1298 public:
1299 MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) {
1300 TLSSupported = false;
1301 IntWidth = 16;
1302 LongWidth = LongLongWidth = 32;
1303 PointerWidth = 16;
1304 IntAlign = 8;
1305 LongAlign = LongLongAlign = 8;
1306 PointerAlign = 8;
1307 SizeType = UnsignedInt;
1308 IntMaxType = SignedLong;
1309 UIntMaxType = UnsignedLong;
1310 IntPtrType = SignedShort;
1311 PtrDiffType = SignedInt;
1312 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8";
1313 }
1314 virtual void getTargetDefines(const LangOptions &Opts,
1315 std::vector<char> &Defines) const {
1316 Define(Defines, "MSP430");
1317 Define(Defines, "__MSP430__");
1318 // FIXME: defines for different 'flavours' of MCU
1319 }
1320 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1321 unsigned &NumRecords) const {
1322 // FIXME: Implement.
1323 Records = 0;
1324 NumRecords = 0;
1325 }
1326 virtual const char *getTargetPrefix() const {
1327 return "msp430";
1328 }
1329 virtual void getGCCRegNames(const char * const *&Names,
1330 unsigned &NumNames) const;
1331 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1332 unsigned &NumAliases) const {
1333 // No aliases.
1334 Aliases = 0;
1335 NumAliases = 0;
1336 }
1337 virtual bool validateAsmConstraint(const char *&Name,
1338 TargetInfo::ConstraintInfo &info) const {
1339 // FIXME: implement
1340 return true;
1341 }
1342 virtual const char *getClobbers() const {
1343 // FIXME: Is this really right?
1344 return "";
1345 }
1346 virtual const char *getVAListDeclaration() const {
1347 // FIXME: implement
Anton Korobeynikoveb716852009-05-08 18:24:57 +00001348 return "typedef char* __builtin_va_list;";
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00001349 }
1350 };
1351
1352 const char * const MSP430TargetInfo::GCCRegNames[] = {
1353 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1354 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1355 };
1356
1357 void MSP430TargetInfo::getGCCRegNames(const char * const *&Names,
1358 unsigned &NumNames) const {
1359 Names = GCCRegNames;
1360 NumNames = llvm::array_lengthof(GCCRegNames);
1361 }
1362}
1363
1364
Reid Spencer5f016e22007-07-11 17:01:13 +00001365//===----------------------------------------------------------------------===//
1366// Driver code
1367//===----------------------------------------------------------------------===//
1368
Ted Kremenek8448d382007-12-04 17:07:35 +00001369static inline bool IsX86(const std::string& TT) {
Ted Kremenekae360762007-12-03 22:06:55 +00001370 return (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' &&
1371 TT[4] == '-' && TT[1] - '3' < 6);
1372}
1373
Chris Lattner42e67372008-03-05 01:18:20 +00001374/// CreateTargetInfo - Return the target info object for the specified target
1375/// triple.
1376TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
Eli Friedmaned855cb2008-08-21 00:13:15 +00001377 // OS detection; this isn't really anywhere near complete.
1378 // Additions and corrections are welcome.
1379 bool isDarwin = T.find("-darwin") != std::string::npos;
Chris Lattnereac7aee2008-08-23 18:23:14 +00001380 bool isDragonFly = T.find("-dragonfly") != std::string::npos;
Chris Lattnerfd0269d2008-10-16 17:04:31 +00001381 bool isFreeBSD = T.find("-freebsd") != std::string::npos;
Eli Friedmaned855cb2008-08-21 00:13:15 +00001382 bool isSolaris = T.find("-solaris") != std::string::npos;
1383 bool isLinux = T.find("-linux") != std::string::npos;
1384 bool isWindows = T.find("-windows") != std::string::npos ||
1385 T.find("-win32") != std::string::npos ||
1386 T.find("-mingw") != std::string::npos;
Eli Friedman61538a72008-05-20 14:21:01 +00001387
Eli Friedmaned855cb2008-08-21 00:13:15 +00001388 if (T.find("ppc-") == 0 || T.find("powerpc-") == 0) {
1389 if (isDarwin)
1390 return new DarwinPPCTargetInfo(T);
1391 return new PPC32TargetInfo(T);
1392 }
Eli Friedman61538a72008-05-20 14:21:01 +00001393
Eli Friedmaned855cb2008-08-21 00:13:15 +00001394 if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0) {
1395 if (isDarwin)
1396 return new DarwinPPC64TargetInfo(T);
1397 return new PPC64TargetInfo(T);
1398 }
Chris Lattner393ff042008-04-21 18:56:49 +00001399
Chris Lattner5b37dc02009-04-23 04:22:04 +00001400 if (T.find("armv") == 0 || T.find("arm-") == 0 || T.find("xscale") == 0) {
Eli Friedmaned855cb2008-08-21 00:13:15 +00001401 if (isDarwin)
1402 return new DarwinARMTargetInfo(T);
Daniel Dunbar1e0107a2009-03-23 16:09:04 +00001403 if (isFreeBSD)
1404 return new FreeBSDARMTargetInfo(T);
Eli Friedmaned855cb2008-08-21 00:13:15 +00001405 return new ARMTargetInfo(T);
1406 }
Eli Friedman61538a72008-05-20 14:21:01 +00001407
Eli Friedmaned855cb2008-08-21 00:13:15 +00001408 if (T.find("sparc-") == 0) {
1409 if (isSolaris)
1410 return new SolarisSparcV8TargetInfo(T);
1411 return new SparcV8TargetInfo(T);
1412 }
1413
Chris Lattner54fefbe2009-02-20 17:04:14 +00001414 if (T.find("x86_64-") == 0 || T.find("amd64-") == 0) {
Eli Friedmaned855cb2008-08-21 00:13:15 +00001415 if (isDarwin)
1416 return new DarwinX86_64TargetInfo(T);
Daniel Dunbarb55a42b2008-09-23 17:37:57 +00001417 if (isLinux)
1418 return new LinuxX86_64TargetInfo(T);
Chris Lattnerfd0269d2008-10-16 17:04:31 +00001419 if (isFreeBSD)
1420 return new FreeBSDX86_64TargetInfo(T);
Eli Friedmaned855cb2008-08-21 00:13:15 +00001421 return new X86_64TargetInfo(T);
1422 }
Eli Friedman61538a72008-05-20 14:21:01 +00001423
Chris Lattner2621fd12008-05-08 05:58:21 +00001424 if (T.find("pic16-") == 0)
1425 return new PIC16TargetInfo(T);
1426
Anton Korobeynikov73c64e52009-05-03 13:43:08 +00001427 if (T.find("msp430-") == 0)
1428 return new MSP430TargetInfo(T);
1429
Eli Friedmaned855cb2008-08-21 00:13:15 +00001430 if (IsX86(T)) {
1431 if (isDarwin)
1432 return new DarwinI386TargetInfo(T);
Eli Friedman0d4047b2008-08-21 00:24:02 +00001433 if (isLinux)
1434 return new LinuxX86_32TargetInfo(T);
Chris Lattnereac7aee2008-08-23 18:23:14 +00001435 if (isDragonFly)
1436 return new DragonFlyX86_32TargetInfo(T);
Chris Lattnerfd0269d2008-10-16 17:04:31 +00001437 if (isFreeBSD)
1438 return new FreeBSDX86_32TargetInfo(T);
Eli Friedman29a30502008-08-21 01:40:19 +00001439 if (isWindows)
1440 return new WindowsX86_32TargetInfo(T);
Eli Friedmaned855cb2008-08-21 00:13:15 +00001441 return new X86_32TargetInfo(T);
1442 }
Eli Friedman61538a72008-05-20 14:21:01 +00001443
Chris Lattner42e67372008-03-05 01:18:20 +00001444 return NULL;
Reid Spencer5f016e22007-07-11 17:01:13 +00001445}