blob: 1b12b0a2f60823deb0ae75f1e27fada3b6536d1b [file] [log] [blame]
Chris Lattner4b009652007-07-25 00:24:17 +00001//===--- Targets.cpp - Implement -arch option and targets -----------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner959e5be2007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Chris Lattner4b009652007-07-25 00:24:17 +00007//
8//===----------------------------------------------------------------------===//
9//
Ted Kremenek38591a22007-12-12 18:05:32 +000010// This file implements construction of a TargetInfo object from a
11// target triple.
Chris Lattner4b009652007-07-25 00:24:17 +000012//
13//===----------------------------------------------------------------------===//
14
Douglas Gregor2e8a7aa2009-02-16 21:58:21 +000015// FIXME: Layering violation
Chris Lattner4b009652007-07-25 00:24:17 +000016#include "clang/AST/Builtins.h"
Anders Carlssone1449c12007-12-09 23:17:02 +000017#include "clang/AST/TargetBuiltins.h"
Chris Lattner4b009652007-07-25 00:24:17 +000018#include "clang/Basic/TargetInfo.h"
Chris Lattnerddae7102008-12-04 22:54:33 +000019#include "clang/Basic/LangOptions.h"
Anders Carlsson7dd1c952007-11-24 23:38:12 +000020#include "llvm/ADT/STLExtras.h"
Eli Friedmand4011892008-05-20 14:27:34 +000021#include "llvm/ADT/APFloat.h"
Chris Lattner4b009652007-07-25 00:24:17 +000022using namespace clang;
23
Chris Lattner4b009652007-07-25 00:24:17 +000024//===----------------------------------------------------------------------===//
25// Common code shared among targets.
26//===----------------------------------------------------------------------===//
27
Chris Lattner0db667a2007-10-06 06:57:34 +000028static void Define(std::vector<char> &Buf, const char *Macro,
29 const char *Val = "1") {
30 const char *Def = "#define ";
31 Buf.insert(Buf.end(), Def, Def+strlen(Def));
32 Buf.insert(Buf.end(), Macro, Macro+strlen(Macro));
33 Buf.push_back(' ');
34 Buf.insert(Buf.end(), Val, Val+strlen(Val));
35 Buf.push_back('\n');
36}
37
Chris Lattnerbd00eb82008-10-05 21:50:58 +000038//===----------------------------------------------------------------------===//
39// Defines specific to certain operating systems.
40//===----------------------------------------------------------------------===//
41
Eli Friedmanff158dd2008-08-20 07:28:14 +000042static void getSolarisDefines(std::vector<char> &Defs) {
43 Define(Defs, "__SUN__");
44 Define(Defs, "__SOLARIS__");
45}
Chris Lattner4b009652007-07-25 00:24:17 +000046
Nate Begemanff1ba1f2009-01-18 01:08:03 +000047static void getFreeBSDDefines(std::vector<char> &Defs, bool is64Bit,
48 const char *Triple) {
Chris Lattner98cb2a22008-10-16 17:04:31 +000049 // FreeBSD defines; list based off of gcc output
50
51 const char *FreeBSD = strstr(Triple, "-freebsd");
52 FreeBSD += strlen("-freebsd");
53 char release[] = "X";
54 release[0] = FreeBSD[0];
55 char version[] = "X00001";
56 version[0] = FreeBSD[0];
57
58 Define(Defs, "__FreeBSD__", release);
59 Define(Defs, "__FreeBSD_cc_version", version);
60 Define(Defs, "__KPRINTF_ATTRIBUTE__");
61 Define(Defs, "unix");
Anton Korobeynikovfb820852009-02-14 16:42:50 +000062 Define(Defs, "__ELF__", "1");
Chris Lattner98cb2a22008-10-16 17:04:31 +000063 if (is64Bit) {
64 Define(Defs, "__LP64__");
65 }
66}
67
Chris Lattnerbd00eb82008-10-05 21:50:58 +000068static void getDragonFlyDefines(std::vector<char> &Defs) {
69 // DragonFly defines; list based off of gcc output
70 Define(Defs, "__DragonFly__");
71 Define(Defs, "__DragonFly_cc_version", "100001");
72 Define(Defs, "__ELF__");
73 Define(Defs, "__KPRINTF_ATTRIBUTE__");
74 Define(Defs, "__tune_i386__");
75 Define(Defs, "unix");
76 Define(Defs, "__unix");
77 Define(Defs, "__unix__");
78}
79
80static void getLinuxDefines(std::vector<char> &Defs) {
81 // Linux defines; list based off of gcc output
82 Define(Defs, "__unix__");
83 Define(Defs, "__unix");
84 Define(Defs, "unix");
85 Define(Defs, "__linux__");
86 Define(Defs, "__linux");
87 Define(Defs, "linux");
88 Define(Defs, "__gnu_linux__");
Argiris Kirtzidis99de9532009-02-14 15:02:45 +000089 Define(Defs, "__ELF__", "1");
Chris Lattnerbd00eb82008-10-05 21:50:58 +000090}
91
Chris Lattnerd7bc88b2008-12-04 23:20:07 +000092/// getDarwinNumber - Parse the 'darwin number' out of the specific targe
93/// triple. For example, if we have darwin8.5 return 8,5,4. If any entry is
94/// not defined, return 0's. Return true if we have -darwin in the string or
95/// false otherwise.
96static bool getDarwinNumber(const char *Triple, unsigned &Maj, unsigned &Min) {
97 Maj = Min = 0;
98 const char *Darwin = strstr(Triple, "-darwin");
99 if (Darwin == 0) return false;
100
101 Darwin += strlen("-darwin");
102 if (Darwin[0] < '0' || Darwin[0] > '9')
103 return true;
104
105 Maj = Darwin[0]-'0';
106 ++Darwin;
107
108 // Handle "darwin11".
109 if (Maj == 1 && Darwin[0] >= '0' && Darwin[0] <= '9') {
110 Maj = 10+Darwin[0]-'0';
111 ++Darwin;
112 }
113
114 // Handle minor version: 10.4.9 -> darwin8.9 -> "1049"
115 if (Darwin[0] == '.' && Darwin[1] >= '0' && Darwin[1] <= '9' &&
116 Darwin[2] == '\0')
117 Min = Darwin[1]-'0';
118
119 return true;
120}
121
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000122static void getDarwinDefines(std::vector<char> &Defs, const char *Triple) {
Eli Friedman872996c2008-08-20 02:34:37 +0000123 Define(Defs, "__APPLE__");
124 Define(Defs, "__MACH__");
Chris Lattner8405e092009-02-05 07:19:24 +0000125 Define(Defs, "OBJC_NEW_PROPERTIES");
126
127 // FIXME: OBJC_ZEROCOST_EXCEPTIONS when using zero cost eh.
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000128
129 // Figure out which "darwin number" the target triple is. "darwin9" -> 10.5.
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000130 unsigned Maj, Min;
131 if (getDarwinNumber(Triple, Maj, Min)) {
Chris Lattnerd376f6d2008-09-30 20:30:12 +0000132 char DarwinStr[] = "1000";
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000133 if (Maj >= 4 && Maj <= 13) { // 10.0-10.9
134 // darwin7 -> 1030, darwin8 -> 1040, darwin9 -> 1050, etc.
135 DarwinStr[2] = '0' + Maj-4;
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000136 }
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000137
138 // Handle minor version: 10.4.9 -> darwin8.9 -> "1049"
139 DarwinStr[3] = Min+'0';
Chris Lattnerd376f6d2008-09-30 20:30:12 +0000140 Define(Defs, "__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", DarwinStr);
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000141 }
Eli Friedman872996c2008-08-20 02:34:37 +0000142}
Chris Lattner4b009652007-07-25 00:24:17 +0000143
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000144/// GetDarwinLanguageOptions - Set the default language options for darwin.
145static void GetDarwinLanguageOptions(LangOptions &Opts,
146 const char *Triple) {
147 Opts.NeXTRuntime = true;
148
149 unsigned Maj, Min;
150 if (!getDarwinNumber(Triple, Maj, Min))
151 return;
152
153 // Blocks default to on for 10.6 (darwin10) and beyond.
Fariborz Jahaniand09b9f72009-02-12 17:54:33 +0000154 // As does nonfragile-abi for 64bit mode
Fariborz Jahanian27f58962009-02-24 23:34:44 +0000155 if (Maj > 9)
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000156 Opts.Blocks = 1;
Fariborz Jahanian27f58962009-02-24 23:34:44 +0000157
Fariborz Jahanian72efecb2009-02-24 23:38:42 +0000158 if (Maj >= 9 && Opts.ObjC1 && !strncmp(Triple, "x86_64", 6))
159 Opts.ObjCNonFragileABI = 1;
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000160}
161
162
Chris Lattnerbd00eb82008-10-05 21:50:58 +0000163//===----------------------------------------------------------------------===//
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000164// Specific target implementations.
165//===----------------------------------------------------------------------===//
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000166
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000167namespace {
168// PPC abstract base class
169class PPCTargetInfo : public TargetInfo {
170 static const Builtin::Info BuiltinInfo[];
171 static const char * const GCCRegNames[];
172 static const TargetInfo::GCCRegAlias GCCRegAliases[];
173
174public:
175 PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {
176 CharIsSigned = false;
177 }
178 virtual void getTargetBuiltins(const Builtin::Info *&Records,
179 unsigned &NumRecords) const {
Chris Lattner4b009652007-07-25 00:24:17 +0000180 Records = BuiltinInfo;
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000181 NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner4b009652007-07-25 00:24:17 +0000182 }
Chris Lattnerbef1d722009-03-02 22:27:17 +0000183
Chris Lattner79682402009-03-20 15:52:06 +0000184 virtual void getTargetDefines(const LangOptions &Opts,
185 std::vector<char> &Defines) const;
Chris Lattnerbef1d722009-03-02 22:27:17 +0000186
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000187 virtual const char *getVAListDeclaration() const {
Chris Lattnera07708f2008-10-27 01:11:29 +0000188 return "typedef char* __builtin_va_list;";
189 // This is the right definition for ABI/V4: System V.4/eabi.
190 /*return "typedef struct __va_list_tag {"
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000191 " unsigned char gpr;"
192 " unsigned char fpr;"
193 " unsigned short reserved;"
194 " void* overflow_arg_area;"
195 " void* reg_save_area;"
Chris Lattnera07708f2008-10-27 01:11:29 +0000196 "} __builtin_va_list[1];";*/
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000197 }
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000198 virtual const char *getTargetPrefix() const {
199 return "ppc";
Anders Carlsson4ce42302007-11-27 04:11:28 +0000200 }
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000201 virtual void getGCCRegNames(const char * const *&Names,
202 unsigned &NumNames) const;
203 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
204 unsigned &NumAliases) const;
Anders Carlsson36834a72009-02-28 17:11:49 +0000205 virtual bool validateAsmConstraint(const char *&Name,
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000206 TargetInfo::ConstraintInfo &info) const {
Anders Carlsson36834a72009-02-28 17:11:49 +0000207 switch (*Name) {
Anders Carlsson4ce42302007-11-27 04:11:28 +0000208 default: return false;
209 case 'O': // Zero
210 return true;
211 case 'b': // Base register
212 case 'f': // Floating point register
213 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
214 return true;
215 }
216 }
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000217 virtual const char *getClobbers() const {
218 return "";
Anders Carlsson4ce42302007-11-27 04:11:28 +0000219 }
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000220};
Anders Carlsson4ce42302007-11-27 04:11:28 +0000221
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000222const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
Douglas Gregor2e8a7aa2009-02-16 21:58:21 +0000223#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
224#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000225#include "clang/AST/PPCBuiltins.def"
226};
Chris Lattnerbef1d722009-03-02 22:27:17 +0000227
228
229/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
230/// #defines that are not tied to a specific subtarget.
Chris Lattner79682402009-03-20 15:52:06 +0000231void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
232 std::vector<char> &Defs) const {
Chris Lattnerbef1d722009-03-02 22:27:17 +0000233 // Target identification.
234 Define(Defs, "__ppc__");
235 Define(Defs, "_ARCH_PPC");
236 Define(Defs, "__POWERPC__");
237 if (PointerWidth == 64) {
238 Define(Defs, "_ARCH_PPC64");
239 Define(Defs, "_LP64");
240 Define(Defs, "__LP64__");
241 Define(Defs, "__ppc64__");
242 } else {
243 Define(Defs, "__ppc__");
244 }
245
246 // Target properties.
247 Define(Defs, "_BIG_ENDIAN");
248 Define(Defs, "__BIG_ENDIAN__");
249
250 // Subtarget options.
251 Define(Defs, "__NATURAL_ALIGNMENT__");
252 Define(Defs, "__REGISTER_PREFIX__", "");
253
254 // FIXME: Should be controlled by command line option.
255 Define(Defs, "__LONG_DOUBLE_128__");
256}
257
Chris Lattner9fd73612008-04-21 18:56:49 +0000258
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000259const char * const PPCTargetInfo::GCCRegNames[] = {
260 "0", "1", "2", "3", "4", "5", "6", "7",
261 "8", "9", "10", "11", "12", "13", "14", "15",
262 "16", "17", "18", "19", "20", "21", "22", "23",
263 "24", "25", "26", "27", "28", "29", "30", "31",
264 "0", "1", "2", "3", "4", "5", "6", "7",
265 "8", "9", "10", "11", "12", "13", "14", "15",
266 "16", "17", "18", "19", "20", "21", "22", "23",
267 "24", "25", "26", "27", "28", "29", "30", "31",
268 "mq", "lr", "ctr", "ap",
269 "0", "1", "2", "3", "4", "5", "6", "7",
270 "xer",
271 "0", "1", "2", "3", "4", "5", "6", "7",
272 "8", "9", "10", "11", "12", "13", "14", "15",
273 "16", "17", "18", "19", "20", "21", "22", "23",
274 "24", "25", "26", "27", "28", "29", "30", "31",
275 "vrsave", "vscr",
276 "spe_acc", "spefscr",
277 "sfp"
278};
Chris Lattner4b009652007-07-25 00:24:17 +0000279
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000280void PPCTargetInfo::getGCCRegNames(const char * const *&Names,
281 unsigned &NumNames) const {
282 Names = GCCRegNames;
283 NumNames = llvm::array_lengthof(GCCRegNames);
284}
Chris Lattner4b009652007-07-25 00:24:17 +0000285
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000286const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
287 // While some of these aliases do map to different registers
288 // they still share the same register name.
289 { { "cc", "cr0", "fr0", "r0", "v0"}, "0" },
290 { { "cr1", "fr1", "r1", "sp", "v1"}, "1" },
291 { { "cr2", "fr2", "r2", "toc", "v2"}, "2" },
292 { { "cr3", "fr3", "r3", "v3"}, "3" },
293 { { "cr4", "fr4", "r4", "v4"}, "4" },
294 { { "cr5", "fr5", "r5", "v5"}, "5" },
295 { { "cr6", "fr6", "r6", "v6"}, "6" },
296 { { "cr7", "fr7", "r7", "v7"}, "7" },
297 { { "fr8", "r8", "v8"}, "8" },
298 { { "fr9", "r9", "v9"}, "9" },
299 { { "fr10", "r10", "v10"}, "10" },
300 { { "fr11", "r11", "v11"}, "11" },
301 { { "fr12", "r12", "v12"}, "12" },
302 { { "fr13", "r13", "v13"}, "13" },
303 { { "fr14", "r14", "v14"}, "14" },
304 { { "fr15", "r15", "v15"}, "15" },
305 { { "fr16", "r16", "v16"}, "16" },
306 { { "fr17", "r17", "v17"}, "17" },
307 { { "fr18", "r18", "v18"}, "18" },
308 { { "fr19", "r19", "v19"}, "19" },
309 { { "fr20", "r20", "v20"}, "20" },
310 { { "fr21", "r21", "v21"}, "21" },
311 { { "fr22", "r22", "v22"}, "22" },
312 { { "fr23", "r23", "v23"}, "23" },
313 { { "fr24", "r24", "v24"}, "24" },
314 { { "fr25", "r25", "v25"}, "25" },
315 { { "fr26", "r26", "v26"}, "26" },
316 { { "fr27", "r27", "v27"}, "27" },
317 { { "fr28", "r28", "v28"}, "28" },
318 { { "fr29", "r29", "v29"}, "29" },
319 { { "fr30", "r30", "v30"}, "30" },
320 { { "fr31", "r31", "v31"}, "31" },
321};
322
323void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
324 unsigned &NumAliases) const {
325 Aliases = GCCRegAliases;
326 NumAliases = llvm::array_lengthof(GCCRegAliases);
327}
328} // end anonymous namespace.
Chris Lattner4b009652007-07-25 00:24:17 +0000329
330namespace {
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000331class PPC32TargetInfo : public PPCTargetInfo {
Chris Lattner4b009652007-07-25 00:24:17 +0000332public:
Eli Friedman2b161652008-08-21 00:13:15 +0000333 PPC32TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
334 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
335 "i64:64:64-f32:32:32-f64:64:64-v128:128:128";
336 }
Chris Lattner4b009652007-07-25 00:24:17 +0000337};
338} // end anonymous namespace.
339
340namespace {
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000341class PPC64TargetInfo : public PPCTargetInfo {
Chris Lattner4b009652007-07-25 00:24:17 +0000342public:
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000343 PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
Chris Lattnere5fde952008-05-09 06:17:04 +0000344 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedman2b161652008-08-21 00:13:15 +0000345 DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
346 "i64:64:64-f32:32:32-f64:64:64-v128:128:128";
Chris Lattnere5fde952008-05-09 06:17:04 +0000347 }
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000348};
349} // end anonymous namespace.
350
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000351
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000352namespace {
353class DarwinPPCTargetInfo : public PPC32TargetInfo {
354public:
355 DarwinPPCTargetInfo(const std::string& triple) : PPC32TargetInfo(triple) {}
Chris Lattner79682402009-03-20 15:52:06 +0000356 virtual void getTargetDefines(const LangOptions &Opts,
357 std::vector<char> &Defines) const {
358 PPC32TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000359 getDarwinDefines(Defines, getTargetTriple());
Chris Lattner4b009652007-07-25 00:24:17 +0000360 }
Daniel Dunbar34542952008-08-23 08:43:39 +0000361
Chris Lattnerddae7102008-12-04 22:54:33 +0000362 /// getDefaultLangOptions - Allow the target to specify default settings for
363 /// various language options. These may be overridden by command line
364 /// options.
365 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000366 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattnerddae7102008-12-04 22:54:33 +0000367 }
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000368};
369} // end anonymous namespace.
370
371namespace {
372class DarwinPPC64TargetInfo : public PPC64TargetInfo {
373public:
374 DarwinPPC64TargetInfo(const std::string& triple) : PPC64TargetInfo(triple) {}
Chris Lattner79682402009-03-20 15:52:06 +0000375 virtual void getTargetDefines(const LangOptions &Opts,
376 std::vector<char> &Defines) const {
377 PPC64TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000378 getDarwinDefines(Defines, getTargetTriple());
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000379 }
Daniel Dunbar34542952008-08-23 08:43:39 +0000380
Chris Lattnerddae7102008-12-04 22:54:33 +0000381 /// getDefaultLangOptions - Allow the target to specify default settings for
382 /// various language options. These may be overridden by command line
383 /// options.
384 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000385 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattnerddae7102008-12-04 22:54:33 +0000386 }
Chris Lattner4b009652007-07-25 00:24:17 +0000387};
388} // end anonymous namespace.
389
390namespace {
Eli Friedman872996c2008-08-20 02:34:37 +0000391// Namespace for x86 abstract base class
392const Builtin::Info BuiltinInfo[] = {
Douglas Gregor2e8a7aa2009-02-16 21:58:21 +0000393#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
394#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
Eli Friedman872996c2008-08-20 02:34:37 +0000395#include "clang/AST/X86Builtins.def"
396};
Eli Friedman0b7b1cb2008-05-20 14:21:01 +0000397
Eli Friedman872996c2008-08-20 02:34:37 +0000398const char *GCCRegNames[] = {
399 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
400 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
401 "argp", "flags", "fspr", "dirflag", "frame",
402 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
403 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
404 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
405 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
406};
407
408const TargetInfo::GCCRegAlias GCCRegAliases[] = {
409 { { "al", "ah", "eax", "rax" }, "ax" },
410 { { "bl", "bh", "ebx", "rbx" }, "bx" },
411 { { "cl", "ch", "ecx", "rcx" }, "cx" },
412 { { "dl", "dh", "edx", "rdx" }, "dx" },
413 { { "esi", "rsi" }, "si" },
414 { { "edi", "rdi" }, "di" },
415 { { "esp", "rsp" }, "sp" },
416 { { "ebp", "rbp" }, "bp" },
417};
418
419// X86 target abstract base class; x86-32 and x86-64 are very close, so
420// most of the implementation can be shared.
421class X86TargetInfo : public TargetInfo {
Chris Lattner715fe4c2009-03-02 22:40:39 +0000422 enum X86SSEEnum {
423 NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42
424 } SSELevel;
Eli Friedman872996c2008-08-20 02:34:37 +0000425public:
Chris Lattner715fe4c2009-03-02 22:40:39 +0000426 X86TargetInfo(const std::string& triple)
Chris Lattnerf6790a82009-03-03 19:56:18 +0000427 : TargetInfo(triple),
428 // FIXME: hard coding to SSE2 for now. This should change to NoMMXSSE so
429 // that the driver controls this.
430 SSELevel(SSE2) {
Eli Friedman872996c2008-08-20 02:34:37 +0000431 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
Chris Lattner4b009652007-07-25 00:24:17 +0000432 }
433 virtual void getTargetBuiltins(const Builtin::Info *&Records,
434 unsigned &NumRecords) const {
Eli Friedman872996c2008-08-20 02:34:37 +0000435 Records = BuiltinInfo;
436 NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner4b009652007-07-25 00:24:17 +0000437 }
Anders Carlsson333052c2007-12-08 19:32:57 +0000438 virtual const char *getTargetPrefix() const {
Eli Friedman872996c2008-08-20 02:34:37 +0000439 return "x86";
Anders Carlsson333052c2007-12-08 19:32:57 +0000440 }
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000441 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedman872996c2008-08-20 02:34:37 +0000442 unsigned &NumNames) const {
443 Names = GCCRegNames;
444 NumNames = llvm::array_lengthof(GCCRegNames);
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000445 }
446 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
447 unsigned &NumAliases) const {
Eli Friedman872996c2008-08-20 02:34:37 +0000448 Aliases = GCCRegAliases;
449 NumAliases = llvm::array_lengthof(GCCRegAliases);
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000450 }
Anders Carlsson36834a72009-02-28 17:11:49 +0000451 virtual bool validateAsmConstraint(const char *&Name,
Eli Friedman872996c2008-08-20 02:34:37 +0000452 TargetInfo::ConstraintInfo &info) const;
453 virtual std::string convertConstraint(const char Constraint) const;
Anders Carlsson4ce42302007-11-27 04:11:28 +0000454 virtual const char *getClobbers() const {
Eli Friedman872996c2008-08-20 02:34:37 +0000455 return "~{dirflag},~{fpsr},~{flags}";
456 }
Chris Lattner79682402009-03-20 15:52:06 +0000457 virtual void getTargetDefines(const LangOptions &Opts,
458 std::vector<char> &Defines) const;
Chris Lattner7d6220c2009-03-02 22:20:04 +0000459
Chris Lattnerf6790a82009-03-03 19:56:18 +0000460 virtual int HandleTargetFeatures(std::string *StrArray, unsigned NumStrs,
461 std::string &ErrorReason);
Chris Lattner4b009652007-07-25 00:24:17 +0000462};
Chris Lattner7d6220c2009-03-02 22:20:04 +0000463
464/// HandleTargetOptions - Handle target-specific options like -msse2 and
465/// friends. An array of arguments is passed in: if they are all valid, this
466/// should handle them and return -1. If there is an error, the index of the
467/// invalid argument should be returned along with an optional error string.
Chris Lattnerf6790a82009-03-03 19:56:18 +0000468int X86TargetInfo::HandleTargetFeatures(std::string *StrArray, unsigned NumStrs,
469 std::string &ErrorReason) {
470 for (unsigned i = 0; i != NumStrs; ++i) {
471 const std::string &Feature = StrArray[i];
472 if (Feature.size() < 2) return i;
473 // Ignore explicitly disabled features.
474 if (Feature[0] == '-') continue;
475
476 // Feature strings are of the form "+feature".
477 if (Feature[0] != '+') return i;
478
479 // The set of supported subtarget features is defined in
480 // lib/Target/X86/X86.td. Here we recognize and map onto our internal
481 // state.
482 if (Feature == "+mmx")
483 SSELevel = std::max(SSELevel, MMX);
484 else if (Feature == "+sse")
485 SSELevel = std::max(SSELevel, SSE1);
486 else if (Feature == "+sse2")
487 SSELevel = std::max(SSELevel, SSE2);
488 else if (Feature == "+sse3")
489 SSELevel = std::max(SSELevel, SSE3);
490 else if (Feature == "+ssse3")
491 SSELevel = std::max(SSELevel, SSSE3);
492 else if (Feature == "+sse41")
493 SSELevel = std::max(SSELevel, SSE41);
494 else if (Feature == "+sse42")
495 SSELevel = std::max(SSELevel, SSE42);
496 else if (Feature == "+64bit" || Feature == "+slow-bt-mem")
497 // Ignore these features.
498 continue;
499 else
500 return i;
501 }
502 return -1;
Chris Lattner7d6220c2009-03-02 22:20:04 +0000503}
Chris Lattnerbef1d722009-03-02 22:27:17 +0000504
505/// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines
506/// that are not tied to a specific subtarget.
Chris Lattner79682402009-03-20 15:52:06 +0000507void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
508 std::vector<char> &Defs) const {
Chris Lattnerbef1d722009-03-02 22:27:17 +0000509 // Target identification.
510 if (PointerWidth == 64) {
511 Define(Defs, "_LP64");
512 Define(Defs, "__LP64__");
513 Define(Defs, "__amd64__");
514 Define(Defs, "__amd64");
515 Define(Defs, "__x86_64");
516 Define(Defs, "__x86_64__");
517 Define(Defs, "__SSE3__");
518 } else {
519 Define(Defs, "__i386__");
520 Define(Defs, "__i386");
521 Define(Defs, "i386");
522 }
523
524 // Target properties.
525 Define(Defs, "__LITTLE_ENDIAN__");
526
527 // Subtarget options.
528 Define(Defs, "__nocona");
529 Define(Defs, "__nocona__");
530 Define(Defs, "__tune_nocona__");
Chris Lattnerbef1d722009-03-02 22:27:17 +0000531 Define(Defs, "__REGISTER_PREFIX__", "");
Chris Lattner715fe4c2009-03-02 22:40:39 +0000532
533 // Each case falls through to the previous one here.
534 switch (SSELevel) {
535 case SSE42:
536 Define(Defs, "__SSE4_2__");
537 case SSE41:
538 Define(Defs, "__SSE4_1__");
539 case SSSE3:
540 Define(Defs, "__SSSE3__");
541 case SSE3:
542 Define(Defs, "__SSE3__");
543 case SSE2:
544 Define(Defs, "__SSE2__");
545 Define(Defs, "__SSE2_MATH__"); // -mfp-math=sse always implied.
546 case SSE1:
547 Define(Defs, "__SSE__");
548 Define(Defs, "__SSE_MATH__"); // -mfp-math=sse always implied.
549 case MMX:
550 Define(Defs, "__MMX__");
551 case NoMMXSSE:
552 break;
553 }
Chris Lattnerbef1d722009-03-02 22:27:17 +0000554}
555
Eli Friedman872996c2008-08-20 02:34:37 +0000556
557bool
Anders Carlsson36834a72009-02-28 17:11:49 +0000558X86TargetInfo::validateAsmConstraint(const char *&Name,
Eli Friedman872996c2008-08-20 02:34:37 +0000559 TargetInfo::ConstraintInfo &info) const {
Anders Carlsson36834a72009-02-28 17:11:49 +0000560 switch (*Name) {
Eli Friedman872996c2008-08-20 02:34:37 +0000561 default: return false;
562 case 'a': // eax.
563 case 'b': // ebx.
564 case 'c': // ecx.
565 case 'd': // edx.
566 case 'S': // esi.
567 case 'D': // edi.
568 case 'A': // edx:eax.
569 case 't': // top of floating point stack.
570 case 'u': // second from top of floating point stack.
571 case 'q': // Any register accessible as [r]l: a, b, c, and d.
Anders Carlsson2285e622008-10-06 00:41:45 +0000572 case 'y': // Any MMX register.
Anders Carlssond2459f92008-10-06 19:17:39 +0000573 case 'x': // Any SSE register.
Eli Friedman872996c2008-08-20 02:34:37 +0000574 case 'Q': // Any register accessible as [r]h: a, b, c, and d.
Anders Carlssonff235da2009-01-24 18:03:09 +0000575 case 'e': // 32-bit signed integer constant for use with zero-extending
576 // x86_64 instructions.
577 case 'Z': // 32-bit unsigned integer constant for use with zero-extending
578 // x86_64 instructions.
Eli Friedman872996c2008-08-20 02:34:37 +0000579 case 'N': // unsigned 8-bit integer constant for use with in and out
580 // instructions.
581 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
582 return true;
583 }
584}
585
586std::string
587X86TargetInfo::convertConstraint(const char Constraint) const {
588 switch (Constraint) {
589 case 'a': return std::string("{ax}");
590 case 'b': return std::string("{bx}");
591 case 'c': return std::string("{cx}");
592 case 'd': return std::string("{dx}");
593 case 'S': return std::string("{si}");
594 case 'D': return std::string("{di}");
595 case 't': // top of floating point stack.
596 return std::string("{st}");
597 case 'u': // second from top of floating point stack.
598 return std::string("{st(1)}"); // second from top of floating point stack.
599 default:
600 return std::string(1, Constraint);
601 }
602}
Eli Friedman872996c2008-08-20 02:34:37 +0000603} // end anonymous namespace
Chris Lattner4b009652007-07-25 00:24:17 +0000604
605namespace {
Eli Friedman872996c2008-08-20 02:34:37 +0000606// X86-32 generic target
607class X86_32TargetInfo : public X86TargetInfo {
Chris Lattner4b009652007-07-25 00:24:17 +0000608public:
Eli Friedman872996c2008-08-20 02:34:37 +0000609 X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
610 DoubleAlign = LongLongAlign = 32;
611 LongDoubleWidth = 96;
612 LongDoubleAlign = 32;
Eli Friedman2b161652008-08-21 00:13:15 +0000613 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
614 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
615 "a0:0:64-f80:32:32";
Eli Friedman872996c2008-08-20 02:34:37 +0000616 }
617 virtual const char *getVAListDeclaration() const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000618 return "typedef char* __builtin_va_list;";
Eli Friedman872996c2008-08-20 02:34:37 +0000619 }
Eli Friedman872996c2008-08-20 02:34:37 +0000620};
621} // end anonymous namespace
622
623namespace {
624// x86-32 Darwin (OS X) target
625class DarwinI386TargetInfo : public X86_32TargetInfo {
626public:
627 DarwinI386TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
628 LongDoubleWidth = 128;
629 LongDoubleAlign = 128;
Chris Lattner8405e092009-02-05 07:19:24 +0000630 PtrDiffType = SignedInt;
Eli Friedman2b161652008-08-21 00:13:15 +0000631 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
632 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
633 "a0:0:64-f80:128:128";
Eli Friedman872996c2008-08-20 02:34:37 +0000634 }
Chris Lattner79682402009-03-20 15:52:06 +0000635 virtual void getTargetDefines(const LangOptions &Opts,
636 std::vector<char> &Defines) const {
637 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000638 getDarwinDefines(Defines, getTargetTriple());
Eli Friedman872996c2008-08-20 02:34:37 +0000639 }
Chris Lattnerddae7102008-12-04 22:54:33 +0000640 /// getDefaultLangOptions - Allow the target to specify default settings for
641 /// various language options. These may be overridden by command line
642 /// options.
643 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000644 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattnerddae7102008-12-04 22:54:33 +0000645 }
Eli Friedman872996c2008-08-20 02:34:37 +0000646};
647} // end anonymous namespace
648
649namespace {
Chris Lattner98cb2a22008-10-16 17:04:31 +0000650// x86-32 FreeBSD target
651class FreeBSDX86_32TargetInfo : public X86_32TargetInfo {
652public:
Eli Friedman7cca0982008-11-02 02:43:55 +0000653 FreeBSDX86_32TargetInfo(const std::string& triple) :
654 X86_32TargetInfo(triple) {
655 SizeType = UnsignedInt;
656 PtrDiffType = SignedInt;
Chris Lattner98cb2a22008-10-16 17:04:31 +0000657 }
Chris Lattner79682402009-03-20 15:52:06 +0000658 virtual void getTargetDefines(const LangOptions &Opts,
659 std::vector<char> &Defines) const {
660 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattner98cb2a22008-10-16 17:04:31 +0000661 getFreeBSDDefines(Defines, 0, getTargetTriple());
662 }
663};
664} // end anonymous namespace
665
666namespace {
Chris Lattnerd4faca42008-08-23 18:23:14 +0000667// x86-32 DragonFly target
668class DragonFlyX86_32TargetInfo : public X86_32TargetInfo {
669public:
Eli Friedman7cca0982008-11-02 02:43:55 +0000670 DragonFlyX86_32TargetInfo(const std::string& triple) :
671 X86_32TargetInfo(triple) {
672 SizeType = UnsignedInt;
673 PtrDiffType = SignedInt;
Chris Lattnerd4faca42008-08-23 18:23:14 +0000674 }
Chris Lattner79682402009-03-20 15:52:06 +0000675 virtual void getTargetDefines(const LangOptions &Opts,
676 std::vector<char> &Defines) const {
677 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerd4faca42008-08-23 18:23:14 +0000678 getDragonFlyDefines(Defines);
679 }
680};
681} // end anonymous namespace
682
683namespace {
Eli Friedman5fb0a022008-08-21 00:24:02 +0000684// x86-32 Linux target
685class LinuxX86_32TargetInfo : public X86_32TargetInfo {
686public:
687 LinuxX86_32TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
Chris Lattner5edfe012008-10-05 19:44:25 +0000688 UserLabelPrefix = "";
Eli Friedman7cca0982008-11-02 02:43:55 +0000689 SizeType = UnsignedInt;
690 PtrDiffType = SignedInt;
Chris Lattnerd9ef7242009-02-13 22:28:55 +0000691 IntPtrType = SignedInt;
Eli Friedman5fb0a022008-08-21 00:24:02 +0000692 }
Chris Lattner79682402009-03-20 15:52:06 +0000693 virtual void getTargetDefines(const LangOptions &Opts,
694 std::vector<char> &Defines) const {
695 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Eli Friedman5fb0a022008-08-21 00:24:02 +0000696 getLinuxDefines(Defines);
697 }
698};
699} // end anonymous namespace
700
701namespace {
Eli Friedman23cb7912008-08-21 01:40:19 +0000702// x86-32 Windows target
703class WindowsX86_32TargetInfo : public X86_32TargetInfo {
704public:
705 WindowsX86_32TargetInfo(const std::string& triple)
706 : X86_32TargetInfo(triple) {
707 // FIXME: Fix wchar_t.
708 // FIXME: We should probably enable -fms-extensions by default for
709 // this target.
Eli Friedman7cca0982008-11-02 02:43:55 +0000710 SizeType = UnsignedInt;
711 PtrDiffType = SignedInt;
Eli Friedman23cb7912008-08-21 01:40:19 +0000712 }
Chris Lattner79682402009-03-20 15:52:06 +0000713 virtual void getTargetDefines(const LangOptions &Opts,
714 std::vector<char> &Defines) const {
715 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Eli Friedman23cb7912008-08-21 01:40:19 +0000716 // This list is based off of the the list of things MingW defines
717 Define(Defines, "__WIN32__");
718 Define(Defines, "__WIN32");
719 Define(Defines, "_WIN32");
720 Define(Defines, "WIN32");
721 Define(Defines, "__WINNT__");
722 Define(Defines, "__WINNT");
723 Define(Defines, "WINNT");
Eli Friedman23cb7912008-08-21 01:40:19 +0000724 Define(Defines, "_X86_");
725 Define(Defines, "__MSVCRT__");
726 }
727};
728} // end anonymous namespace
729
730namespace {
Eli Friedman872996c2008-08-20 02:34:37 +0000731// x86-64 generic target
732class X86_64TargetInfo : public X86TargetInfo {
733public:
Chris Lattner79682402009-03-20 15:52:06 +0000734 X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) {
Chris Lattnere5fde952008-05-09 06:17:04 +0000735 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Chris Lattner4dfc45a2009-01-28 06:58:19 +0000736 DoubleAlign = LongLongAlign = 64;
Eli Friedman0b7b1cb2008-05-20 14:21:01 +0000737 LongDoubleWidth = 128;
738 LongDoubleAlign = 128;
Chris Lattnerbfbfbaf2009-02-05 07:32:46 +0000739 IntMaxType = SignedLong;
740 UIntMaxType = UnsignedLong;
741
Eli Friedman2b161652008-08-21 00:13:15 +0000742 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
743 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
744 "a0:0:64-f80:128:128";
Chris Lattner4b009652007-07-25 00:24:17 +0000745 }
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000746 virtual const char *getVAListDeclaration() const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000747 return "typedef struct __va_list_tag {"
748 " unsigned gp_offset;"
749 " unsigned fp_offset;"
750 " void* overflow_arg_area;"
751 " void* reg_save_area;"
752 "} __builtin_va_list[1];";
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000753 }
Eli Friedman872996c2008-08-20 02:34:37 +0000754};
755} // end anonymous namespace
756
757namespace {
Chris Lattner98cb2a22008-10-16 17:04:31 +0000758// x86-64 FreeBSD target
759class FreeBSDX86_64TargetInfo : public X86_64TargetInfo {
760public:
Chris Lattner79682402009-03-20 15:52:06 +0000761 FreeBSDX86_64TargetInfo(const std::string &triple)
762 : X86_64TargetInfo(triple) {}
763 virtual void getTargetDefines(const LangOptions &Opts,
764 std::vector<char> &Defines) const {
765 X86_64TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattner98cb2a22008-10-16 17:04:31 +0000766 getFreeBSDDefines(Defines, 1, getTargetTriple());
767 }
768};
769} // end anonymous namespace
770
771namespace {
Daniel Dunbare5a80f22008-09-23 17:37:57 +0000772// x86-64 Linux target
773class LinuxX86_64TargetInfo : public X86_64TargetInfo {
774public:
775 LinuxX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) {
Chris Lattner5edfe012008-10-05 19:44:25 +0000776 UserLabelPrefix = "";
Daniel Dunbare5a80f22008-09-23 17:37:57 +0000777 }
Chris Lattner79682402009-03-20 15:52:06 +0000778 virtual void getTargetDefines(const LangOptions &Opts,
779 std::vector<char> &Defines) const {
780 X86_64TargetInfo::getTargetDefines(Opts, Defines);
Daniel Dunbare5a80f22008-09-23 17:37:57 +0000781 getLinuxDefines(Defines);
Daniel Dunbare5a80f22008-09-23 17:37:57 +0000782 }
783};
784} // end anonymous namespace
785
786namespace {
Eli Friedman872996c2008-08-20 02:34:37 +0000787// x86-64 Darwin (OS X) target
788class DarwinX86_64TargetInfo : public X86_64TargetInfo {
789public:
790 DarwinX86_64TargetInfo(const std::string& triple) :
791 X86_64TargetInfo(triple) {}
792
Chris Lattner79682402009-03-20 15:52:06 +0000793 virtual void getTargetDefines(const LangOptions &Opts,
794 std::vector<char> &Defines) const {
795 X86_64TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000796 getDarwinDefines(Defines, getTargetTriple());
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000797 }
Daniel Dunbar34542952008-08-23 08:43:39 +0000798
Chris Lattnerddae7102008-12-04 22:54:33 +0000799 /// getDefaultLangOptions - Allow the target to specify default settings for
800 /// various language options. These may be overridden by command line
801 /// options.
802 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000803 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattnerddae7102008-12-04 22:54:33 +0000804 }
Chris Lattner4b009652007-07-25 00:24:17 +0000805};
806} // end anonymous namespace.
807
Chris Lattner9fd73612008-04-21 18:56:49 +0000808namespace {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000809class ARMTargetInfo : public TargetInfo {
Chris Lattner9fd73612008-04-21 18:56:49 +0000810public:
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000811 ARMTargetInfo(const std::string& triple) : TargetInfo(triple) {
812 // FIXME: Are the defaults correct for ARM?
Eli Friedman2b161652008-08-21 00:13:15 +0000813 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
814 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:64";
Eli Friedman0b7b1cb2008-05-20 14:21:01 +0000815 }
Chris Lattner79682402009-03-20 15:52:06 +0000816 virtual void getTargetDefines(const LangOptions &Opts,
817 std::vector<char> &Defs) const {
Chris Lattnerbef1d722009-03-02 22:27:17 +0000818 // Target identification.
819 Define(Defs, "__arm");
820 Define(Defs, "__arm__");
821
822 // Target properties.
823 Define(Defs, "__LITTLE_ENDIAN__");
824
825 // Subtarget options. [hard coded to v6 for now]
826 Define(Defs, "__ARM_ARCH_6K__");
827 Define(Defs, "__ARMEL__");
828 Define(Defs, "__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", "20000");
Chris Lattner9fd73612008-04-21 18:56:49 +0000829 }
830 virtual void getTargetBuiltins(const Builtin::Info *&Records,
831 unsigned &NumRecords) const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000832 // FIXME: Implement.
833 Records = 0;
Chris Lattner9fd73612008-04-21 18:56:49 +0000834 NumRecords = 0;
835 }
836 virtual const char *getVAListDeclaration() const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000837 return "typedef char* __builtin_va_list;";
Chris Lattner9fd73612008-04-21 18:56:49 +0000838 }
839 virtual const char *getTargetPrefix() const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000840 return "arm";
Chris Lattner9fd73612008-04-21 18:56:49 +0000841 }
Chris Lattner9fd73612008-04-21 18:56:49 +0000842 virtual void getGCCRegNames(const char * const *&Names,
843 unsigned &NumNames) const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000844 // FIXME: Implement.
845 Names = 0;
Chris Lattner9fd73612008-04-21 18:56:49 +0000846 NumNames = 0;
847 }
848 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
849 unsigned &NumAliases) const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000850 // FIXME: Implement.
851 Aliases = 0;
Chris Lattner9fd73612008-04-21 18:56:49 +0000852 NumAliases = 0;
853 }
Anders Carlsson36834a72009-02-28 17:11:49 +0000854 virtual bool validateAsmConstraint(const char *&Name,
Nate Begeman222823a2008-04-22 05:03:19 +0000855 TargetInfo::ConstraintInfo &info) const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000856 // FIXME: Check if this is complete
Anders Carlsson36834a72009-02-28 17:11:49 +0000857 switch (*Name) {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000858 default:
Nate Begeman222823a2008-04-22 05:03:19 +0000859 case 'l': // r0-r7
860 case 'h': // r8-r15
861 case 'w': // VFP Floating point register single precision
862 case 'P': // VFP Floating point register double precision
863 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
864 return true;
865 }
Chris Lattner9fd73612008-04-21 18:56:49 +0000866 return false;
867 }
868 virtual const char *getClobbers() const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000869 // FIXME: Is this really right?
Chris Lattner9fd73612008-04-21 18:56:49 +0000870 return "";
871 }
872};
873} // end anonymous namespace.
874
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000875
876namespace {
877class DarwinARMTargetInfo : public ARMTargetInfo {
878public:
879 DarwinARMTargetInfo(const std::string& triple) : ARMTargetInfo(triple) {}
880
Chris Lattner79682402009-03-20 15:52:06 +0000881 virtual void getTargetDefines(const LangOptions &Opts,
882 std::vector<char> &Defines) const {
883 ARMTargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000884 getDarwinDefines(Defines, getTargetTriple());
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000885 }
886};
887} // end anonymous namespace.
888
Chris Lattner4b009652007-07-25 00:24:17 +0000889namespace {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000890class SparcV8TargetInfo : public TargetInfo {
Chris Lattnerff7c53d2009-01-27 01:58:38 +0000891 static const TargetInfo::GCCRegAlias GCCRegAliases[];
892 static const char * const GCCRegNames[];
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000893public:
Eli Friedmanff158dd2008-08-20 07:28:14 +0000894 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
895 // FIXME: Support Sparc quad-precision long double?
Eli Friedman2b161652008-08-21 00:13:15 +0000896 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
897 "i64:64:64-f32:32:32-f64:64:64-v64:64:64";
Eli Friedmanff158dd2008-08-20 07:28:14 +0000898 }
Chris Lattner79682402009-03-20 15:52:06 +0000899 virtual void getTargetDefines(const LangOptions &Opts,
900 std::vector<char> &Defines) const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000901 // FIXME: This is missing a lot of important defines; some of the
902 // missing stuff is likely to break system headers.
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000903 Define(Defines, "__sparc");
Eli Friedman1dee5c52008-05-25 05:26:09 +0000904 Define(Defines, "__sparc__");
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000905 Define(Defines, "__sparcv8");
906 }
907 virtual void getTargetBuiltins(const Builtin::Info *&Records,
908 unsigned &NumRecords) const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000909 // FIXME: Implement!
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000910 }
911 virtual const char *getVAListDeclaration() const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000912 return "typedef void* __builtin_va_list;";
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000913 }
914 virtual const char *getTargetPrefix() const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000915 return "sparc";
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000916 }
917 virtual void getGCCRegNames(const char * const *&Names,
Chris Lattnerff7c53d2009-01-27 01:58:38 +0000918 unsigned &NumNames) const;
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000919 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattnerff7c53d2009-01-27 01:58:38 +0000920 unsigned &NumAliases) const;
Anders Carlsson36834a72009-02-28 17:11:49 +0000921 virtual bool validateAsmConstraint(const char *&Name,
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000922 TargetInfo::ConstraintInfo &info) const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000923 // FIXME: Implement!
924 return false;
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000925 }
926 virtual const char *getClobbers() const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000927 // FIXME: Implement!
928 return "";
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000929 }
930};
931
Chris Lattnerff7c53d2009-01-27 01:58:38 +0000932const char * const SparcV8TargetInfo::GCCRegNames[] = {
933 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
934 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
935 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
936 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
937};
938
939void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names,
940 unsigned &NumNames) const {
941 Names = GCCRegNames;
942 NumNames = llvm::array_lengthof(GCCRegNames);
943}
944
945const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = {
946 { { "g0" }, "r0" },
947 { { "g1" }, "r1" },
948 { { "g2" }, "r2" },
949 { { "g3" }, "r3" },
950 { { "g4" }, "r4" },
951 { { "g5" }, "r5" },
952 { { "g6" }, "r6" },
953 { { "g7" }, "r7" },
954 { { "o0" }, "r8" },
955 { { "o1" }, "r9" },
956 { { "o2" }, "r10" },
957 { { "o3" }, "r11" },
958 { { "o4" }, "r12" },
959 { { "o5" }, "r13" },
960 { { "o6", "sp" }, "r14" },
961 { { "o7" }, "r15" },
962 { { "l0" }, "r16" },
963 { { "l1" }, "r17" },
964 { { "l2" }, "r18" },
965 { { "l3" }, "r19" },
966 { { "l4" }, "r20" },
967 { { "l5" }, "r21" },
968 { { "l6" }, "r22" },
969 { { "l7" }, "r23" },
970 { { "i0" }, "r24" },
971 { { "i1" }, "r25" },
972 { { "i2" }, "r26" },
973 { { "i3" }, "r27" },
974 { { "i4" }, "r28" },
975 { { "i5" }, "r29" },
976 { { "i6", "fp" }, "r30" },
977 { { "i7" }, "r31" },
978};
979
980void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
981 unsigned &NumAliases) const {
982 Aliases = GCCRegAliases;
983 NumAliases = llvm::array_lengthof(GCCRegAliases);
984}
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000985} // end anonymous namespace.
986
Eli Friedmanff158dd2008-08-20 07:28:14 +0000987namespace {
988class SolarisSparcV8TargetInfo : public SparcV8TargetInfo {
989public:
990 SolarisSparcV8TargetInfo(const std::string& triple) :
Eli Friedman7cca0982008-11-02 02:43:55 +0000991 SparcV8TargetInfo(triple) {
992 SizeType = UnsignedInt;
993 PtrDiffType = SignedInt;
994 }
Eli Friedmanff158dd2008-08-20 07:28:14 +0000995
Chris Lattner79682402009-03-20 15:52:06 +0000996 virtual void getTargetDefines(const LangOptions &Opts,
997 std::vector<char> &Defines) const {
998 SparcV8TargetInfo::getTargetDefines(Opts, Defines);
Eli Friedmanff158dd2008-08-20 07:28:14 +0000999 getSolarisDefines(Defines);
1000 }
1001};
1002} // end anonymous namespace.
Chris Lattner4b009652007-07-25 00:24:17 +00001003
Chris Lattner85970f32008-05-08 05:58:21 +00001004namespace {
1005 class PIC16TargetInfo : public TargetInfo{
1006 public:
1007 PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) {
Sanjiv Guptafa451432008-10-31 09:52:39 +00001008 IntWidth = 16;
1009 LongWidth = LongLongWidth = 32;
1010 PointerWidth = 16;
1011 IntAlign = 8;
1012 LongAlign = LongLongAlign = 8;
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001013 PointerAlign = 8;
Sanjiv Guptafa451432008-10-31 09:52:39 +00001014 SizeType = UnsignedInt;
1015 IntMaxType = SignedLong;
1016 UIntMaxType = UnsignedLong;
Chris Lattnerd9ef7242009-02-13 22:28:55 +00001017 IntPtrType = SignedShort;
Eli Friedman7cca0982008-11-02 02:43:55 +00001018 PtrDiffType = SignedInt;
Sanjiv Guptaebd8f0f2008-08-18 10:05:22 +00001019 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8";
Chris Lattner85970f32008-05-08 05:58:21 +00001020 }
Chris Lattner727b3c42008-05-09 06:08:39 +00001021 virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; }
1022 virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; }
Chris Lattner79682402009-03-20 15:52:06 +00001023 virtual void getTargetDefines(const LangOptions &Opts,
1024 std::vector<char> &Defines) const {
Chris Lattner85970f32008-05-08 05:58:21 +00001025 Define(Defines, "__pic16");
1026 }
1027 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1028 unsigned &NumRecords) const {}
1029 virtual const char *getVAListDeclaration() const { return "";}
1030 virtual const char *getClobbers() const {return "";}
1031 virtual const char *getTargetPrefix() const {return "";}
1032 virtual void getGCCRegNames(const char * const *&Names,
1033 unsigned &NumNames) const {}
Anders Carlsson36834a72009-02-28 17:11:49 +00001034 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattner85970f32008-05-08 05:58:21 +00001035 TargetInfo::ConstraintInfo &info) const {
1036 return true;
1037 }
1038 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1039 unsigned &NumAliases) const {}
1040 virtual bool useGlobalsForAutomaticVariables() const {return true;}
1041 };
1042}
1043
Chris Lattner4b009652007-07-25 00:24:17 +00001044//===----------------------------------------------------------------------===//
1045// Driver code
1046//===----------------------------------------------------------------------===//
1047
Ted Kremenekb97d7672007-12-04 17:07:35 +00001048static inline bool IsX86(const std::string& TT) {
Ted Kremenek40499482007-12-03 22:06:55 +00001049 return (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' &&
1050 TT[4] == '-' && TT[1] - '3' < 6);
1051}
1052
Chris Lattnerfc457002008-03-05 01:18:20 +00001053/// CreateTargetInfo - Return the target info object for the specified target
1054/// triple.
1055TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
Eli Friedman2b161652008-08-21 00:13:15 +00001056 // OS detection; this isn't really anywhere near complete.
1057 // Additions and corrections are welcome.
1058 bool isDarwin = T.find("-darwin") != std::string::npos;
Chris Lattnerd4faca42008-08-23 18:23:14 +00001059 bool isDragonFly = T.find("-dragonfly") != std::string::npos;
Chris Lattner98cb2a22008-10-16 17:04:31 +00001060 bool isFreeBSD = T.find("-freebsd") != std::string::npos;
Eli Friedman2b161652008-08-21 00:13:15 +00001061 bool isSolaris = T.find("-solaris") != std::string::npos;
1062 bool isLinux = T.find("-linux") != std::string::npos;
1063 bool isWindows = T.find("-windows") != std::string::npos ||
1064 T.find("-win32") != std::string::npos ||
1065 T.find("-mingw") != std::string::npos;
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001066
Eli Friedman2b161652008-08-21 00:13:15 +00001067 if (T.find("ppc-") == 0 || T.find("powerpc-") == 0) {
1068 if (isDarwin)
1069 return new DarwinPPCTargetInfo(T);
1070 return new PPC32TargetInfo(T);
1071 }
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001072
Eli Friedman2b161652008-08-21 00:13:15 +00001073 if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0) {
1074 if (isDarwin)
1075 return new DarwinPPC64TargetInfo(T);
1076 return new PPC64TargetInfo(T);
1077 }
Chris Lattner9fd73612008-04-21 18:56:49 +00001078
Eli Friedman2b161652008-08-21 00:13:15 +00001079 if (T.find("armv6-") == 0 || T.find("arm-") == 0) {
1080 if (isDarwin)
1081 return new DarwinARMTargetInfo(T);
1082 return new ARMTargetInfo(T);
1083 }
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001084
Eli Friedman2b161652008-08-21 00:13:15 +00001085 if (T.find("sparc-") == 0) {
1086 if (isSolaris)
1087 return new SolarisSparcV8TargetInfo(T);
1088 return new SparcV8TargetInfo(T);
1089 }
1090
Chris Lattner273dce42009-02-20 17:04:14 +00001091 if (T.find("x86_64-") == 0 || T.find("amd64-") == 0) {
Eli Friedman2b161652008-08-21 00:13:15 +00001092 if (isDarwin)
1093 return new DarwinX86_64TargetInfo(T);
Daniel Dunbare5a80f22008-09-23 17:37:57 +00001094 if (isLinux)
1095 return new LinuxX86_64TargetInfo(T);
Chris Lattner98cb2a22008-10-16 17:04:31 +00001096 if (isFreeBSD)
1097 return new FreeBSDX86_64TargetInfo(T);
Eli Friedman2b161652008-08-21 00:13:15 +00001098 return new X86_64TargetInfo(T);
1099 }
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001100
Chris Lattner85970f32008-05-08 05:58:21 +00001101 if (T.find("pic16-") == 0)
1102 return new PIC16TargetInfo(T);
1103
Eli Friedman2b161652008-08-21 00:13:15 +00001104 if (IsX86(T)) {
1105 if (isDarwin)
1106 return new DarwinI386TargetInfo(T);
Eli Friedman5fb0a022008-08-21 00:24:02 +00001107 if (isLinux)
1108 return new LinuxX86_32TargetInfo(T);
Chris Lattnerd4faca42008-08-23 18:23:14 +00001109 if (isDragonFly)
1110 return new DragonFlyX86_32TargetInfo(T);
Chris Lattner98cb2a22008-10-16 17:04:31 +00001111 if (isFreeBSD)
1112 return new FreeBSDX86_32TargetInfo(T);
Eli Friedman23cb7912008-08-21 01:40:19 +00001113 if (isWindows)
1114 return new WindowsX86_32TargetInfo(T);
Eli Friedman2b161652008-08-21 00:13:15 +00001115 return new X86_32TargetInfo(T);
1116 }
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001117
Chris Lattnerfc457002008-03-05 01:18:20 +00001118 return NULL;
Chris Lattner4b009652007-07-25 00:24:17 +00001119}
Ted Kremenekd507bab2008-03-04 17:47:18 +00001120