blob: c72982bf2216fb7f6378dab84ad68a9bf8f41920 [file] [log] [blame]
Reid Spencer5f016e22007-07-11 17:01:13 +00001//===--- Targets.cpp - Implement -arch option and targets -----------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner0bc735f2007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Reid Spencer5f016e22007-07-11 17:01:13 +00007//
8//===----------------------------------------------------------------------===//
9//
Ted Kremenekbbced582007-12-12 18:05:32 +000010// This file implements construction of a TargetInfo object from a
11// target triple.
Reid Spencer5f016e22007-07-11 17:01:13 +000012//
13//===----------------------------------------------------------------------===//
14
Reid Spencer5f016e22007-07-11 17:01:13 +000015#include "clang/AST/Builtins.h"
Anders Carlsson564f1de2007-12-09 23:17:02 +000016#include "clang/AST/TargetBuiltins.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000017#include "clang/Basic/TargetInfo.h"
Chris Lattner8fc4dfb2008-12-04 22:54:33 +000018#include "clang/Basic/LangOptions.h"
Anders Carlsson3346ae62007-11-24 23:38:12 +000019#include "llvm/ADT/STLExtras.h"
Eli Friedman25531262008-05-20 14:27:34 +000020#include "llvm/ADT/APFloat.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000021using namespace clang;
22
Reid Spencer5f016e22007-07-11 17:01:13 +000023//===----------------------------------------------------------------------===//
24// Common code shared among targets.
25//===----------------------------------------------------------------------===//
26
Chris Lattnerd15fa822007-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 Lattnerd29b6302008-10-05 21:50:58 +000037//===----------------------------------------------------------------------===//
38// Defines specific to certain operating systems.
39//===----------------------------------------------------------------------===//
40
Eli Friedman01b86682008-08-20 07:28:14 +000041static void getSolarisDefines(std::vector<char> &Defs) {
42 Define(Defs, "__SUN__");
43 Define(Defs, "__SOLARIS__");
44}
Reid Spencer5f016e22007-07-11 17:01:13 +000045
Nate Begemanca013422009-01-18 01:08:03 +000046static void getFreeBSDDefines(std::vector<char> &Defs, bool is64Bit,
47 const char *Triple) {
Chris Lattnerfd0269d2008-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 Lattnerd29b6302008-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__");
88}
89
Chris Lattnerae0ee032008-12-04 23:20:07 +000090/// getDarwinNumber - Parse the 'darwin number' out of the specific targe
91/// triple. For example, if we have darwin8.5 return 8,5,4. If any entry is
92/// not defined, return 0's. Return true if we have -darwin in the string or
93/// false otherwise.
94static bool getDarwinNumber(const char *Triple, unsigned &Maj, unsigned &Min) {
95 Maj = Min = 0;
96 const char *Darwin = strstr(Triple, "-darwin");
97 if (Darwin == 0) return false;
98
99 Darwin += strlen("-darwin");
100 if (Darwin[0] < '0' || Darwin[0] > '9')
101 return true;
102
103 Maj = Darwin[0]-'0';
104 ++Darwin;
105
106 // Handle "darwin11".
107 if (Maj == 1 && Darwin[0] >= '0' && Darwin[0] <= '9') {
108 Maj = 10+Darwin[0]-'0';
109 ++Darwin;
110 }
111
112 // Handle minor version: 10.4.9 -> darwin8.9 -> "1049"
113 if (Darwin[0] == '.' && Darwin[1] >= '0' && Darwin[1] <= '9' &&
114 Darwin[2] == '\0')
115 Min = Darwin[1]-'0';
116
117 return true;
118}
119
Chris Lattner8b30c412008-09-30 01:00:25 +0000120static void getDarwinDefines(std::vector<char> &Defs, const char *Triple) {
Eli Friedman618234a2008-08-20 02:34:37 +0000121 Define(Defs, "__APPLE__");
122 Define(Defs, "__MACH__");
Chris Lattnerd427ad42009-02-05 07:19:24 +0000123 Define(Defs, "OBJC_NEW_PROPERTIES");
124
125 // FIXME: OBJC_ZEROCOST_EXCEPTIONS when using zero cost eh.
Chris Lattner8b30c412008-09-30 01:00:25 +0000126
127 // Figure out which "darwin number" the target triple is. "darwin9" -> 10.5.
Chris Lattnerae0ee032008-12-04 23:20:07 +0000128 unsigned Maj, Min;
129 if (getDarwinNumber(Triple, Maj, Min)) {
Chris Lattner079f2c462008-09-30 20:30:12 +0000130 char DarwinStr[] = "1000";
Chris Lattnerae0ee032008-12-04 23:20:07 +0000131 if (Maj >= 4 && Maj <= 13) { // 10.0-10.9
132 // darwin7 -> 1030, darwin8 -> 1040, darwin9 -> 1050, etc.
133 DarwinStr[2] = '0' + Maj-4;
Chris Lattner8b30c412008-09-30 01:00:25 +0000134 }
Chris Lattnerae0ee032008-12-04 23:20:07 +0000135
136 // Handle minor version: 10.4.9 -> darwin8.9 -> "1049"
137 DarwinStr[3] = Min+'0';
Chris Lattner079f2c462008-09-30 20:30:12 +0000138 Define(Defs, "__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", DarwinStr);
Chris Lattner8b30c412008-09-30 01:00:25 +0000139 }
Eli Friedman618234a2008-08-20 02:34:37 +0000140}
Reid Spencer5f016e22007-07-11 17:01:13 +0000141
Chris Lattnerae0ee032008-12-04 23:20:07 +0000142/// GetDarwinLanguageOptions - Set the default language options for darwin.
143static void GetDarwinLanguageOptions(LangOptions &Opts,
144 const char *Triple) {
145 Opts.NeXTRuntime = true;
146
147 unsigned Maj, Min;
148 if (!getDarwinNumber(Triple, Maj, Min))
149 return;
150
151 // Blocks default to on for 10.6 (darwin10) and beyond.
Fariborz Jahaniana30b17b2009-02-12 17:54:33 +0000152 // As does nonfragile-abi for 64bit mode
153 if (Maj > 9) {
Chris Lattnerae0ee032008-12-04 23:20:07 +0000154 Opts.Blocks = 1;
Fariborz Jahaniana30b17b2009-02-12 17:54:33 +0000155 if (Opts.ObjC1 && !strncmp(Triple, "x86_64", 6))
156 Opts.ObjCNonFragileABI = 1;
157 }
Chris Lattnerae0ee032008-12-04 23:20:07 +0000158}
159
160
Chris Lattnerd29b6302008-10-05 21:50:58 +0000161//===----------------------------------------------------------------------===//
162// Defines specific to certain architectures.
163//===----------------------------------------------------------------------===//
Eli Friedman0d4047b2008-08-21 00:24:02 +0000164
Reid Spencer5f016e22007-07-11 17:01:13 +0000165/// getPowerPCDefines - Return a set of the PowerPC-specific #defines that are
166/// not tied to a specific subtarget.
Chris Lattnerd15fa822007-10-06 06:57:34 +0000167static void getPowerPCDefines(std::vector<char> &Defs, bool is64Bit) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000168 // Target identification.
Chris Lattnerd15fa822007-10-06 06:57:34 +0000169 Define(Defs, "__ppc__");
170 Define(Defs, "_ARCH_PPC");
171 Define(Defs, "__POWERPC__");
Reid Spencer5f016e22007-07-11 17:01:13 +0000172 if (is64Bit) {
Chris Lattnerd15fa822007-10-06 06:57:34 +0000173 Define(Defs, "_ARCH_PPC64");
174 Define(Defs, "_LP64");
175 Define(Defs, "__LP64__");
176 Define(Defs, "__ppc64__");
Reid Spencer5f016e22007-07-11 17:01:13 +0000177 } else {
Chris Lattnerd15fa822007-10-06 06:57:34 +0000178 Define(Defs, "__ppc__");
Reid Spencer5f016e22007-07-11 17:01:13 +0000179 }
180
181 // Target properties.
Chris Lattnerd15fa822007-10-06 06:57:34 +0000182 Define(Defs, "_BIG_ENDIAN");
183 Define(Defs, "__BIG_ENDIAN__");
Reid Spencer5f016e22007-07-11 17:01:13 +0000184
Reid Spencer5f016e22007-07-11 17:01:13 +0000185 // Subtarget options.
Chris Lattnerd15fa822007-10-06 06:57:34 +0000186 Define(Defs, "__NATURAL_ALIGNMENT__");
187 Define(Defs, "__REGISTER_PREFIX__", "");
Reid Spencer5f016e22007-07-11 17:01:13 +0000188
Chris Lattner12f09262008-10-05 21:49:27 +0000189 // FIXME: Should be controlled by command line option.
Chris Lattnerd15fa822007-10-06 06:57:34 +0000190 Define(Defs, "__LONG_DOUBLE_128__");
Reid Spencer5f016e22007-07-11 17:01:13 +0000191}
192
193/// getX86Defines - Return a set of the X86-specific #defines that are
194/// not tied to a specific subtarget.
Chris Lattnerd15fa822007-10-06 06:57:34 +0000195static void getX86Defines(std::vector<char> &Defs, bool is64Bit) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000196 // Target identification.
197 if (is64Bit) {
Chris Lattnerd15fa822007-10-06 06:57:34 +0000198 Define(Defs, "_LP64");
199 Define(Defs, "__LP64__");
200 Define(Defs, "__amd64__");
201 Define(Defs, "__amd64");
202 Define(Defs, "__x86_64");
203 Define(Defs, "__x86_64__");
Chris Lattner06ebe862009-02-05 07:32:46 +0000204 Define(Defs, "__SSE3__");
Reid Spencer5f016e22007-07-11 17:01:13 +0000205 } else {
Chris Lattnerd15fa822007-10-06 06:57:34 +0000206 Define(Defs, "__i386__");
207 Define(Defs, "__i386");
208 Define(Defs, "i386");
Reid Spencer5f016e22007-07-11 17:01:13 +0000209 }
210
211 // Target properties.
Chris Lattnerd15fa822007-10-06 06:57:34 +0000212 Define(Defs, "__LITTLE_ENDIAN__");
Reid Spencer5f016e22007-07-11 17:01:13 +0000213
Reid Spencer5f016e22007-07-11 17:01:13 +0000214 // Subtarget options.
Chris Lattnerd15fa822007-10-06 06:57:34 +0000215 Define(Defs, "__nocona");
216 Define(Defs, "__nocona__");
217 Define(Defs, "__tune_nocona__");
218 Define(Defs, "__SSE2_MATH__");
219 Define(Defs, "__SSE2__");
220 Define(Defs, "__SSE_MATH__");
221 Define(Defs, "__SSE__");
222 Define(Defs, "__MMX__");
223 Define(Defs, "__REGISTER_PREFIX__", "");
Reid Spencer5f016e22007-07-11 17:01:13 +0000224}
225
Chris Lattnerd0c33d32008-04-21 20:19:54 +0000226/// getARMDefines - Return a set of the ARM-specific #defines that are
Chris Lattner393ff042008-04-21 18:56:49 +0000227/// not tied to a specific subtarget.
228static void getARMDefines(std::vector<char> &Defs) {
229 // Target identification.
230 Define(Defs, "__arm");
231 Define(Defs, "__arm__");
232
233 // Target properties.
234 Define(Defs, "__LITTLE_ENDIAN__");
235
Chris Lattner393ff042008-04-21 18:56:49 +0000236 // Subtarget options. [hard coded to v6 for now]
237 Define(Defs, "__ARM_ARCH_6K__");
238 Define(Defs, "__ARMEL__");
239 Define(Defs, "__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", "20000");
Chris Lattner393ff042008-04-21 18:56:49 +0000240}
241
Eli Friedmane4277982008-08-20 23:11:40 +0000242//===----------------------------------------------------------------------===//
243// Specific target implementations.
244//===----------------------------------------------------------------------===//
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000245
Eli Friedmane4277982008-08-20 23:11:40 +0000246namespace {
247// PPC abstract base class
248class PPCTargetInfo : public TargetInfo {
249 static const Builtin::Info BuiltinInfo[];
250 static const char * const GCCRegNames[];
251 static const TargetInfo::GCCRegAlias GCCRegAliases[];
252
253public:
254 PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {
255 CharIsSigned = false;
256 }
257 virtual void getTargetBuiltins(const Builtin::Info *&Records,
258 unsigned &NumRecords) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000259 Records = BuiltinInfo;
Eli Friedmane4277982008-08-20 23:11:40 +0000260 NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
Reid Spencer5f016e22007-07-11 17:01:13 +0000261 }
Eli Friedmane4277982008-08-20 23:11:40 +0000262 virtual const char *getVAListDeclaration() const {
Chris Lattnerd5998502008-10-27 01:11:29 +0000263 return "typedef char* __builtin_va_list;";
264 // This is the right definition for ABI/V4: System V.4/eabi.
265 /*return "typedef struct __va_list_tag {"
Eli Friedmane4277982008-08-20 23:11:40 +0000266 " unsigned char gpr;"
267 " unsigned char fpr;"
268 " unsigned short reserved;"
269 " void* overflow_arg_area;"
270 " void* reg_save_area;"
Chris Lattnerd5998502008-10-27 01:11:29 +0000271 "} __builtin_va_list[1];";*/
Anders Carlsson3346ae62007-11-24 23:38:12 +0000272 }
Eli Friedmane4277982008-08-20 23:11:40 +0000273 virtual const char *getTargetPrefix() const {
274 return "ppc";
Anders Carlssond04c6e22007-11-27 04:11:28 +0000275 }
Eli Friedmane4277982008-08-20 23:11:40 +0000276 virtual void getGCCRegNames(const char * const *&Names,
277 unsigned &NumNames) const;
278 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
279 unsigned &NumAliases) const;
280 virtual bool validateAsmConstraint(char c,
281 TargetInfo::ConstraintInfo &info) const {
Anders Carlssond04c6e22007-11-27 04:11:28 +0000282 switch (c) {
283 default: return false;
284 case 'O': // Zero
285 return true;
286 case 'b': // Base register
287 case 'f': // Floating point register
288 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
289 return true;
290 }
291 }
Eli Friedmane4277982008-08-20 23:11:40 +0000292 virtual const char *getClobbers() const {
293 return "";
Anders Carlssond04c6e22007-11-27 04:11:28 +0000294 }
Eli Friedmane4277982008-08-20 23:11:40 +0000295};
Anders Carlssond04c6e22007-11-27 04:11:28 +0000296
Eli Friedmane4277982008-08-20 23:11:40 +0000297const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
298#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
299#include "clang/AST/PPCBuiltins.def"
300};
Chris Lattner393ff042008-04-21 18:56:49 +0000301
Eli Friedmane4277982008-08-20 23:11:40 +0000302const char * const PPCTargetInfo::GCCRegNames[] = {
303 "0", "1", "2", "3", "4", "5", "6", "7",
304 "8", "9", "10", "11", "12", "13", "14", "15",
305 "16", "17", "18", "19", "20", "21", "22", "23",
306 "24", "25", "26", "27", "28", "29", "30", "31",
307 "0", "1", "2", "3", "4", "5", "6", "7",
308 "8", "9", "10", "11", "12", "13", "14", "15",
309 "16", "17", "18", "19", "20", "21", "22", "23",
310 "24", "25", "26", "27", "28", "29", "30", "31",
311 "mq", "lr", "ctr", "ap",
312 "0", "1", "2", "3", "4", "5", "6", "7",
313 "xer",
314 "0", "1", "2", "3", "4", "5", "6", "7",
315 "8", "9", "10", "11", "12", "13", "14", "15",
316 "16", "17", "18", "19", "20", "21", "22", "23",
317 "24", "25", "26", "27", "28", "29", "30", "31",
318 "vrsave", "vscr",
319 "spe_acc", "spefscr",
320 "sfp"
321};
Reid Spencer5f016e22007-07-11 17:01:13 +0000322
Eli Friedmane4277982008-08-20 23:11:40 +0000323void PPCTargetInfo::getGCCRegNames(const char * const *&Names,
324 unsigned &NumNames) const {
325 Names = GCCRegNames;
326 NumNames = llvm::array_lengthof(GCCRegNames);
327}
Reid Spencer5f016e22007-07-11 17:01:13 +0000328
Eli Friedmane4277982008-08-20 23:11:40 +0000329const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
330 // While some of these aliases do map to different registers
331 // they still share the same register name.
332 { { "cc", "cr0", "fr0", "r0", "v0"}, "0" },
333 { { "cr1", "fr1", "r1", "sp", "v1"}, "1" },
334 { { "cr2", "fr2", "r2", "toc", "v2"}, "2" },
335 { { "cr3", "fr3", "r3", "v3"}, "3" },
336 { { "cr4", "fr4", "r4", "v4"}, "4" },
337 { { "cr5", "fr5", "r5", "v5"}, "5" },
338 { { "cr6", "fr6", "r6", "v6"}, "6" },
339 { { "cr7", "fr7", "r7", "v7"}, "7" },
340 { { "fr8", "r8", "v8"}, "8" },
341 { { "fr9", "r9", "v9"}, "9" },
342 { { "fr10", "r10", "v10"}, "10" },
343 { { "fr11", "r11", "v11"}, "11" },
344 { { "fr12", "r12", "v12"}, "12" },
345 { { "fr13", "r13", "v13"}, "13" },
346 { { "fr14", "r14", "v14"}, "14" },
347 { { "fr15", "r15", "v15"}, "15" },
348 { { "fr16", "r16", "v16"}, "16" },
349 { { "fr17", "r17", "v17"}, "17" },
350 { { "fr18", "r18", "v18"}, "18" },
351 { { "fr19", "r19", "v19"}, "19" },
352 { { "fr20", "r20", "v20"}, "20" },
353 { { "fr21", "r21", "v21"}, "21" },
354 { { "fr22", "r22", "v22"}, "22" },
355 { { "fr23", "r23", "v23"}, "23" },
356 { { "fr24", "r24", "v24"}, "24" },
357 { { "fr25", "r25", "v25"}, "25" },
358 { { "fr26", "r26", "v26"}, "26" },
359 { { "fr27", "r27", "v27"}, "27" },
360 { { "fr28", "r28", "v28"}, "28" },
361 { { "fr29", "r29", "v29"}, "29" },
362 { { "fr30", "r30", "v30"}, "30" },
363 { { "fr31", "r31", "v31"}, "31" },
364};
365
366void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
367 unsigned &NumAliases) const {
368 Aliases = GCCRegAliases;
369 NumAliases = llvm::array_lengthof(GCCRegAliases);
370}
371} // end anonymous namespace.
Reid Spencer5f016e22007-07-11 17:01:13 +0000372
373namespace {
Eli Friedmane4277982008-08-20 23:11:40 +0000374class PPC32TargetInfo : public PPCTargetInfo {
Reid Spencer5f016e22007-07-11 17:01:13 +0000375public:
Eli Friedmaned855cb2008-08-21 00:13:15 +0000376 PPC32TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
377 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
378 "i64:64:64-f32:32:32-f64:64:64-v128:128:128";
379 }
Chris Lattnerd15fa822007-10-06 06:57:34 +0000380 virtual void getTargetDefines(std::vector<char> &Defines) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000381 getPowerPCDefines(Defines, false);
382 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000383};
384} // end anonymous namespace.
385
386namespace {
Eli Friedmane4277982008-08-20 23:11:40 +0000387class PPC64TargetInfo : public PPCTargetInfo {
Reid Spencer5f016e22007-07-11 17:01:13 +0000388public:
Eli Friedmane4277982008-08-20 23:11:40 +0000389 PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
Chris Lattnerf291b102008-05-09 06:17:04 +0000390 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedmaned855cb2008-08-21 00:13:15 +0000391 DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
392 "i64:64:64-f32:32:32-f64:64:64-v128:128:128";
Chris Lattnerf291b102008-05-09 06:17:04 +0000393 }
Chris Lattnerd15fa822007-10-06 06:57:34 +0000394 virtual void getTargetDefines(std::vector<char> &Defines) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000395 getPowerPCDefines(Defines, true);
396 }
Eli Friedmane4277982008-08-20 23:11:40 +0000397};
398} // end anonymous namespace.
399
Chris Lattnerae0ee032008-12-04 23:20:07 +0000400
Eli Friedmane4277982008-08-20 23:11:40 +0000401namespace {
402class DarwinPPCTargetInfo : public PPC32TargetInfo {
403public:
404 DarwinPPCTargetInfo(const std::string& triple) : PPC32TargetInfo(triple) {}
405 virtual void getTargetDefines(std::vector<char> &Defines) const {
406 PPC32TargetInfo::getTargetDefines(Defines);
Chris Lattner8b30c412008-09-30 01:00:25 +0000407 getDarwinDefines(Defines, getTargetTriple());
Reid Spencer5f016e22007-07-11 17:01:13 +0000408 }
Daniel Dunbardcb4a1a2008-08-23 08:43:39 +0000409
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000410 /// getDefaultLangOptions - Allow the target to specify default settings for
411 /// various language options. These may be overridden by command line
412 /// options.
413 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattnerae0ee032008-12-04 23:20:07 +0000414 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000415 }
Eli Friedmane4277982008-08-20 23:11:40 +0000416};
417} // end anonymous namespace.
418
419namespace {
420class DarwinPPC64TargetInfo : public PPC64TargetInfo {
421public:
422 DarwinPPC64TargetInfo(const std::string& triple) : PPC64TargetInfo(triple) {}
423 virtual void getTargetDefines(std::vector<char> &Defines) const {
424 PPC64TargetInfo::getTargetDefines(Defines);
Chris Lattner8b30c412008-09-30 01:00:25 +0000425 getDarwinDefines(Defines, getTargetTriple());
Anders Carlsson3346ae62007-11-24 23:38:12 +0000426 }
Daniel Dunbardcb4a1a2008-08-23 08:43:39 +0000427
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000428 /// getDefaultLangOptions - Allow the target to specify default settings for
429 /// various language options. These may be overridden by command line
430 /// options.
431 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattnerae0ee032008-12-04 23:20:07 +0000432 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000433 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000434};
435} // end anonymous namespace.
436
437namespace {
Eli Friedman618234a2008-08-20 02:34:37 +0000438// Namespace for x86 abstract base class
439const Builtin::Info BuiltinInfo[] = {
440#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
441#include "clang/AST/X86Builtins.def"
442};
Eli Friedman61538a72008-05-20 14:21:01 +0000443
Eli Friedman618234a2008-08-20 02:34:37 +0000444const char *GCCRegNames[] = {
445 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
446 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
447 "argp", "flags", "fspr", "dirflag", "frame",
448 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
449 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
450 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
451 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
452};
453
454const TargetInfo::GCCRegAlias GCCRegAliases[] = {
455 { { "al", "ah", "eax", "rax" }, "ax" },
456 { { "bl", "bh", "ebx", "rbx" }, "bx" },
457 { { "cl", "ch", "ecx", "rcx" }, "cx" },
458 { { "dl", "dh", "edx", "rdx" }, "dx" },
459 { { "esi", "rsi" }, "si" },
460 { { "edi", "rdi" }, "di" },
461 { { "esp", "rsp" }, "sp" },
462 { { "ebp", "rbp" }, "bp" },
463};
464
465// X86 target abstract base class; x86-32 and x86-64 are very close, so
466// most of the implementation can be shared.
467class X86TargetInfo : public TargetInfo {
468public:
469 X86TargetInfo(const std::string& triple) : TargetInfo(triple) {
470 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
Reid Spencer5f016e22007-07-11 17:01:13 +0000471 }
472 virtual void getTargetBuiltins(const Builtin::Info *&Records,
473 unsigned &NumRecords) const {
Eli Friedman618234a2008-08-20 02:34:37 +0000474 Records = BuiltinInfo;
475 NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
Reid Spencer5f016e22007-07-11 17:01:13 +0000476 }
Anders Carlsson44fe49c2007-12-08 19:32:57 +0000477 virtual const char *getTargetPrefix() const {
Eli Friedman618234a2008-08-20 02:34:37 +0000478 return "x86";
Anders Carlsson44fe49c2007-12-08 19:32:57 +0000479 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000480 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedman618234a2008-08-20 02:34:37 +0000481 unsigned &NumNames) const {
482 Names = GCCRegNames;
483 NumNames = llvm::array_lengthof(GCCRegNames);
Anders Carlsson3346ae62007-11-24 23:38:12 +0000484 }
485 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
486 unsigned &NumAliases) const {
Eli Friedman618234a2008-08-20 02:34:37 +0000487 Aliases = GCCRegAliases;
488 NumAliases = llvm::array_lengthof(GCCRegAliases);
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000489 }
Anders Carlssond04c6e22007-11-27 04:11:28 +0000490 virtual bool validateAsmConstraint(char c,
Eli Friedman618234a2008-08-20 02:34:37 +0000491 TargetInfo::ConstraintInfo &info) const;
492 virtual std::string convertConstraint(const char Constraint) const;
Anders Carlssond04c6e22007-11-27 04:11:28 +0000493 virtual const char *getClobbers() const {
Eli Friedman618234a2008-08-20 02:34:37 +0000494 return "~{dirflag},~{fpsr},~{flags}";
495 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000496};
Eli Friedman618234a2008-08-20 02:34:37 +0000497
498bool
499X86TargetInfo::validateAsmConstraint(char c,
500 TargetInfo::ConstraintInfo &info) const {
501 switch (c) {
502 default: return false;
503 case 'a': // eax.
504 case 'b': // ebx.
505 case 'c': // ecx.
506 case 'd': // edx.
507 case 'S': // esi.
508 case 'D': // edi.
509 case 'A': // edx:eax.
510 case 't': // top of floating point stack.
511 case 'u': // second from top of floating point stack.
512 case 'q': // Any register accessible as [r]l: a, b, c, and d.
Anders Carlssonfce09342008-10-06 00:41:45 +0000513 case 'y': // Any MMX register.
Anders Carlssona7406d42008-10-06 19:17:39 +0000514 case 'x': // Any SSE register.
Eli Friedman618234a2008-08-20 02:34:37 +0000515 case 'Q': // Any register accessible as [r]h: a, b, c, and d.
Anders Carlsson79bc64c2009-01-24 18:03:09 +0000516 case 'e': // 32-bit signed integer constant for use with zero-extending
517 // x86_64 instructions.
518 case 'Z': // 32-bit unsigned integer constant for use with zero-extending
519 // x86_64 instructions.
Eli Friedman618234a2008-08-20 02:34:37 +0000520 case 'N': // unsigned 8-bit integer constant for use with in and out
521 // instructions.
522 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
523 return true;
524 }
525}
526
527std::string
528X86TargetInfo::convertConstraint(const char Constraint) const {
529 switch (Constraint) {
530 case 'a': return std::string("{ax}");
531 case 'b': return std::string("{bx}");
532 case 'c': return std::string("{cx}");
533 case 'd': return std::string("{dx}");
534 case 'S': return std::string("{si}");
535 case 'D': return std::string("{di}");
536 case 't': // top of floating point stack.
537 return std::string("{st}");
538 case 'u': // second from top of floating point stack.
539 return std::string("{st(1)}"); // second from top of floating point stack.
540 default:
541 return std::string(1, Constraint);
542 }
543}
Eli Friedman618234a2008-08-20 02:34:37 +0000544} // end anonymous namespace
Reid Spencer5f016e22007-07-11 17:01:13 +0000545
546namespace {
Eli Friedman618234a2008-08-20 02:34:37 +0000547// X86-32 generic target
548class X86_32TargetInfo : public X86TargetInfo {
Reid Spencer5f016e22007-07-11 17:01:13 +0000549public:
Eli Friedman618234a2008-08-20 02:34:37 +0000550 X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
551 DoubleAlign = LongLongAlign = 32;
552 LongDoubleWidth = 96;
553 LongDoubleAlign = 32;
Eli Friedmaned855cb2008-08-21 00:13:15 +0000554 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
555 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
556 "a0:0:64-f80:32:32";
Eli Friedman618234a2008-08-20 02:34:37 +0000557 }
558 virtual const char *getVAListDeclaration() const {
Eli Friedman01b86682008-08-20 07:28:14 +0000559 return "typedef char* __builtin_va_list;";
Eli Friedman618234a2008-08-20 02:34:37 +0000560 }
561 virtual void getTargetDefines(std::vector<char> &Defines) const {
562 getX86Defines(Defines, false);
563 }
564};
565} // end anonymous namespace
566
567namespace {
568// x86-32 Darwin (OS X) target
569class DarwinI386TargetInfo : public X86_32TargetInfo {
570public:
571 DarwinI386TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
572 LongDoubleWidth = 128;
573 LongDoubleAlign = 128;
Chris Lattnerd427ad42009-02-05 07:19:24 +0000574 PtrDiffType = SignedInt;
Eli Friedmaned855cb2008-08-21 00:13:15 +0000575 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
576 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
577 "a0:0:64-f80:128:128";
Eli Friedman618234a2008-08-20 02:34:37 +0000578 }
579 virtual void getTargetDefines(std::vector<char> &Defines) const {
580 X86_32TargetInfo::getTargetDefines(Defines);
Chris Lattner8b30c412008-09-30 01:00:25 +0000581 getDarwinDefines(Defines, getTargetTriple());
Eli Friedman618234a2008-08-20 02:34:37 +0000582 }
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000583 /// getDefaultLangOptions - Allow the target to specify default settings for
584 /// various language options. These may be overridden by command line
585 /// options.
586 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattnerae0ee032008-12-04 23:20:07 +0000587 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000588 }
Eli Friedman618234a2008-08-20 02:34:37 +0000589};
590} // end anonymous namespace
591
592namespace {
Chris Lattnerfd0269d2008-10-16 17:04:31 +0000593// x86-32 FreeBSD target
594class FreeBSDX86_32TargetInfo : public X86_32TargetInfo {
595public:
Eli Friedmanf509d732008-11-02 02:43:55 +0000596 FreeBSDX86_32TargetInfo(const std::string& triple) :
597 X86_32TargetInfo(triple) {
598 SizeType = UnsignedInt;
599 PtrDiffType = SignedInt;
Chris Lattnerfd0269d2008-10-16 17:04:31 +0000600 }
601 virtual void getTargetDefines(std::vector<char> &Defines) const {
602 X86_32TargetInfo::getTargetDefines(Defines);
603 getFreeBSDDefines(Defines, 0, getTargetTriple());
604 }
605};
606} // end anonymous namespace
607
608namespace {
Chris Lattnereac7aee2008-08-23 18:23:14 +0000609// x86-32 DragonFly target
610class DragonFlyX86_32TargetInfo : public X86_32TargetInfo {
611public:
Eli Friedmanf509d732008-11-02 02:43:55 +0000612 DragonFlyX86_32TargetInfo(const std::string& triple) :
613 X86_32TargetInfo(triple) {
614 SizeType = UnsignedInt;
615 PtrDiffType = SignedInt;
Chris Lattnereac7aee2008-08-23 18:23:14 +0000616 }
617 virtual void getTargetDefines(std::vector<char> &Defines) const {
618 X86_32TargetInfo::getTargetDefines(Defines);
619 getDragonFlyDefines(Defines);
620 }
621};
622} // end anonymous namespace
623
624namespace {
Eli Friedman0d4047b2008-08-21 00:24:02 +0000625// x86-32 Linux target
626class LinuxX86_32TargetInfo : public X86_32TargetInfo {
627public:
628 LinuxX86_32TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
Chris Lattner9b533162008-10-05 19:44:25 +0000629 UserLabelPrefix = "";
Eli Friedmanf509d732008-11-02 02:43:55 +0000630 SizeType = UnsignedInt;
631 PtrDiffType = SignedInt;
Eli Friedman0d4047b2008-08-21 00:24:02 +0000632 }
633 virtual void getTargetDefines(std::vector<char> &Defines) const {
634 X86_32TargetInfo::getTargetDefines(Defines);
635 getLinuxDefines(Defines);
636 }
637};
638} // end anonymous namespace
639
640namespace {
Eli Friedman29a30502008-08-21 01:40:19 +0000641// x86-32 Windows target
642class WindowsX86_32TargetInfo : public X86_32TargetInfo {
643public:
644 WindowsX86_32TargetInfo(const std::string& triple)
645 : X86_32TargetInfo(triple) {
646 // FIXME: Fix wchar_t.
647 // FIXME: We should probably enable -fms-extensions by default for
648 // this target.
Eli Friedmanf509d732008-11-02 02:43:55 +0000649 SizeType = UnsignedInt;
650 PtrDiffType = SignedInt;
Eli Friedman29a30502008-08-21 01:40:19 +0000651 }
652 virtual void getTargetDefines(std::vector<char> &Defines) const {
653 X86_32TargetInfo::getTargetDefines(Defines);
654 // This list is based off of the the list of things MingW defines
655 Define(Defines, "__WIN32__");
656 Define(Defines, "__WIN32");
657 Define(Defines, "_WIN32");
658 Define(Defines, "WIN32");
659 Define(Defines, "__WINNT__");
660 Define(Defines, "__WINNT");
661 Define(Defines, "WINNT");
Eli Friedman29a30502008-08-21 01:40:19 +0000662 Define(Defines, "_X86_");
663 Define(Defines, "__MSVCRT__");
664 }
665};
666} // end anonymous namespace
667
668namespace {
Eli Friedman618234a2008-08-20 02:34:37 +0000669// x86-64 generic target
670class X86_64TargetInfo : public X86TargetInfo {
671public:
672 X86_64TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
Chris Lattnerf291b102008-05-09 06:17:04 +0000673 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Chris Lattner778601f2009-01-28 06:58:19 +0000674 DoubleAlign = LongLongAlign = 64;
Eli Friedman61538a72008-05-20 14:21:01 +0000675 LongDoubleWidth = 128;
676 LongDoubleAlign = 128;
Chris Lattner06ebe862009-02-05 07:32:46 +0000677 IntMaxType = SignedLong;
678 UIntMaxType = UnsignedLong;
679
Eli Friedmaned855cb2008-08-21 00:13:15 +0000680 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
681 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
682 "a0:0:64-f80:128:128";
Reid Spencer5f016e22007-07-11 17:01:13 +0000683 }
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000684 virtual const char *getVAListDeclaration() const {
Eli Friedman01b86682008-08-20 07:28:14 +0000685 return "typedef struct __va_list_tag {"
686 " unsigned gp_offset;"
687 " unsigned fp_offset;"
688 " void* overflow_arg_area;"
689 " void* reg_save_area;"
690 "} __builtin_va_list[1];";
Anders Carlsson3346ae62007-11-24 23:38:12 +0000691 }
Eli Friedman618234a2008-08-20 02:34:37 +0000692 virtual void getTargetDefines(std::vector<char> &Defines) const {
693 getX86Defines(Defines, true);
Anders Carlsson44fe49c2007-12-08 19:32:57 +0000694 }
Eli Friedman618234a2008-08-20 02:34:37 +0000695};
696} // end anonymous namespace
697
698namespace {
Chris Lattnerfd0269d2008-10-16 17:04:31 +0000699// x86-64 FreeBSD target
700class FreeBSDX86_64TargetInfo : public X86_64TargetInfo {
701public:
Eli Friedmanf509d732008-11-02 02:43:55 +0000702 FreeBSDX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) {}
Chris Lattnerfd0269d2008-10-16 17:04:31 +0000703 virtual void getTargetDefines(std::vector<char> &Defines) const {
704 X86_64TargetInfo::getTargetDefines(Defines);
705 getFreeBSDDefines(Defines, 1, getTargetTriple());
706 }
707};
708} // end anonymous namespace
709
710namespace {
Daniel Dunbarb55a42b2008-09-23 17:37:57 +0000711// x86-64 Linux target
712class LinuxX86_64TargetInfo : public X86_64TargetInfo {
713public:
714 LinuxX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) {
Chris Lattner9b533162008-10-05 19:44:25 +0000715 UserLabelPrefix = "";
Daniel Dunbarb55a42b2008-09-23 17:37:57 +0000716 }
717 virtual void getTargetDefines(std::vector<char> &Defines) const {
718 X86_64TargetInfo::getTargetDefines(Defines);
719 getLinuxDefines(Defines);
Daniel Dunbarb55a42b2008-09-23 17:37:57 +0000720 }
721};
722} // end anonymous namespace
723
724namespace {
Eli Friedman618234a2008-08-20 02:34:37 +0000725// x86-64 Darwin (OS X) target
726class DarwinX86_64TargetInfo : public X86_64TargetInfo {
727public:
728 DarwinX86_64TargetInfo(const std::string& triple) :
729 X86_64TargetInfo(triple) {}
730
731 virtual void getTargetDefines(std::vector<char> &Defines) const {
732 X86_64TargetInfo::getTargetDefines(Defines);
Chris Lattner8b30c412008-09-30 01:00:25 +0000733 getDarwinDefines(Defines, getTargetTriple());
Anders Carlsson3346ae62007-11-24 23:38:12 +0000734 }
Daniel Dunbardcb4a1a2008-08-23 08:43:39 +0000735
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000736 /// getDefaultLangOptions - Allow the target to specify default settings for
737 /// various language options. These may be overridden by command line
738 /// options.
739 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattnerae0ee032008-12-04 23:20:07 +0000740 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000741 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000742};
743} // end anonymous namespace.
744
Chris Lattner393ff042008-04-21 18:56:49 +0000745namespace {
Eli Friedmana9f54962008-08-20 07:44:10 +0000746class ARMTargetInfo : public TargetInfo {
Chris Lattner393ff042008-04-21 18:56:49 +0000747public:
Eli Friedmana9f54962008-08-20 07:44:10 +0000748 ARMTargetInfo(const std::string& triple) : TargetInfo(triple) {
749 // FIXME: Are the defaults correct for ARM?
Eli Friedmaned855cb2008-08-21 00:13:15 +0000750 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
751 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:64";
Eli Friedman61538a72008-05-20 14:21:01 +0000752 }
Chris Lattner393ff042008-04-21 18:56:49 +0000753 virtual void getTargetDefines(std::vector<char> &Defines) const {
Chris Lattner393ff042008-04-21 18:56:49 +0000754 getARMDefines(Defines);
755 }
756 virtual void getTargetBuiltins(const Builtin::Info *&Records,
757 unsigned &NumRecords) const {
Eli Friedmana9f54962008-08-20 07:44:10 +0000758 // FIXME: Implement.
759 Records = 0;
Chris Lattner393ff042008-04-21 18:56:49 +0000760 NumRecords = 0;
761 }
762 virtual const char *getVAListDeclaration() const {
Eli Friedmana9f54962008-08-20 07:44:10 +0000763 return "typedef char* __builtin_va_list;";
Chris Lattner393ff042008-04-21 18:56:49 +0000764 }
765 virtual const char *getTargetPrefix() const {
Eli Friedmana9f54962008-08-20 07:44:10 +0000766 return "arm";
Chris Lattner393ff042008-04-21 18:56:49 +0000767 }
Chris Lattner393ff042008-04-21 18:56:49 +0000768 virtual void getGCCRegNames(const char * const *&Names,
769 unsigned &NumNames) const {
Eli Friedmana9f54962008-08-20 07:44:10 +0000770 // FIXME: Implement.
771 Names = 0;
Chris Lattner393ff042008-04-21 18:56:49 +0000772 NumNames = 0;
773 }
774 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
775 unsigned &NumAliases) const {
Eli Friedmana9f54962008-08-20 07:44:10 +0000776 // FIXME: Implement.
777 Aliases = 0;
Chris Lattner393ff042008-04-21 18:56:49 +0000778 NumAliases = 0;
779 }
780 virtual bool validateAsmConstraint(char c,
Nate Begemanad487f42008-04-22 05:03:19 +0000781 TargetInfo::ConstraintInfo &info) const {
Eli Friedmana9f54962008-08-20 07:44:10 +0000782 // FIXME: Check if this is complete
Nate Begemanad487f42008-04-22 05:03:19 +0000783 switch (c) {
Eli Friedmana9f54962008-08-20 07:44:10 +0000784 default:
Nate Begemanad487f42008-04-22 05:03:19 +0000785 case 'l': // r0-r7
786 case 'h': // r8-r15
787 case 'w': // VFP Floating point register single precision
788 case 'P': // VFP Floating point register double precision
789 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
790 return true;
791 }
Chris Lattner393ff042008-04-21 18:56:49 +0000792 return false;
793 }
794 virtual const char *getClobbers() const {
Eli Friedmana9f54962008-08-20 07:44:10 +0000795 // FIXME: Is this really right?
Chris Lattner393ff042008-04-21 18:56:49 +0000796 return "";
797 }
798};
799} // end anonymous namespace.
800
Eli Friedmana9f54962008-08-20 07:44:10 +0000801
802namespace {
803class DarwinARMTargetInfo : public ARMTargetInfo {
804public:
805 DarwinARMTargetInfo(const std::string& triple) : ARMTargetInfo(triple) {}
806
807 virtual void getTargetDefines(std::vector<char> &Defines) const {
808 ARMTargetInfo::getTargetDefines(Defines);
Chris Lattner8b30c412008-09-30 01:00:25 +0000809 getDarwinDefines(Defines, getTargetTriple());
Eli Friedmana9f54962008-08-20 07:44:10 +0000810 }
811};
812} // end anonymous namespace.
813
Reid Spencer5f016e22007-07-11 17:01:13 +0000814namespace {
Eli Friedman01b86682008-08-20 07:28:14 +0000815class SparcV8TargetInfo : public TargetInfo {
Chris Lattnere957f532009-01-27 01:58:38 +0000816 static const TargetInfo::GCCRegAlias GCCRegAliases[];
817 static const char * const GCCRegNames[];
Gabor Greif26658672008-02-21 16:29:08 +0000818public:
Eli Friedman01b86682008-08-20 07:28:14 +0000819 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
820 // FIXME: Support Sparc quad-precision long double?
Eli Friedmaned855cb2008-08-21 00:13:15 +0000821 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
822 "i64:64:64-f32:32:32-f64:64:64-v64:64:64";
Eli Friedman01b86682008-08-20 07:28:14 +0000823 }
Gabor Greif26658672008-02-21 16:29:08 +0000824 virtual void getTargetDefines(std::vector<char> &Defines) const {
Eli Friedman01b86682008-08-20 07:28:14 +0000825 // FIXME: This is missing a lot of important defines; some of the
826 // missing stuff is likely to break system headers.
Gabor Greif26658672008-02-21 16:29:08 +0000827 Define(Defines, "__sparc");
Eli Friedmanbf0c9bd2008-05-25 05:26:09 +0000828 Define(Defines, "__sparc__");
Gabor Greif26658672008-02-21 16:29:08 +0000829 Define(Defines, "__sparcv8");
830 }
831 virtual void getTargetBuiltins(const Builtin::Info *&Records,
832 unsigned &NumRecords) const {
Eli Friedman01b86682008-08-20 07:28:14 +0000833 // FIXME: Implement!
Gabor Greif26658672008-02-21 16:29:08 +0000834 }
835 virtual const char *getVAListDeclaration() const {
Eli Friedman01b86682008-08-20 07:28:14 +0000836 return "typedef void* __builtin_va_list;";
Gabor Greif26658672008-02-21 16:29:08 +0000837 }
838 virtual const char *getTargetPrefix() const {
Eli Friedman01b86682008-08-20 07:28:14 +0000839 return "sparc";
Gabor Greif26658672008-02-21 16:29:08 +0000840 }
841 virtual void getGCCRegNames(const char * const *&Names,
Chris Lattnere957f532009-01-27 01:58:38 +0000842 unsigned &NumNames) const;
Gabor Greif26658672008-02-21 16:29:08 +0000843 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattnere957f532009-01-27 01:58:38 +0000844 unsigned &NumAliases) const;
Gabor Greif26658672008-02-21 16:29:08 +0000845 virtual bool validateAsmConstraint(char c,
846 TargetInfo::ConstraintInfo &info) const {
Eli Friedman01b86682008-08-20 07:28:14 +0000847 // FIXME: Implement!
848 return false;
Gabor Greif26658672008-02-21 16:29:08 +0000849 }
850 virtual const char *getClobbers() const {
Eli Friedman01b86682008-08-20 07:28:14 +0000851 // FIXME: Implement!
852 return "";
Gabor Greif26658672008-02-21 16:29:08 +0000853 }
854};
855
Chris Lattnere957f532009-01-27 01:58:38 +0000856const char * const SparcV8TargetInfo::GCCRegNames[] = {
857 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
858 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
859 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
860 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
861};
862
863void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names,
864 unsigned &NumNames) const {
865 Names = GCCRegNames;
866 NumNames = llvm::array_lengthof(GCCRegNames);
867}
868
869const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = {
870 { { "g0" }, "r0" },
871 { { "g1" }, "r1" },
872 { { "g2" }, "r2" },
873 { { "g3" }, "r3" },
874 { { "g4" }, "r4" },
875 { { "g5" }, "r5" },
876 { { "g6" }, "r6" },
877 { { "g7" }, "r7" },
878 { { "o0" }, "r8" },
879 { { "o1" }, "r9" },
880 { { "o2" }, "r10" },
881 { { "o3" }, "r11" },
882 { { "o4" }, "r12" },
883 { { "o5" }, "r13" },
884 { { "o6", "sp" }, "r14" },
885 { { "o7" }, "r15" },
886 { { "l0" }, "r16" },
887 { { "l1" }, "r17" },
888 { { "l2" }, "r18" },
889 { { "l3" }, "r19" },
890 { { "l4" }, "r20" },
891 { { "l5" }, "r21" },
892 { { "l6" }, "r22" },
893 { { "l7" }, "r23" },
894 { { "i0" }, "r24" },
895 { { "i1" }, "r25" },
896 { { "i2" }, "r26" },
897 { { "i3" }, "r27" },
898 { { "i4" }, "r28" },
899 { { "i5" }, "r29" },
900 { { "i6", "fp" }, "r30" },
901 { { "i7" }, "r31" },
902};
903
904void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
905 unsigned &NumAliases) const {
906 Aliases = GCCRegAliases;
907 NumAliases = llvm::array_lengthof(GCCRegAliases);
908}
Gabor Greif26658672008-02-21 16:29:08 +0000909} // end anonymous namespace.
910
Eli Friedman01b86682008-08-20 07:28:14 +0000911namespace {
912class SolarisSparcV8TargetInfo : public SparcV8TargetInfo {
913public:
914 SolarisSparcV8TargetInfo(const std::string& triple) :
Eli Friedmanf509d732008-11-02 02:43:55 +0000915 SparcV8TargetInfo(triple) {
916 SizeType = UnsignedInt;
917 PtrDiffType = SignedInt;
918 }
Eli Friedman01b86682008-08-20 07:28:14 +0000919
920 virtual void getTargetDefines(std::vector<char> &Defines) const {
921 SparcV8TargetInfo::getTargetDefines(Defines);
922 getSolarisDefines(Defines);
923 }
924};
925} // end anonymous namespace.
Reid Spencer5f016e22007-07-11 17:01:13 +0000926
Chris Lattner2621fd12008-05-08 05:58:21 +0000927namespace {
928 class PIC16TargetInfo : public TargetInfo{
929 public:
930 PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) {
Sanjiv Gupta31fc07d2008-10-31 09:52:39 +0000931 IntWidth = 16;
932 LongWidth = LongLongWidth = 32;
933 PointerWidth = 16;
934 IntAlign = 8;
935 LongAlign = LongLongAlign = 8;
Eli Friedman61538a72008-05-20 14:21:01 +0000936 PointerAlign = 8;
Sanjiv Gupta31fc07d2008-10-31 09:52:39 +0000937 SizeType = UnsignedInt;
938 IntMaxType = SignedLong;
939 UIntMaxType = UnsignedLong;
Eli Friedmanf509d732008-11-02 02:43:55 +0000940 PtrDiffType = SignedInt;
Sanjiv Gupta364af812008-08-18 10:05:22 +0000941 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8";
Chris Lattner2621fd12008-05-08 05:58:21 +0000942 }
Chris Lattner927686f2008-05-09 06:08:39 +0000943 virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; }
944 virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; }
Chris Lattner2621fd12008-05-08 05:58:21 +0000945 virtual void getTargetDefines(std::vector<char> &Defines) const {
946 Define(Defines, "__pic16");
947 }
948 virtual void getTargetBuiltins(const Builtin::Info *&Records,
949 unsigned &NumRecords) const {}
950 virtual const char *getVAListDeclaration() const { return "";}
951 virtual const char *getClobbers() const {return "";}
952 virtual const char *getTargetPrefix() const {return "";}
953 virtual void getGCCRegNames(const char * const *&Names,
954 unsigned &NumNames) const {}
955 virtual bool validateAsmConstraint(char c,
956 TargetInfo::ConstraintInfo &info) const {
957 return true;
958 }
959 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
960 unsigned &NumAliases) const {}
961 virtual bool useGlobalsForAutomaticVariables() const {return true;}
962 };
963}
964
Reid Spencer5f016e22007-07-11 17:01:13 +0000965//===----------------------------------------------------------------------===//
966// Driver code
967//===----------------------------------------------------------------------===//
968
Ted Kremenek8448d382007-12-04 17:07:35 +0000969static inline bool IsX86(const std::string& TT) {
Ted Kremenekae360762007-12-03 22:06:55 +0000970 return (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' &&
971 TT[4] == '-' && TT[1] - '3' < 6);
972}
973
Chris Lattner42e67372008-03-05 01:18:20 +0000974/// CreateTargetInfo - Return the target info object for the specified target
975/// triple.
976TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
Eli Friedmaned855cb2008-08-21 00:13:15 +0000977 // OS detection; this isn't really anywhere near complete.
978 // Additions and corrections are welcome.
979 bool isDarwin = T.find("-darwin") != std::string::npos;
Chris Lattnereac7aee2008-08-23 18:23:14 +0000980 bool isDragonFly = T.find("-dragonfly") != std::string::npos;
Chris Lattnerfd0269d2008-10-16 17:04:31 +0000981 bool isFreeBSD = T.find("-freebsd") != std::string::npos;
Eli Friedmaned855cb2008-08-21 00:13:15 +0000982 bool isSolaris = T.find("-solaris") != std::string::npos;
983 bool isLinux = T.find("-linux") != std::string::npos;
984 bool isWindows = T.find("-windows") != std::string::npos ||
985 T.find("-win32") != std::string::npos ||
986 T.find("-mingw") != std::string::npos;
Eli Friedman61538a72008-05-20 14:21:01 +0000987
Eli Friedmaned855cb2008-08-21 00:13:15 +0000988 if (T.find("ppc-") == 0 || T.find("powerpc-") == 0) {
989 if (isDarwin)
990 return new DarwinPPCTargetInfo(T);
991 return new PPC32TargetInfo(T);
992 }
Eli Friedman61538a72008-05-20 14:21:01 +0000993
Eli Friedmaned855cb2008-08-21 00:13:15 +0000994 if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0) {
995 if (isDarwin)
996 return new DarwinPPC64TargetInfo(T);
997 return new PPC64TargetInfo(T);
998 }
Chris Lattner393ff042008-04-21 18:56:49 +0000999
Eli Friedmaned855cb2008-08-21 00:13:15 +00001000 if (T.find("armv6-") == 0 || T.find("arm-") == 0) {
1001 if (isDarwin)
1002 return new DarwinARMTargetInfo(T);
1003 return new ARMTargetInfo(T);
1004 }
Eli Friedman61538a72008-05-20 14:21:01 +00001005
Eli Friedmaned855cb2008-08-21 00:13:15 +00001006 if (T.find("sparc-") == 0) {
1007 if (isSolaris)
1008 return new SolarisSparcV8TargetInfo(T);
1009 return new SparcV8TargetInfo(T);
1010 }
1011
1012 if (T.find("x86_64-") == 0) {
1013 if (isDarwin)
1014 return new DarwinX86_64TargetInfo(T);
Daniel Dunbarb55a42b2008-09-23 17:37:57 +00001015 if (isLinux)
1016 return new LinuxX86_64TargetInfo(T);
Chris Lattnerfd0269d2008-10-16 17:04:31 +00001017 if (isFreeBSD)
1018 return new FreeBSDX86_64TargetInfo(T);
Eli Friedmaned855cb2008-08-21 00:13:15 +00001019 return new X86_64TargetInfo(T);
1020 }
Eli Friedman61538a72008-05-20 14:21:01 +00001021
Chris Lattner2621fd12008-05-08 05:58:21 +00001022 if (T.find("pic16-") == 0)
1023 return new PIC16TargetInfo(T);
1024
Eli Friedmaned855cb2008-08-21 00:13:15 +00001025 if (IsX86(T)) {
1026 if (isDarwin)
1027 return new DarwinI386TargetInfo(T);
Eli Friedman0d4047b2008-08-21 00:24:02 +00001028 if (isLinux)
1029 return new LinuxX86_32TargetInfo(T);
Chris Lattnereac7aee2008-08-23 18:23:14 +00001030 if (isDragonFly)
1031 return new DragonFlyX86_32TargetInfo(T);
Chris Lattnerfd0269d2008-10-16 17:04:31 +00001032 if (isFreeBSD)
1033 return new FreeBSDX86_32TargetInfo(T);
Eli Friedman29a30502008-08-21 01:40:19 +00001034 if (isWindows)
1035 return new WindowsX86_32TargetInfo(T);
Eli Friedmaned855cb2008-08-21 00:13:15 +00001036 return new X86_32TargetInfo(T);
1037 }
Eli Friedman61538a72008-05-20 14:21:01 +00001038
Chris Lattner42e67372008-03-05 01:18:20 +00001039 return NULL;
Reid Spencer5f016e22007-07-11 17:01:13 +00001040}
Ted Kremenekfb79f7c2008-03-04 17:47:18 +00001041