blob: b37939fc224c440b545d5f64027289644d62c0ac [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
Chris Lattner4b009652007-07-25 00:24:17 +000015#include "clang/AST/Builtins.h"
Anders Carlssone1449c12007-12-09 23:17:02 +000016#include "clang/AST/TargetBuiltins.h"
Chris Lattner4b009652007-07-25 00:24:17 +000017#include "clang/Basic/TargetInfo.h"
Chris Lattnerddae7102008-12-04 22:54:33 +000018#include "clang/Basic/LangOptions.h"
Anders Carlsson7dd1c952007-11-24 23:38:12 +000019#include "llvm/ADT/STLExtras.h"
Eli Friedmand4011892008-05-20 14:27:34 +000020#include "llvm/ADT/APFloat.h"
Chris Lattner4b009652007-07-25 00:24:17 +000021using namespace clang;
22
Chris Lattner4b009652007-07-25 00:24:17 +000023//===----------------------------------------------------------------------===//
24// Common code shared among targets.
25//===----------------------------------------------------------------------===//
26
Chris Lattner0db667a2007-10-06 06:57:34 +000027static void Define(std::vector<char> &Buf, const char *Macro,
28 const char *Val = "1") {
29 const char *Def = "#define ";
30 Buf.insert(Buf.end(), Def, Def+strlen(Def));
31 Buf.insert(Buf.end(), Macro, Macro+strlen(Macro));
32 Buf.push_back(' ');
33 Buf.insert(Buf.end(), Val, Val+strlen(Val));
34 Buf.push_back('\n');
35}
36
Chris Lattnerbd00eb82008-10-05 21:50:58 +000037//===----------------------------------------------------------------------===//
38// Defines specific to certain operating systems.
39//===----------------------------------------------------------------------===//
40
Eli Friedmanff158dd2008-08-20 07:28:14 +000041static void getSolarisDefines(std::vector<char> &Defs) {
42 Define(Defs, "__SUN__");
43 Define(Defs, "__SOLARIS__");
44}
Chris Lattner4b009652007-07-25 00:24:17 +000045
Nate Begemanff1ba1f2009-01-18 01:08:03 +000046static void getFreeBSDDefines(std::vector<char> &Defs, bool is64Bit,
47 const char *Triple) {
Chris Lattner98cb2a22008-10-16 17:04:31 +000048 // FreeBSD defines; list based off of gcc output
49
50 const char *FreeBSD = strstr(Triple, "-freebsd");
51 FreeBSD += strlen("-freebsd");
52 char release[] = "X";
53 release[0] = FreeBSD[0];
54 char version[] = "X00001";
55 version[0] = FreeBSD[0];
56
57 Define(Defs, "__FreeBSD__", release);
58 Define(Defs, "__FreeBSD_cc_version", version);
59 Define(Defs, "__KPRINTF_ATTRIBUTE__");
60 Define(Defs, "unix");
61 Define(Defs, "bsd");
62 if (is64Bit) {
63 Define(Defs, "__LP64__");
64 }
65}
66
Chris Lattnerbd00eb82008-10-05 21:50:58 +000067static void getDragonFlyDefines(std::vector<char> &Defs) {
68 // DragonFly defines; list based off of gcc output
69 Define(Defs, "__DragonFly__");
70 Define(Defs, "__DragonFly_cc_version", "100001");
71 Define(Defs, "__ELF__");
72 Define(Defs, "__KPRINTF_ATTRIBUTE__");
73 Define(Defs, "__tune_i386__");
74 Define(Defs, "unix");
75 Define(Defs, "__unix");
76 Define(Defs, "__unix__");
77}
78
79static void getLinuxDefines(std::vector<char> &Defs) {
80 // Linux defines; list based off of gcc output
81 Define(Defs, "__unix__");
82 Define(Defs, "__unix");
83 Define(Defs, "unix");
84 Define(Defs, "__linux__");
85 Define(Defs, "__linux");
86 Define(Defs, "linux");
87 Define(Defs, "__gnu_linux__");
Argiris Kirtzidis99de9532009-02-14 15:02:45 +000088 Define(Defs, "__ELF__", "1");
Chris Lattnerbd00eb82008-10-05 21:50:58 +000089}
90
Chris Lattnerd7bc88b2008-12-04 23:20:07 +000091/// getDarwinNumber - Parse the 'darwin number' out of the specific targe
92/// triple. For example, if we have darwin8.5 return 8,5,4. If any entry is
93/// not defined, return 0's. Return true if we have -darwin in the string or
94/// false otherwise.
95static bool getDarwinNumber(const char *Triple, unsigned &Maj, unsigned &Min) {
96 Maj = Min = 0;
97 const char *Darwin = strstr(Triple, "-darwin");
98 if (Darwin == 0) return false;
99
100 Darwin += strlen("-darwin");
101 if (Darwin[0] < '0' || Darwin[0] > '9')
102 return true;
103
104 Maj = Darwin[0]-'0';
105 ++Darwin;
106
107 // Handle "darwin11".
108 if (Maj == 1 && Darwin[0] >= '0' && Darwin[0] <= '9') {
109 Maj = 10+Darwin[0]-'0';
110 ++Darwin;
111 }
112
113 // Handle minor version: 10.4.9 -> darwin8.9 -> "1049"
114 if (Darwin[0] == '.' && Darwin[1] >= '0' && Darwin[1] <= '9' &&
115 Darwin[2] == '\0')
116 Min = Darwin[1]-'0';
117
118 return true;
119}
120
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000121static void getDarwinDefines(std::vector<char> &Defs, const char *Triple) {
Eli Friedman872996c2008-08-20 02:34:37 +0000122 Define(Defs, "__APPLE__");
123 Define(Defs, "__MACH__");
Chris Lattner8405e092009-02-05 07:19:24 +0000124 Define(Defs, "OBJC_NEW_PROPERTIES");
125
126 // FIXME: OBJC_ZEROCOST_EXCEPTIONS when using zero cost eh.
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000127
128 // Figure out which "darwin number" the target triple is. "darwin9" -> 10.5.
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000129 unsigned Maj, Min;
130 if (getDarwinNumber(Triple, Maj, Min)) {
Chris Lattnerd376f6d2008-09-30 20:30:12 +0000131 char DarwinStr[] = "1000";
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000132 if (Maj >= 4 && Maj <= 13) { // 10.0-10.9
133 // darwin7 -> 1030, darwin8 -> 1040, darwin9 -> 1050, etc.
134 DarwinStr[2] = '0' + Maj-4;
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000135 }
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000136
137 // Handle minor version: 10.4.9 -> darwin8.9 -> "1049"
138 DarwinStr[3] = Min+'0';
Chris Lattnerd376f6d2008-09-30 20:30:12 +0000139 Define(Defs, "__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", DarwinStr);
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000140 }
Eli Friedman872996c2008-08-20 02:34:37 +0000141}
Chris Lattner4b009652007-07-25 00:24:17 +0000142
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000143/// GetDarwinLanguageOptions - Set the default language options for darwin.
144static void GetDarwinLanguageOptions(LangOptions &Opts,
145 const char *Triple) {
146 Opts.NeXTRuntime = true;
147
148 unsigned Maj, Min;
149 if (!getDarwinNumber(Triple, Maj, Min))
150 return;
151
152 // Blocks default to on for 10.6 (darwin10) and beyond.
Fariborz Jahaniand09b9f72009-02-12 17:54:33 +0000153 // As does nonfragile-abi for 64bit mode
154 if (Maj > 9) {
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000155 Opts.Blocks = 1;
Fariborz Jahaniand09b9f72009-02-12 17:54:33 +0000156 if (Opts.ObjC1 && !strncmp(Triple, "x86_64", 6))
157 Opts.ObjCNonFragileABI = 1;
158 }
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000159}
160
161
Chris Lattnerbd00eb82008-10-05 21:50:58 +0000162//===----------------------------------------------------------------------===//
163// Defines specific to certain architectures.
164//===----------------------------------------------------------------------===//
Eli Friedman5fb0a022008-08-21 00:24:02 +0000165
Chris Lattner4b009652007-07-25 00:24:17 +0000166/// getPowerPCDefines - Return a set of the PowerPC-specific #defines that are
167/// not tied to a specific subtarget.
Chris Lattner0db667a2007-10-06 06:57:34 +0000168static void getPowerPCDefines(std::vector<char> &Defs, bool is64Bit) {
Chris Lattner4b009652007-07-25 00:24:17 +0000169 // Target identification.
Chris Lattner0db667a2007-10-06 06:57:34 +0000170 Define(Defs, "__ppc__");
171 Define(Defs, "_ARCH_PPC");
172 Define(Defs, "__POWERPC__");
Chris Lattner4b009652007-07-25 00:24:17 +0000173 if (is64Bit) {
Chris Lattner0db667a2007-10-06 06:57:34 +0000174 Define(Defs, "_ARCH_PPC64");
175 Define(Defs, "_LP64");
176 Define(Defs, "__LP64__");
177 Define(Defs, "__ppc64__");
Chris Lattner4b009652007-07-25 00:24:17 +0000178 } else {
Chris Lattner0db667a2007-10-06 06:57:34 +0000179 Define(Defs, "__ppc__");
Chris Lattner4b009652007-07-25 00:24:17 +0000180 }
181
182 // Target properties.
Chris Lattner0db667a2007-10-06 06:57:34 +0000183 Define(Defs, "_BIG_ENDIAN");
184 Define(Defs, "__BIG_ENDIAN__");
Chris Lattner4b009652007-07-25 00:24:17 +0000185
Chris Lattner4b009652007-07-25 00:24:17 +0000186 // Subtarget options.
Chris Lattner0db667a2007-10-06 06:57:34 +0000187 Define(Defs, "__NATURAL_ALIGNMENT__");
188 Define(Defs, "__REGISTER_PREFIX__", "");
Chris Lattner4b009652007-07-25 00:24:17 +0000189
Chris Lattner3da35682008-10-05 21:49:27 +0000190 // FIXME: Should be controlled by command line option.
Chris Lattner0db667a2007-10-06 06:57:34 +0000191 Define(Defs, "__LONG_DOUBLE_128__");
Chris Lattner4b009652007-07-25 00:24:17 +0000192}
193
194/// getX86Defines - Return a set of the X86-specific #defines that are
195/// not tied to a specific subtarget.
Chris Lattner0db667a2007-10-06 06:57:34 +0000196static void getX86Defines(std::vector<char> &Defs, bool is64Bit) {
Chris Lattner4b009652007-07-25 00:24:17 +0000197 // Target identification.
198 if (is64Bit) {
Chris Lattner0db667a2007-10-06 06:57:34 +0000199 Define(Defs, "_LP64");
200 Define(Defs, "__LP64__");
201 Define(Defs, "__amd64__");
202 Define(Defs, "__amd64");
203 Define(Defs, "__x86_64");
204 Define(Defs, "__x86_64__");
Chris Lattnerbfbfbaf2009-02-05 07:32:46 +0000205 Define(Defs, "__SSE3__");
Chris Lattner4b009652007-07-25 00:24:17 +0000206 } else {
Chris Lattner0db667a2007-10-06 06:57:34 +0000207 Define(Defs, "__i386__");
208 Define(Defs, "__i386");
209 Define(Defs, "i386");
Chris Lattner4b009652007-07-25 00:24:17 +0000210 }
211
212 // Target properties.
Chris Lattner0db667a2007-10-06 06:57:34 +0000213 Define(Defs, "__LITTLE_ENDIAN__");
Chris Lattner4b009652007-07-25 00:24:17 +0000214
Chris Lattner4b009652007-07-25 00:24:17 +0000215 // Subtarget options.
Chris Lattner0db667a2007-10-06 06:57:34 +0000216 Define(Defs, "__nocona");
217 Define(Defs, "__nocona__");
218 Define(Defs, "__tune_nocona__");
219 Define(Defs, "__SSE2_MATH__");
220 Define(Defs, "__SSE2__");
221 Define(Defs, "__SSE_MATH__");
222 Define(Defs, "__SSE__");
223 Define(Defs, "__MMX__");
224 Define(Defs, "__REGISTER_PREFIX__", "");
Chris Lattner4b009652007-07-25 00:24:17 +0000225}
226
Chris Lattnerb6444052008-04-21 20:19:54 +0000227/// getARMDefines - Return a set of the ARM-specific #defines that are
Chris Lattner9fd73612008-04-21 18:56:49 +0000228/// not tied to a specific subtarget.
229static void getARMDefines(std::vector<char> &Defs) {
230 // Target identification.
231 Define(Defs, "__arm");
232 Define(Defs, "__arm__");
233
234 // Target properties.
235 Define(Defs, "__LITTLE_ENDIAN__");
236
Chris Lattner9fd73612008-04-21 18:56:49 +0000237 // Subtarget options. [hard coded to v6 for now]
238 Define(Defs, "__ARM_ARCH_6K__");
239 Define(Defs, "__ARMEL__");
240 Define(Defs, "__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", "20000");
Chris Lattner9fd73612008-04-21 18:56:49 +0000241}
242
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000243//===----------------------------------------------------------------------===//
244// Specific target implementations.
245//===----------------------------------------------------------------------===//
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000246
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000247namespace {
248// PPC abstract base class
249class PPCTargetInfo : public TargetInfo {
250 static const Builtin::Info BuiltinInfo[];
251 static const char * const GCCRegNames[];
252 static const TargetInfo::GCCRegAlias GCCRegAliases[];
253
254public:
255 PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {
256 CharIsSigned = false;
257 }
258 virtual void getTargetBuiltins(const Builtin::Info *&Records,
259 unsigned &NumRecords) const {
Chris Lattner4b009652007-07-25 00:24:17 +0000260 Records = BuiltinInfo;
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000261 NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner4b009652007-07-25 00:24:17 +0000262 }
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000263 virtual const char *getVAListDeclaration() const {
Chris Lattnera07708f2008-10-27 01:11:29 +0000264 return "typedef char* __builtin_va_list;";
265 // This is the right definition for ABI/V4: System V.4/eabi.
266 /*return "typedef struct __va_list_tag {"
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000267 " unsigned char gpr;"
268 " unsigned char fpr;"
269 " unsigned short reserved;"
270 " void* overflow_arg_area;"
271 " void* reg_save_area;"
Chris Lattnera07708f2008-10-27 01:11:29 +0000272 "} __builtin_va_list[1];";*/
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000273 }
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000274 virtual const char *getTargetPrefix() const {
275 return "ppc";
Anders Carlsson4ce42302007-11-27 04:11:28 +0000276 }
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000277 virtual void getGCCRegNames(const char * const *&Names,
278 unsigned &NumNames) const;
279 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
280 unsigned &NumAliases) const;
281 virtual bool validateAsmConstraint(char c,
282 TargetInfo::ConstraintInfo &info) const {
Anders Carlsson4ce42302007-11-27 04:11:28 +0000283 switch (c) {
284 default: return false;
285 case 'O': // Zero
286 return true;
287 case 'b': // Base register
288 case 'f': // Floating point register
289 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
290 return true;
291 }
292 }
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000293 virtual const char *getClobbers() const {
294 return "";
Anders Carlsson4ce42302007-11-27 04:11:28 +0000295 }
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000296};
Anders Carlsson4ce42302007-11-27 04:11:28 +0000297
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000298const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
299#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
300#include "clang/AST/PPCBuiltins.def"
301};
Chris Lattner9fd73612008-04-21 18:56:49 +0000302
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000303const char * const PPCTargetInfo::GCCRegNames[] = {
304 "0", "1", "2", "3", "4", "5", "6", "7",
305 "8", "9", "10", "11", "12", "13", "14", "15",
306 "16", "17", "18", "19", "20", "21", "22", "23",
307 "24", "25", "26", "27", "28", "29", "30", "31",
308 "0", "1", "2", "3", "4", "5", "6", "7",
309 "8", "9", "10", "11", "12", "13", "14", "15",
310 "16", "17", "18", "19", "20", "21", "22", "23",
311 "24", "25", "26", "27", "28", "29", "30", "31",
312 "mq", "lr", "ctr", "ap",
313 "0", "1", "2", "3", "4", "5", "6", "7",
314 "xer",
315 "0", "1", "2", "3", "4", "5", "6", "7",
316 "8", "9", "10", "11", "12", "13", "14", "15",
317 "16", "17", "18", "19", "20", "21", "22", "23",
318 "24", "25", "26", "27", "28", "29", "30", "31",
319 "vrsave", "vscr",
320 "spe_acc", "spefscr",
321 "sfp"
322};
Chris Lattner4b009652007-07-25 00:24:17 +0000323
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000324void PPCTargetInfo::getGCCRegNames(const char * const *&Names,
325 unsigned &NumNames) const {
326 Names = GCCRegNames;
327 NumNames = llvm::array_lengthof(GCCRegNames);
328}
Chris Lattner4b009652007-07-25 00:24:17 +0000329
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000330const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
331 // While some of these aliases do map to different registers
332 // they still share the same register name.
333 { { "cc", "cr0", "fr0", "r0", "v0"}, "0" },
334 { { "cr1", "fr1", "r1", "sp", "v1"}, "1" },
335 { { "cr2", "fr2", "r2", "toc", "v2"}, "2" },
336 { { "cr3", "fr3", "r3", "v3"}, "3" },
337 { { "cr4", "fr4", "r4", "v4"}, "4" },
338 { { "cr5", "fr5", "r5", "v5"}, "5" },
339 { { "cr6", "fr6", "r6", "v6"}, "6" },
340 { { "cr7", "fr7", "r7", "v7"}, "7" },
341 { { "fr8", "r8", "v8"}, "8" },
342 { { "fr9", "r9", "v9"}, "9" },
343 { { "fr10", "r10", "v10"}, "10" },
344 { { "fr11", "r11", "v11"}, "11" },
345 { { "fr12", "r12", "v12"}, "12" },
346 { { "fr13", "r13", "v13"}, "13" },
347 { { "fr14", "r14", "v14"}, "14" },
348 { { "fr15", "r15", "v15"}, "15" },
349 { { "fr16", "r16", "v16"}, "16" },
350 { { "fr17", "r17", "v17"}, "17" },
351 { { "fr18", "r18", "v18"}, "18" },
352 { { "fr19", "r19", "v19"}, "19" },
353 { { "fr20", "r20", "v20"}, "20" },
354 { { "fr21", "r21", "v21"}, "21" },
355 { { "fr22", "r22", "v22"}, "22" },
356 { { "fr23", "r23", "v23"}, "23" },
357 { { "fr24", "r24", "v24"}, "24" },
358 { { "fr25", "r25", "v25"}, "25" },
359 { { "fr26", "r26", "v26"}, "26" },
360 { { "fr27", "r27", "v27"}, "27" },
361 { { "fr28", "r28", "v28"}, "28" },
362 { { "fr29", "r29", "v29"}, "29" },
363 { { "fr30", "r30", "v30"}, "30" },
364 { { "fr31", "r31", "v31"}, "31" },
365};
366
367void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
368 unsigned &NumAliases) const {
369 Aliases = GCCRegAliases;
370 NumAliases = llvm::array_lengthof(GCCRegAliases);
371}
372} // end anonymous namespace.
Chris Lattner4b009652007-07-25 00:24:17 +0000373
374namespace {
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000375class PPC32TargetInfo : public PPCTargetInfo {
Chris Lattner4b009652007-07-25 00:24:17 +0000376public:
Eli Friedman2b161652008-08-21 00:13:15 +0000377 PPC32TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
378 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
379 "i64:64:64-f32:32:32-f64:64:64-v128:128:128";
380 }
Chris Lattner0db667a2007-10-06 06:57:34 +0000381 virtual void getTargetDefines(std::vector<char> &Defines) const {
Chris Lattner4b009652007-07-25 00:24:17 +0000382 getPowerPCDefines(Defines, false);
383 }
Chris Lattner4b009652007-07-25 00:24:17 +0000384};
385} // end anonymous namespace.
386
387namespace {
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000388class PPC64TargetInfo : public PPCTargetInfo {
Chris Lattner4b009652007-07-25 00:24:17 +0000389public:
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000390 PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
Chris Lattnere5fde952008-05-09 06:17:04 +0000391 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedman2b161652008-08-21 00:13:15 +0000392 DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
393 "i64:64:64-f32:32:32-f64:64:64-v128:128:128";
Chris Lattnere5fde952008-05-09 06:17:04 +0000394 }
Chris Lattner0db667a2007-10-06 06:57:34 +0000395 virtual void getTargetDefines(std::vector<char> &Defines) const {
Chris Lattner4b009652007-07-25 00:24:17 +0000396 getPowerPCDefines(Defines, true);
397 }
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000398};
399} // end anonymous namespace.
400
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000401
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000402namespace {
403class DarwinPPCTargetInfo : public PPC32TargetInfo {
404public:
405 DarwinPPCTargetInfo(const std::string& triple) : PPC32TargetInfo(triple) {}
406 virtual void getTargetDefines(std::vector<char> &Defines) const {
407 PPC32TargetInfo::getTargetDefines(Defines);
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000408 getDarwinDefines(Defines, getTargetTriple());
Chris Lattner4b009652007-07-25 00:24:17 +0000409 }
Daniel Dunbar34542952008-08-23 08:43:39 +0000410
Chris Lattnerddae7102008-12-04 22:54:33 +0000411 /// getDefaultLangOptions - Allow the target to specify default settings for
412 /// various language options. These may be overridden by command line
413 /// options.
414 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000415 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattnerddae7102008-12-04 22:54:33 +0000416 }
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000417};
418} // end anonymous namespace.
419
420namespace {
421class DarwinPPC64TargetInfo : public PPC64TargetInfo {
422public:
423 DarwinPPC64TargetInfo(const std::string& triple) : PPC64TargetInfo(triple) {}
424 virtual void getTargetDefines(std::vector<char> &Defines) const {
425 PPC64TargetInfo::getTargetDefines(Defines);
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000426 getDarwinDefines(Defines, getTargetTriple());
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000427 }
Daniel Dunbar34542952008-08-23 08:43:39 +0000428
Chris Lattnerddae7102008-12-04 22:54:33 +0000429 /// getDefaultLangOptions - Allow the target to specify default settings for
430 /// various language options. These may be overridden by command line
431 /// options.
432 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000433 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattnerddae7102008-12-04 22:54:33 +0000434 }
Chris Lattner4b009652007-07-25 00:24:17 +0000435};
436} // end anonymous namespace.
437
438namespace {
Eli Friedman872996c2008-08-20 02:34:37 +0000439// Namespace for x86 abstract base class
440const Builtin::Info BuiltinInfo[] = {
441#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
442#include "clang/AST/X86Builtins.def"
443};
Eli Friedman0b7b1cb2008-05-20 14:21:01 +0000444
Eli Friedman872996c2008-08-20 02:34:37 +0000445const char *GCCRegNames[] = {
446 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
447 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
448 "argp", "flags", "fspr", "dirflag", "frame",
449 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
450 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
451 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
452 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
453};
454
455const TargetInfo::GCCRegAlias GCCRegAliases[] = {
456 { { "al", "ah", "eax", "rax" }, "ax" },
457 { { "bl", "bh", "ebx", "rbx" }, "bx" },
458 { { "cl", "ch", "ecx", "rcx" }, "cx" },
459 { { "dl", "dh", "edx", "rdx" }, "dx" },
460 { { "esi", "rsi" }, "si" },
461 { { "edi", "rdi" }, "di" },
462 { { "esp", "rsp" }, "sp" },
463 { { "ebp", "rbp" }, "bp" },
464};
465
466// X86 target abstract base class; x86-32 and x86-64 are very close, so
467// most of the implementation can be shared.
468class X86TargetInfo : public TargetInfo {
469public:
470 X86TargetInfo(const std::string& triple) : TargetInfo(triple) {
471 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
Chris Lattner4b009652007-07-25 00:24:17 +0000472 }
473 virtual void getTargetBuiltins(const Builtin::Info *&Records,
474 unsigned &NumRecords) const {
Eli Friedman872996c2008-08-20 02:34:37 +0000475 Records = BuiltinInfo;
476 NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner4b009652007-07-25 00:24:17 +0000477 }
Anders Carlsson333052c2007-12-08 19:32:57 +0000478 virtual const char *getTargetPrefix() const {
Eli Friedman872996c2008-08-20 02:34:37 +0000479 return "x86";
Anders Carlsson333052c2007-12-08 19:32:57 +0000480 }
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000481 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedman872996c2008-08-20 02:34:37 +0000482 unsigned &NumNames) const {
483 Names = GCCRegNames;
484 NumNames = llvm::array_lengthof(GCCRegNames);
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000485 }
486 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
487 unsigned &NumAliases) const {
Eli Friedman872996c2008-08-20 02:34:37 +0000488 Aliases = GCCRegAliases;
489 NumAliases = llvm::array_lengthof(GCCRegAliases);
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000490 }
Anders Carlsson4ce42302007-11-27 04:11:28 +0000491 virtual bool validateAsmConstraint(char c,
Eli Friedman872996c2008-08-20 02:34:37 +0000492 TargetInfo::ConstraintInfo &info) const;
493 virtual std::string convertConstraint(const char Constraint) const;
Anders Carlsson4ce42302007-11-27 04:11:28 +0000494 virtual const char *getClobbers() const {
Eli Friedman872996c2008-08-20 02:34:37 +0000495 return "~{dirflag},~{fpsr},~{flags}";
496 }
Chris Lattner4b009652007-07-25 00:24:17 +0000497};
Eli Friedman872996c2008-08-20 02:34:37 +0000498
499bool
500X86TargetInfo::validateAsmConstraint(char c,
501 TargetInfo::ConstraintInfo &info) const {
502 switch (c) {
503 default: return false;
504 case 'a': // eax.
505 case 'b': // ebx.
506 case 'c': // ecx.
507 case 'd': // edx.
508 case 'S': // esi.
509 case 'D': // edi.
510 case 'A': // edx:eax.
511 case 't': // top of floating point stack.
512 case 'u': // second from top of floating point stack.
513 case 'q': // Any register accessible as [r]l: a, b, c, and d.
Anders Carlsson2285e622008-10-06 00:41:45 +0000514 case 'y': // Any MMX register.
Anders Carlssond2459f92008-10-06 19:17:39 +0000515 case 'x': // Any SSE register.
Eli Friedman872996c2008-08-20 02:34:37 +0000516 case 'Q': // Any register accessible as [r]h: a, b, c, and d.
Anders Carlssonff235da2009-01-24 18:03:09 +0000517 case 'e': // 32-bit signed integer constant for use with zero-extending
518 // x86_64 instructions.
519 case 'Z': // 32-bit unsigned integer constant for use with zero-extending
520 // x86_64 instructions.
Eli Friedman872996c2008-08-20 02:34:37 +0000521 case 'N': // unsigned 8-bit integer constant for use with in and out
522 // instructions.
523 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
524 return true;
525 }
526}
527
528std::string
529X86TargetInfo::convertConstraint(const char Constraint) const {
530 switch (Constraint) {
531 case 'a': return std::string("{ax}");
532 case 'b': return std::string("{bx}");
533 case 'c': return std::string("{cx}");
534 case 'd': return std::string("{dx}");
535 case 'S': return std::string("{si}");
536 case 'D': return std::string("{di}");
537 case 't': // top of floating point stack.
538 return std::string("{st}");
539 case 'u': // second from top of floating point stack.
540 return std::string("{st(1)}"); // second from top of floating point stack.
541 default:
542 return std::string(1, Constraint);
543 }
544}
Eli Friedman872996c2008-08-20 02:34:37 +0000545} // end anonymous namespace
Chris Lattner4b009652007-07-25 00:24:17 +0000546
547namespace {
Eli Friedman872996c2008-08-20 02:34:37 +0000548// X86-32 generic target
549class X86_32TargetInfo : public X86TargetInfo {
Chris Lattner4b009652007-07-25 00:24:17 +0000550public:
Eli Friedman872996c2008-08-20 02:34:37 +0000551 X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
552 DoubleAlign = LongLongAlign = 32;
553 LongDoubleWidth = 96;
554 LongDoubleAlign = 32;
Eli Friedman2b161652008-08-21 00:13:15 +0000555 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
556 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
557 "a0:0:64-f80:32:32";
Eli Friedman872996c2008-08-20 02:34:37 +0000558 }
559 virtual const char *getVAListDeclaration() const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000560 return "typedef char* __builtin_va_list;";
Eli Friedman872996c2008-08-20 02:34:37 +0000561 }
562 virtual void getTargetDefines(std::vector<char> &Defines) const {
563 getX86Defines(Defines, false);
564 }
565};
566} // end anonymous namespace
567
568namespace {
569// x86-32 Darwin (OS X) target
570class DarwinI386TargetInfo : public X86_32TargetInfo {
571public:
572 DarwinI386TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
573 LongDoubleWidth = 128;
574 LongDoubleAlign = 128;
Chris Lattner8405e092009-02-05 07:19:24 +0000575 PtrDiffType = SignedInt;
Eli Friedman2b161652008-08-21 00:13:15 +0000576 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
577 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
578 "a0:0:64-f80:128:128";
Eli Friedman872996c2008-08-20 02:34:37 +0000579 }
580 virtual void getTargetDefines(std::vector<char> &Defines) const {
581 X86_32TargetInfo::getTargetDefines(Defines);
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000582 getDarwinDefines(Defines, getTargetTriple());
Eli Friedman872996c2008-08-20 02:34:37 +0000583 }
Chris Lattnerddae7102008-12-04 22:54:33 +0000584 /// getDefaultLangOptions - Allow the target to specify default settings for
585 /// various language options. These may be overridden by command line
586 /// options.
587 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000588 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattnerddae7102008-12-04 22:54:33 +0000589 }
Eli Friedman872996c2008-08-20 02:34:37 +0000590};
591} // end anonymous namespace
592
593namespace {
Chris Lattner98cb2a22008-10-16 17:04:31 +0000594// x86-32 FreeBSD target
595class FreeBSDX86_32TargetInfo : public X86_32TargetInfo {
596public:
Eli Friedman7cca0982008-11-02 02:43:55 +0000597 FreeBSDX86_32TargetInfo(const std::string& triple) :
598 X86_32TargetInfo(triple) {
599 SizeType = UnsignedInt;
600 PtrDiffType = SignedInt;
Chris Lattner98cb2a22008-10-16 17:04:31 +0000601 }
602 virtual void getTargetDefines(std::vector<char> &Defines) const {
603 X86_32TargetInfo::getTargetDefines(Defines);
604 getFreeBSDDefines(Defines, 0, getTargetTriple());
605 }
606};
607} // end anonymous namespace
608
609namespace {
Chris Lattnerd4faca42008-08-23 18:23:14 +0000610// x86-32 DragonFly target
611class DragonFlyX86_32TargetInfo : public X86_32TargetInfo {
612public:
Eli Friedman7cca0982008-11-02 02:43:55 +0000613 DragonFlyX86_32TargetInfo(const std::string& triple) :
614 X86_32TargetInfo(triple) {
615 SizeType = UnsignedInt;
616 PtrDiffType = SignedInt;
Chris Lattnerd4faca42008-08-23 18:23:14 +0000617 }
618 virtual void getTargetDefines(std::vector<char> &Defines) const {
619 X86_32TargetInfo::getTargetDefines(Defines);
620 getDragonFlyDefines(Defines);
621 }
622};
623} // end anonymous namespace
624
625namespace {
Eli Friedman5fb0a022008-08-21 00:24:02 +0000626// x86-32 Linux target
627class LinuxX86_32TargetInfo : public X86_32TargetInfo {
628public:
629 LinuxX86_32TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
Chris Lattner5edfe012008-10-05 19:44:25 +0000630 UserLabelPrefix = "";
Eli Friedman7cca0982008-11-02 02:43:55 +0000631 SizeType = UnsignedInt;
632 PtrDiffType = SignedInt;
Chris Lattnerd9ef7242009-02-13 22:28:55 +0000633 IntPtrType = SignedInt;
Eli Friedman5fb0a022008-08-21 00:24:02 +0000634 }
635 virtual void getTargetDefines(std::vector<char> &Defines) const {
636 X86_32TargetInfo::getTargetDefines(Defines);
637 getLinuxDefines(Defines);
638 }
639};
640} // end anonymous namespace
641
642namespace {
Eli Friedman23cb7912008-08-21 01:40:19 +0000643// x86-32 Windows target
644class WindowsX86_32TargetInfo : public X86_32TargetInfo {
645public:
646 WindowsX86_32TargetInfo(const std::string& triple)
647 : X86_32TargetInfo(triple) {
648 // FIXME: Fix wchar_t.
649 // FIXME: We should probably enable -fms-extensions by default for
650 // this target.
Eli Friedman7cca0982008-11-02 02:43:55 +0000651 SizeType = UnsignedInt;
652 PtrDiffType = SignedInt;
Eli Friedman23cb7912008-08-21 01:40:19 +0000653 }
654 virtual void getTargetDefines(std::vector<char> &Defines) const {
655 X86_32TargetInfo::getTargetDefines(Defines);
656 // This list is based off of the the list of things MingW defines
657 Define(Defines, "__WIN32__");
658 Define(Defines, "__WIN32");
659 Define(Defines, "_WIN32");
660 Define(Defines, "WIN32");
661 Define(Defines, "__WINNT__");
662 Define(Defines, "__WINNT");
663 Define(Defines, "WINNT");
Eli Friedman23cb7912008-08-21 01:40:19 +0000664 Define(Defines, "_X86_");
665 Define(Defines, "__MSVCRT__");
666 }
667};
668} // end anonymous namespace
669
670namespace {
Eli Friedman872996c2008-08-20 02:34:37 +0000671// x86-64 generic target
672class X86_64TargetInfo : public X86TargetInfo {
673public:
674 X86_64TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
Chris Lattnere5fde952008-05-09 06:17:04 +0000675 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Chris Lattner4dfc45a2009-01-28 06:58:19 +0000676 DoubleAlign = LongLongAlign = 64;
Eli Friedman0b7b1cb2008-05-20 14:21:01 +0000677 LongDoubleWidth = 128;
678 LongDoubleAlign = 128;
Chris Lattnerbfbfbaf2009-02-05 07:32:46 +0000679 IntMaxType = SignedLong;
680 UIntMaxType = UnsignedLong;
681
Eli Friedman2b161652008-08-21 00:13:15 +0000682 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
683 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
684 "a0:0:64-f80:128:128";
Chris Lattner4b009652007-07-25 00:24:17 +0000685 }
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000686 virtual const char *getVAListDeclaration() const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000687 return "typedef struct __va_list_tag {"
688 " unsigned gp_offset;"
689 " unsigned fp_offset;"
690 " void* overflow_arg_area;"
691 " void* reg_save_area;"
692 "} __builtin_va_list[1];";
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000693 }
Eli Friedman872996c2008-08-20 02:34:37 +0000694 virtual void getTargetDefines(std::vector<char> &Defines) const {
695 getX86Defines(Defines, true);
Anders Carlsson333052c2007-12-08 19:32:57 +0000696 }
Eli Friedman872996c2008-08-20 02:34:37 +0000697};
698} // end anonymous namespace
699
700namespace {
Chris Lattner98cb2a22008-10-16 17:04:31 +0000701// x86-64 FreeBSD target
702class FreeBSDX86_64TargetInfo : public X86_64TargetInfo {
703public:
Eli Friedman7cca0982008-11-02 02:43:55 +0000704 FreeBSDX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) {}
Chris Lattner98cb2a22008-10-16 17:04:31 +0000705 virtual void getTargetDefines(std::vector<char> &Defines) const {
706 X86_64TargetInfo::getTargetDefines(Defines);
707 getFreeBSDDefines(Defines, 1, getTargetTriple());
708 }
709};
710} // end anonymous namespace
711
712namespace {
Daniel Dunbare5a80f22008-09-23 17:37:57 +0000713// x86-64 Linux target
714class LinuxX86_64TargetInfo : public X86_64TargetInfo {
715public:
716 LinuxX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) {
Chris Lattner5edfe012008-10-05 19:44:25 +0000717 UserLabelPrefix = "";
Daniel Dunbare5a80f22008-09-23 17:37:57 +0000718 }
719 virtual void getTargetDefines(std::vector<char> &Defines) const {
720 X86_64TargetInfo::getTargetDefines(Defines);
721 getLinuxDefines(Defines);
Daniel Dunbare5a80f22008-09-23 17:37:57 +0000722 }
723};
724} // end anonymous namespace
725
726namespace {
Eli Friedman872996c2008-08-20 02:34:37 +0000727// x86-64 Darwin (OS X) target
728class DarwinX86_64TargetInfo : public X86_64TargetInfo {
729public:
730 DarwinX86_64TargetInfo(const std::string& triple) :
731 X86_64TargetInfo(triple) {}
732
733 virtual void getTargetDefines(std::vector<char> &Defines) const {
734 X86_64TargetInfo::getTargetDefines(Defines);
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000735 getDarwinDefines(Defines, getTargetTriple());
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000736 }
Daniel Dunbar34542952008-08-23 08:43:39 +0000737
Chris Lattnerddae7102008-12-04 22:54:33 +0000738 /// getDefaultLangOptions - Allow the target to specify default settings for
739 /// various language options. These may be overridden by command line
740 /// options.
741 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000742 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattnerddae7102008-12-04 22:54:33 +0000743 }
Chris Lattner4b009652007-07-25 00:24:17 +0000744};
745} // end anonymous namespace.
746
Chris Lattner9fd73612008-04-21 18:56:49 +0000747namespace {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000748class ARMTargetInfo : public TargetInfo {
Chris Lattner9fd73612008-04-21 18:56:49 +0000749public:
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000750 ARMTargetInfo(const std::string& triple) : TargetInfo(triple) {
751 // FIXME: Are the defaults correct for ARM?
Eli Friedman2b161652008-08-21 00:13:15 +0000752 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
753 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:64";
Eli Friedman0b7b1cb2008-05-20 14:21:01 +0000754 }
Chris Lattner9fd73612008-04-21 18:56:49 +0000755 virtual void getTargetDefines(std::vector<char> &Defines) const {
Chris Lattner9fd73612008-04-21 18:56:49 +0000756 getARMDefines(Defines);
757 }
758 virtual void getTargetBuiltins(const Builtin::Info *&Records,
759 unsigned &NumRecords) const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000760 // FIXME: Implement.
761 Records = 0;
Chris Lattner9fd73612008-04-21 18:56:49 +0000762 NumRecords = 0;
763 }
764 virtual const char *getVAListDeclaration() const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000765 return "typedef char* __builtin_va_list;";
Chris Lattner9fd73612008-04-21 18:56:49 +0000766 }
767 virtual const char *getTargetPrefix() const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000768 return "arm";
Chris Lattner9fd73612008-04-21 18:56:49 +0000769 }
Chris Lattner9fd73612008-04-21 18:56:49 +0000770 virtual void getGCCRegNames(const char * const *&Names,
771 unsigned &NumNames) const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000772 // FIXME: Implement.
773 Names = 0;
Chris Lattner9fd73612008-04-21 18:56:49 +0000774 NumNames = 0;
775 }
776 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
777 unsigned &NumAliases) const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000778 // FIXME: Implement.
779 Aliases = 0;
Chris Lattner9fd73612008-04-21 18:56:49 +0000780 NumAliases = 0;
781 }
782 virtual bool validateAsmConstraint(char c,
Nate Begeman222823a2008-04-22 05:03:19 +0000783 TargetInfo::ConstraintInfo &info) const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000784 // FIXME: Check if this is complete
Nate Begeman222823a2008-04-22 05:03:19 +0000785 switch (c) {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000786 default:
Nate Begeman222823a2008-04-22 05:03:19 +0000787 case 'l': // r0-r7
788 case 'h': // r8-r15
789 case 'w': // VFP Floating point register single precision
790 case 'P': // VFP Floating point register double precision
791 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
792 return true;
793 }
Chris Lattner9fd73612008-04-21 18:56:49 +0000794 return false;
795 }
796 virtual const char *getClobbers() const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000797 // FIXME: Is this really right?
Chris Lattner9fd73612008-04-21 18:56:49 +0000798 return "";
799 }
800};
801} // end anonymous namespace.
802
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000803
804namespace {
805class DarwinARMTargetInfo : public ARMTargetInfo {
806public:
807 DarwinARMTargetInfo(const std::string& triple) : ARMTargetInfo(triple) {}
808
809 virtual void getTargetDefines(std::vector<char> &Defines) const {
810 ARMTargetInfo::getTargetDefines(Defines);
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000811 getDarwinDefines(Defines, getTargetTriple());
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000812 }
813};
814} // end anonymous namespace.
815
Chris Lattner4b009652007-07-25 00:24:17 +0000816namespace {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000817class SparcV8TargetInfo : public TargetInfo {
Chris Lattnerff7c53d2009-01-27 01:58:38 +0000818 static const TargetInfo::GCCRegAlias GCCRegAliases[];
819 static const char * const GCCRegNames[];
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000820public:
Eli Friedmanff158dd2008-08-20 07:28:14 +0000821 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
822 // FIXME: Support Sparc quad-precision long double?
Eli Friedman2b161652008-08-21 00:13:15 +0000823 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
824 "i64:64:64-f32:32:32-f64:64:64-v64:64:64";
Eli Friedmanff158dd2008-08-20 07:28:14 +0000825 }
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000826 virtual void getTargetDefines(std::vector<char> &Defines) const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000827 // FIXME: This is missing a lot of important defines; some of the
828 // missing stuff is likely to break system headers.
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000829 Define(Defines, "__sparc");
Eli Friedman1dee5c52008-05-25 05:26:09 +0000830 Define(Defines, "__sparc__");
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000831 Define(Defines, "__sparcv8");
832 }
833 virtual void getTargetBuiltins(const Builtin::Info *&Records,
834 unsigned &NumRecords) const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000835 // FIXME: Implement!
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000836 }
837 virtual const char *getVAListDeclaration() const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000838 return "typedef void* __builtin_va_list;";
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000839 }
840 virtual const char *getTargetPrefix() const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000841 return "sparc";
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000842 }
843 virtual void getGCCRegNames(const char * const *&Names,
Chris Lattnerff7c53d2009-01-27 01:58:38 +0000844 unsigned &NumNames) const;
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000845 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattnerff7c53d2009-01-27 01:58:38 +0000846 unsigned &NumAliases) const;
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000847 virtual bool validateAsmConstraint(char c,
848 TargetInfo::ConstraintInfo &info) const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000849 // FIXME: Implement!
850 return false;
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000851 }
852 virtual const char *getClobbers() const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000853 // FIXME: Implement!
854 return "";
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000855 }
856};
857
Chris Lattnerff7c53d2009-01-27 01:58:38 +0000858const char * const SparcV8TargetInfo::GCCRegNames[] = {
859 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
860 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
861 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
862 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
863};
864
865void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names,
866 unsigned &NumNames) const {
867 Names = GCCRegNames;
868 NumNames = llvm::array_lengthof(GCCRegNames);
869}
870
871const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = {
872 { { "g0" }, "r0" },
873 { { "g1" }, "r1" },
874 { { "g2" }, "r2" },
875 { { "g3" }, "r3" },
876 { { "g4" }, "r4" },
877 { { "g5" }, "r5" },
878 { { "g6" }, "r6" },
879 { { "g7" }, "r7" },
880 { { "o0" }, "r8" },
881 { { "o1" }, "r9" },
882 { { "o2" }, "r10" },
883 { { "o3" }, "r11" },
884 { { "o4" }, "r12" },
885 { { "o5" }, "r13" },
886 { { "o6", "sp" }, "r14" },
887 { { "o7" }, "r15" },
888 { { "l0" }, "r16" },
889 { { "l1" }, "r17" },
890 { { "l2" }, "r18" },
891 { { "l3" }, "r19" },
892 { { "l4" }, "r20" },
893 { { "l5" }, "r21" },
894 { { "l6" }, "r22" },
895 { { "l7" }, "r23" },
896 { { "i0" }, "r24" },
897 { { "i1" }, "r25" },
898 { { "i2" }, "r26" },
899 { { "i3" }, "r27" },
900 { { "i4" }, "r28" },
901 { { "i5" }, "r29" },
902 { { "i6", "fp" }, "r30" },
903 { { "i7" }, "r31" },
904};
905
906void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
907 unsigned &NumAliases) const {
908 Aliases = GCCRegAliases;
909 NumAliases = llvm::array_lengthof(GCCRegAliases);
910}
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000911} // end anonymous namespace.
912
Eli Friedmanff158dd2008-08-20 07:28:14 +0000913namespace {
914class SolarisSparcV8TargetInfo : public SparcV8TargetInfo {
915public:
916 SolarisSparcV8TargetInfo(const std::string& triple) :
Eli Friedman7cca0982008-11-02 02:43:55 +0000917 SparcV8TargetInfo(triple) {
918 SizeType = UnsignedInt;
919 PtrDiffType = SignedInt;
920 }
Eli Friedmanff158dd2008-08-20 07:28:14 +0000921
922 virtual void getTargetDefines(std::vector<char> &Defines) const {
923 SparcV8TargetInfo::getTargetDefines(Defines);
924 getSolarisDefines(Defines);
925 }
926};
927} // end anonymous namespace.
Chris Lattner4b009652007-07-25 00:24:17 +0000928
Chris Lattner85970f32008-05-08 05:58:21 +0000929namespace {
930 class PIC16TargetInfo : public TargetInfo{
931 public:
932 PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) {
Sanjiv Guptafa451432008-10-31 09:52:39 +0000933 IntWidth = 16;
934 LongWidth = LongLongWidth = 32;
935 PointerWidth = 16;
936 IntAlign = 8;
937 LongAlign = LongLongAlign = 8;
Eli Friedman0b7b1cb2008-05-20 14:21:01 +0000938 PointerAlign = 8;
Sanjiv Guptafa451432008-10-31 09:52:39 +0000939 SizeType = UnsignedInt;
940 IntMaxType = SignedLong;
941 UIntMaxType = UnsignedLong;
Chris Lattnerd9ef7242009-02-13 22:28:55 +0000942 IntPtrType = SignedShort;
Eli Friedman7cca0982008-11-02 02:43:55 +0000943 PtrDiffType = SignedInt;
Sanjiv Guptaebd8f0f2008-08-18 10:05:22 +0000944 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8";
Chris Lattner85970f32008-05-08 05:58:21 +0000945 }
Chris Lattner727b3c42008-05-09 06:08:39 +0000946 virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; }
947 virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; }
Chris Lattner85970f32008-05-08 05:58:21 +0000948 virtual void getTargetDefines(std::vector<char> &Defines) const {
949 Define(Defines, "__pic16");
950 }
951 virtual void getTargetBuiltins(const Builtin::Info *&Records,
952 unsigned &NumRecords) const {}
953 virtual const char *getVAListDeclaration() const { return "";}
954 virtual const char *getClobbers() const {return "";}
955 virtual const char *getTargetPrefix() const {return "";}
956 virtual void getGCCRegNames(const char * const *&Names,
957 unsigned &NumNames) const {}
958 virtual bool validateAsmConstraint(char c,
959 TargetInfo::ConstraintInfo &info) const {
960 return true;
961 }
962 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
963 unsigned &NumAliases) const {}
964 virtual bool useGlobalsForAutomaticVariables() const {return true;}
965 };
966}
967
Chris Lattner4b009652007-07-25 00:24:17 +0000968//===----------------------------------------------------------------------===//
969// Driver code
970//===----------------------------------------------------------------------===//
971
Ted Kremenekb97d7672007-12-04 17:07:35 +0000972static inline bool IsX86(const std::string& TT) {
Ted Kremenek40499482007-12-03 22:06:55 +0000973 return (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' &&
974 TT[4] == '-' && TT[1] - '3' < 6);
975}
976
Chris Lattnerfc457002008-03-05 01:18:20 +0000977/// CreateTargetInfo - Return the target info object for the specified target
978/// triple.
979TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
Eli Friedman2b161652008-08-21 00:13:15 +0000980 // OS detection; this isn't really anywhere near complete.
981 // Additions and corrections are welcome.
982 bool isDarwin = T.find("-darwin") != std::string::npos;
Chris Lattnerd4faca42008-08-23 18:23:14 +0000983 bool isDragonFly = T.find("-dragonfly") != std::string::npos;
Chris Lattner98cb2a22008-10-16 17:04:31 +0000984 bool isFreeBSD = T.find("-freebsd") != std::string::npos;
Eli Friedman2b161652008-08-21 00:13:15 +0000985 bool isSolaris = T.find("-solaris") != std::string::npos;
986 bool isLinux = T.find("-linux") != std::string::npos;
987 bool isWindows = T.find("-windows") != std::string::npos ||
988 T.find("-win32") != std::string::npos ||
989 T.find("-mingw") != std::string::npos;
Eli Friedman0b7b1cb2008-05-20 14:21:01 +0000990
Eli Friedman2b161652008-08-21 00:13:15 +0000991 if (T.find("ppc-") == 0 || T.find("powerpc-") == 0) {
992 if (isDarwin)
993 return new DarwinPPCTargetInfo(T);
994 return new PPC32TargetInfo(T);
995 }
Eli Friedman0b7b1cb2008-05-20 14:21:01 +0000996
Eli Friedman2b161652008-08-21 00:13:15 +0000997 if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0) {
998 if (isDarwin)
999 return new DarwinPPC64TargetInfo(T);
1000 return new PPC64TargetInfo(T);
1001 }
Chris Lattner9fd73612008-04-21 18:56:49 +00001002
Eli Friedman2b161652008-08-21 00:13:15 +00001003 if (T.find("armv6-") == 0 || T.find("arm-") == 0) {
1004 if (isDarwin)
1005 return new DarwinARMTargetInfo(T);
1006 return new ARMTargetInfo(T);
1007 }
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001008
Eli Friedman2b161652008-08-21 00:13:15 +00001009 if (T.find("sparc-") == 0) {
1010 if (isSolaris)
1011 return new SolarisSparcV8TargetInfo(T);
1012 return new SparcV8TargetInfo(T);
1013 }
1014
1015 if (T.find("x86_64-") == 0) {
1016 if (isDarwin)
1017 return new DarwinX86_64TargetInfo(T);
Daniel Dunbare5a80f22008-09-23 17:37:57 +00001018 if (isLinux)
1019 return new LinuxX86_64TargetInfo(T);
Chris Lattner98cb2a22008-10-16 17:04:31 +00001020 if (isFreeBSD)
1021 return new FreeBSDX86_64TargetInfo(T);
Eli Friedman2b161652008-08-21 00:13:15 +00001022 return new X86_64TargetInfo(T);
1023 }
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001024
Chris Lattner85970f32008-05-08 05:58:21 +00001025 if (T.find("pic16-") == 0)
1026 return new PIC16TargetInfo(T);
1027
Eli Friedman2b161652008-08-21 00:13:15 +00001028 if (IsX86(T)) {
1029 if (isDarwin)
1030 return new DarwinI386TargetInfo(T);
Eli Friedman5fb0a022008-08-21 00:24:02 +00001031 if (isLinux)
1032 return new LinuxX86_32TargetInfo(T);
Chris Lattnerd4faca42008-08-23 18:23:14 +00001033 if (isDragonFly)
1034 return new DragonFlyX86_32TargetInfo(T);
Chris Lattner98cb2a22008-10-16 17:04:31 +00001035 if (isFreeBSD)
1036 return new FreeBSDX86_32TargetInfo(T);
Eli Friedman23cb7912008-08-21 01:40:19 +00001037 if (isWindows)
1038 return new WindowsX86_32TargetInfo(T);
Eli Friedman2b161652008-08-21 00:13:15 +00001039 return new X86_32TargetInfo(T);
1040 }
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001041
Chris Lattnerfc457002008-03-05 01:18:20 +00001042 return NULL;
Chris Lattner4b009652007-07-25 00:24:17 +00001043}
Ted Kremenekd507bab2008-03-04 17:47:18 +00001044