blob: fcd105a7aafb0ddd7cef32114ca7e064a893800a [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/Diagnostic.h"
18#include "clang/Basic/TargetInfo.h"
Anders Carlsson3346ae62007-11-24 23:38:12 +000019#include "llvm/ADT/STLExtras.h"
Ted Kremenekae360762007-12-03 22:06:55 +000020
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
37
Reid Spencer5f016e22007-07-11 17:01:13 +000038namespace {
39class DarwinTargetInfo : public TargetInfoImpl {
40public:
Ted Kremenekae360762007-12-03 22:06:55 +000041 DarwinTargetInfo(const std::string& triple) : TargetInfoImpl(triple) {}
42
Chris Lattnerd15fa822007-10-06 06:57:34 +000043 virtual void getTargetDefines(std::vector<char> &Defs) const {
Chris Lattner338128b2007-10-17 06:04:46 +000044// FIXME: we need a real target configuration system. For now, only define
45// __APPLE__ if the host has it.
46#ifdef __APPLE__
Chris Lattnerd15fa822007-10-06 06:57:34 +000047 Define(Defs, "__APPLE__");
48 Define(Defs, "__MACH__");
Chris Lattner338128b2007-10-17 06:04:46 +000049#endif
Reid Spencer5f016e22007-07-11 17:01:13 +000050
51 if (1) {// -fobjc-gc controls this.
Chris Lattnerd15fa822007-10-06 06:57:34 +000052 Define(Defs, "__weak", "");
53 Define(Defs, "__strong", "");
Reid Spencer5f016e22007-07-11 17:01:13 +000054 } else {
Chris Lattnerd15fa822007-10-06 06:57:34 +000055 Define(Defs, "__weak", "__attribute__((objc_gc(weak)))");
56 Define(Defs, "__strong", "__attribute__((objc_gc(strong)))");
57 Define(Defs, "__OBJC_GC__");
Reid Spencer5f016e22007-07-11 17:01:13 +000058 }
59
60 // darwin_constant_cfstrings controls this.
Chris Lattnerd15fa822007-10-06 06:57:34 +000061 Define(Defs, "__CONSTANT_CFSTRINGS__");
Reid Spencer5f016e22007-07-11 17:01:13 +000062
63 if (0) // darwin_pascal_strings
Chris Lattnerd15fa822007-10-06 06:57:34 +000064 Define(Defs, "__PASCAL_STRINGS__");
Reid Spencer5f016e22007-07-11 17:01:13 +000065 }
66
67};
68} // end anonymous namespace.
69
70
71/// getPowerPCDefines - Return a set of the PowerPC-specific #defines that are
72/// not tied to a specific subtarget.
Chris Lattnerd15fa822007-10-06 06:57:34 +000073static void getPowerPCDefines(std::vector<char> &Defs, bool is64Bit) {
Reid Spencer5f016e22007-07-11 17:01:13 +000074 // Target identification.
Chris Lattnerd15fa822007-10-06 06:57:34 +000075 Define(Defs, "__ppc__");
76 Define(Defs, "_ARCH_PPC");
77 Define(Defs, "__POWERPC__");
Reid Spencer5f016e22007-07-11 17:01:13 +000078 if (is64Bit) {
Chris Lattnerd15fa822007-10-06 06:57:34 +000079 Define(Defs, "_ARCH_PPC64");
80 Define(Defs, "_LP64");
81 Define(Defs, "__LP64__");
82 Define(Defs, "__ppc64__");
Reid Spencer5f016e22007-07-11 17:01:13 +000083 } else {
Chris Lattnerd15fa822007-10-06 06:57:34 +000084 Define(Defs, "__ppc__");
Reid Spencer5f016e22007-07-11 17:01:13 +000085 }
86
87 // Target properties.
Chris Lattnerd15fa822007-10-06 06:57:34 +000088 Define(Defs, "_BIG_ENDIAN");
89 Define(Defs, "__BIG_ENDIAN__");
Reid Spencer5f016e22007-07-11 17:01:13 +000090
91 if (is64Bit) {
Chris Lattnerd15fa822007-10-06 06:57:34 +000092 Define(Defs, "__INTMAX_MAX__", "9223372036854775807L");
93 Define(Defs, "__INTMAX_TYPE__", "long int");
94 Define(Defs, "__LONG_MAX__", "9223372036854775807L");
95 Define(Defs, "__PTRDIFF_TYPE__", "long int");
96 Define(Defs, "__UINTMAX_TYPE__", "long unsigned int");
Reid Spencer5f016e22007-07-11 17:01:13 +000097 } else {
Chris Lattnerd15fa822007-10-06 06:57:34 +000098 Define(Defs, "__INTMAX_MAX__", "9223372036854775807LL");
99 Define(Defs, "__INTMAX_TYPE__", "long long int");
100 Define(Defs, "__LONG_MAX__", "2147483647L");
101 Define(Defs, "__PTRDIFF_TYPE__", "int");
102 Define(Defs, "__UINTMAX_TYPE__", "long long unsigned int");
Reid Spencer5f016e22007-07-11 17:01:13 +0000103 }
Chris Lattnerd15fa822007-10-06 06:57:34 +0000104 Define(Defs, "__INT_MAX__", "2147483647");
105 Define(Defs, "__LONG_LONG_MAX__", "9223372036854775807LL");
106 Define(Defs, "__CHAR_BIT__", "8");
107 Define(Defs, "__SCHAR_MAX__", "127");
108 Define(Defs, "__SHRT_MAX__", "32767");
109 Define(Defs, "__SIZE_TYPE__", "long unsigned int");
Reid Spencer5f016e22007-07-11 17:01:13 +0000110
111 // Subtarget options.
Chris Lattnerd15fa822007-10-06 06:57:34 +0000112 Define(Defs, "__USER_LABEL_PREFIX__", "_");
113 Define(Defs, "__NATURAL_ALIGNMENT__");
114 Define(Defs, "__REGISTER_PREFIX__", "");
Reid Spencer5f016e22007-07-11 17:01:13 +0000115
Chris Lattnerd15fa822007-10-06 06:57:34 +0000116 Define(Defs, "__WCHAR_MAX__", "2147483647");
117 Define(Defs, "__WCHAR_TYPE__", "int");
118 Define(Defs, "__WINT_TYPE__", "int");
Reid Spencer5f016e22007-07-11 17:01:13 +0000119
120 // Float macros.
Chris Lattnerd15fa822007-10-06 06:57:34 +0000121 Define(Defs, "__FLT_DENORM_MIN__", "1.40129846e-45F");
122 Define(Defs, "__FLT_DIG__", "6");
123 Define(Defs, "__FLT_EPSILON__", "1.19209290e-7F");
124 Define(Defs, "__FLT_EVAL_METHOD__", "0");
125 Define(Defs, "__FLT_HAS_INFINITY__");
126 Define(Defs, "__FLT_HAS_QUIET_NAN__");
127 Define(Defs, "__FLT_MANT_DIG__", "24");
128 Define(Defs, "__FLT_MAX_10_EXP__", "38");
129 Define(Defs, "__FLT_MAX_EXP__", "128");
130 Define(Defs, "__FLT_MAX__", "3.40282347e+38F");
131 Define(Defs, "__FLT_MIN_10_EXP__", "(-37)");
132 Define(Defs, "__FLT_MIN_EXP__", "(-125)");
133 Define(Defs, "__FLT_MIN__", "1.17549435e-38F");
134 Define(Defs, "__FLT_RADIX__", "2");
Reid Spencer5f016e22007-07-11 17:01:13 +0000135
136 // double macros.
Chris Lattnerd15fa822007-10-06 06:57:34 +0000137 Define(Defs, "__DBL_DENORM_MIN__", "4.9406564584124654e-324");
138 Define(Defs, "__DBL_DIG__", "15");
139 Define(Defs, "__DBL_EPSILON__", "2.2204460492503131e-16");
140 Define(Defs, "__DBL_HAS_INFINITY__");
141 Define(Defs, "__DBL_HAS_QUIET_NAN__");
142 Define(Defs, "__DBL_MANT_DIG__", "53");
143 Define(Defs, "__DBL_MAX_10_EXP__", "308");
144 Define(Defs, "__DBL_MAX_EXP__", "1024");
145 Define(Defs, "__DBL_MAX__", "1.7976931348623157e+308");
146 Define(Defs, "__DBL_MIN_10_EXP__", "(-307)");
147 Define(Defs, "__DBL_MIN_EXP__", "(-1021)");
148 Define(Defs, "__DBL_MIN__", "2.2250738585072014e-308");
149 Define(Defs, "__DECIMAL_DIG__", "33");
Reid Spencer5f016e22007-07-11 17:01:13 +0000150
151 // 128-bit long double macros.
Chris Lattnerd15fa822007-10-06 06:57:34 +0000152 Define(Defs, "__LDBL_DENORM_MIN__",
153 "4.94065645841246544176568792868221e-324L");
154 Define(Defs, "__LDBL_DIG__", "31");
155 Define(Defs, "__LDBL_EPSILON__",
156 "4.94065645841246544176568792868221e-324L");
157 Define(Defs, "__LDBL_HAS_INFINITY__");
158 Define(Defs, "__LDBL_HAS_QUIET_NAN__");
159 Define(Defs, "__LDBL_MANT_DIG__", "106");
160 Define(Defs, "__LDBL_MAX_10_EXP__", "308");
161 Define(Defs, "__LDBL_MAX_EXP__", "1024");
162 Define(Defs, "__LDBL_MAX__",
163 "1.79769313486231580793728971405301e+308L");
164 Define(Defs, "__LDBL_MIN_10_EXP__", "(-291)");
165 Define(Defs, "__LDBL_MIN_EXP__", "(-968)");
166 Define(Defs, "__LDBL_MIN__",
167 "2.00416836000897277799610805135016e-292L");
168 Define(Defs, "__LONG_DOUBLE_128__");
Reid Spencer5f016e22007-07-11 17:01:13 +0000169}
170
171/// getX86Defines - Return a set of the X86-specific #defines that are
172/// not tied to a specific subtarget.
Chris Lattnerd15fa822007-10-06 06:57:34 +0000173static void getX86Defines(std::vector<char> &Defs, bool is64Bit) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000174 // Target identification.
175 if (is64Bit) {
Chris Lattnerd15fa822007-10-06 06:57:34 +0000176 Define(Defs, "_LP64");
177 Define(Defs, "__LP64__");
178 Define(Defs, "__amd64__");
179 Define(Defs, "__amd64");
180 Define(Defs, "__x86_64");
181 Define(Defs, "__x86_64__");
Reid Spencer5f016e22007-07-11 17:01:13 +0000182 } else {
Chris Lattnerd15fa822007-10-06 06:57:34 +0000183 Define(Defs, "__i386__");
184 Define(Defs, "__i386");
185 Define(Defs, "i386");
Reid Spencer5f016e22007-07-11 17:01:13 +0000186 }
187
188 // Target properties.
Chris Lattnerd15fa822007-10-06 06:57:34 +0000189 Define(Defs, "__LITTLE_ENDIAN__");
Reid Spencer5f016e22007-07-11 17:01:13 +0000190
191 if (is64Bit) {
Chris Lattnerd15fa822007-10-06 06:57:34 +0000192 Define(Defs, "__INTMAX_MAX__", "9223372036854775807L");
193 Define(Defs, "__INTMAX_TYPE__", "long int");
194 Define(Defs, "__LONG_MAX__", "9223372036854775807L");
195 Define(Defs, "__PTRDIFF_TYPE__", "long int");
196 Define(Defs, "__UINTMAX_TYPE__", "long unsigned int");
Reid Spencer5f016e22007-07-11 17:01:13 +0000197 } else {
Chris Lattnerd15fa822007-10-06 06:57:34 +0000198 Define(Defs, "__INTMAX_MAX__", "9223372036854775807LL");
199 Define(Defs, "__INTMAX_TYPE__", "long long int");
200 Define(Defs, "__LONG_MAX__", "2147483647L");
201 Define(Defs, "__PTRDIFF_TYPE__", "int");
202 Define(Defs, "__UINTMAX_TYPE__", "long long unsigned int");
Reid Spencer5f016e22007-07-11 17:01:13 +0000203 }
Chris Lattnerd15fa822007-10-06 06:57:34 +0000204 Define(Defs, "__CHAR_BIT__", "8");
205 Define(Defs, "__INT_MAX__", "2147483647");
206 Define(Defs, "__LONG_LONG_MAX__", "9223372036854775807LL");
207 Define(Defs, "__SCHAR_MAX__", "127");
208 Define(Defs, "__SHRT_MAX__", "32767");
209 Define(Defs, "__SIZE_TYPE__", "long unsigned int");
Reid Spencer5f016e22007-07-11 17:01:13 +0000210
211 // Subtarget options.
Chris Lattnerd15fa822007-10-06 06:57:34 +0000212 Define(Defs, "__nocona");
213 Define(Defs, "__nocona__");
214 Define(Defs, "__tune_nocona__");
215 Define(Defs, "__SSE2_MATH__");
216 Define(Defs, "__SSE2__");
217 Define(Defs, "__SSE_MATH__");
218 Define(Defs, "__SSE__");
219 Define(Defs, "__MMX__");
220 Define(Defs, "__REGISTER_PREFIX__", "");
Reid Spencer5f016e22007-07-11 17:01:13 +0000221
Chris Lattnerd15fa822007-10-06 06:57:34 +0000222 Define(Defs, "__WCHAR_MAX__", "2147483647");
223 Define(Defs, "__WCHAR_TYPE__", "int");
224 Define(Defs, "__WINT_TYPE__", "int");
Reid Spencer5f016e22007-07-11 17:01:13 +0000225
226 // Float macros.
Chris Lattnerd15fa822007-10-06 06:57:34 +0000227 Define(Defs, "__FLT_DENORM_MIN__", "1.40129846e-45F");
228 Define(Defs, "__FLT_DIG__", "6");
229 Define(Defs, "__FLT_EPSILON__", "1.19209290e-7F");
230 Define(Defs, "__FLT_EVAL_METHOD__", "0");
231 Define(Defs, "__FLT_HAS_INFINITY__");
232 Define(Defs, "__FLT_HAS_QUIET_NAN__");
233 Define(Defs, "__FLT_MANT_DIG__", "24");
234 Define(Defs, "__FLT_MAX_10_EXP__", "38");
235 Define(Defs, "__FLT_MAX_EXP__", "128");
236 Define(Defs, "__FLT_MAX__", "3.40282347e+38F");
237 Define(Defs, "__FLT_MIN_10_EXP__", "(-37)");
238 Define(Defs, "__FLT_MIN_EXP__", "(-125)");
239 Define(Defs, "__FLT_MIN__", "1.17549435e-38F");
240 Define(Defs, "__FLT_RADIX__", "2");
Reid Spencer5f016e22007-07-11 17:01:13 +0000241
242 // Double macros.
Chris Lattnerd15fa822007-10-06 06:57:34 +0000243 Define(Defs, "__DBL_DENORM_MIN__", "4.9406564584124654e-324");
244 Define(Defs, "__DBL_DIG__", "15");
245 Define(Defs, "__DBL_EPSILON__", "2.2204460492503131e-16");
246 Define(Defs, "__DBL_HAS_INFINITY__");
247 Define(Defs, "__DBL_HAS_QUIET_NAN__");
248 Define(Defs, "__DBL_MANT_DIG__", "53");
249 Define(Defs, "__DBL_MAX_10_EXP__", "308");
250 Define(Defs, "__DBL_MAX_EXP__", "1024");
251 Define(Defs, "__DBL_MAX__", "1.7976931348623157e+308");
252 Define(Defs, "__DBL_MIN_10_EXP__", "(-307)");
253 Define(Defs, "__DBL_MIN_EXP__", "(-1021)");
254 Define(Defs, "__DBL_MIN__", "2.2250738585072014e-308");
255 Define(Defs, "__DECIMAL_DIG__", "21");
Reid Spencer5f016e22007-07-11 17:01:13 +0000256
257 // 80-bit Long double macros.
Chris Lattnerd15fa822007-10-06 06:57:34 +0000258 Define(Defs, "__LDBL_DENORM_MIN__", "3.64519953188247460253e-4951L");
259 Define(Defs, "__LDBL_DIG__", "18");
260 Define(Defs, "__LDBL_EPSILON__", "1.08420217248550443401e-19L");
261 Define(Defs, "__LDBL_HAS_INFINITY__");
262 Define(Defs, "__LDBL_HAS_QUIET_NAN__");
263 Define(Defs, "__LDBL_MANT_DIG__", "64");
264 Define(Defs, "__LDBL_MAX_10_EXP__", "4932");
265 Define(Defs, "__LDBL_MAX_EXP__", "16384");
266 Define(Defs, "__LDBL_MAX__", "1.18973149535723176502e+4932L");
267 Define(Defs, "__LDBL_MIN_10_EXP__", "(-4931)");
268 Define(Defs, "__LDBL_MIN_EXP__", "(-16381)");
269 Define(Defs, "__LDBL_MIN__", "3.36210314311209350626e-4932L");
Reid Spencer5f016e22007-07-11 17:01:13 +0000270}
271
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000272static const char* getI386VAListDeclaration() {
273 return "typedef char* __builtin_va_list;";
274}
275
276static const char* getX86_64VAListDeclaration() {
277 return
278 "typedef struct __va_list_tag {"
279 " unsigned gp_offset;"
280 " unsigned fp_offset;"
281 " void* overflow_arg_area;"
282 " void* reg_save_area;"
283 "} __builtin_va_list[1];";
284}
285
286static const char* getPPCVAListDeclaration() {
287 return
288 "typedef struct __va_list_tag {"
289 " unsigned char gpr;"
290 " unsigned char fpr;"
291 " unsigned short reserved;"
292 " void* overflow_arg_area;"
293 " void* reg_save_area;"
294 "} __builtin_va_list[1];";
295}
296
297
Reid Spencer5f016e22007-07-11 17:01:13 +0000298/// PPC builtin info.
Chris Lattnerfb344d32007-12-11 04:36:28 +0000299namespace clang {
Reid Spencer5f016e22007-07-11 17:01:13 +0000300namespace PPC {
Reid Spencer5f016e22007-07-11 17:01:13 +0000301
302 static const Builtin::Info BuiltinInfo[] = {
303#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
Anders Carlsson564f1de2007-12-09 23:17:02 +0000304#include "clang/AST/PPCBuiltins.def"
Reid Spencer5f016e22007-07-11 17:01:13 +0000305 };
306
307 static void getBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) {
308 Records = BuiltinInfo;
309 NumRecords = LastTSBuiltin-Builtin::FirstTSBuiltin;
310 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000311
312 static const char * const GCCRegNames[] = {
313 "0", "1", "2", "3", "4", "5", "6", "7",
314 "8", "9", "10", "11", "12", "13", "14", "15",
315 "16", "17", "18", "19", "20", "21", "22", "23",
316 "24", "25", "26", "27", "28", "29", "30", "31",
317 "0", "1", "2", "3", "4", "5", "6", "7",
318 "8", "9", "10", "11", "12", "13", "14", "15",
319 "16", "17", "18", "19", "20", "21", "22", "23",
320 "24", "25", "26", "27", "28", "29", "30", "31",
321 "mq", "lr", "ctr", "ap",
322 "0", "1", "2", "3", "4", "5", "6", "7",
323 "xer",
324 "0", "1", "2", "3", "4", "5", "6", "7",
325 "8", "9", "10", "11", "12", "13", "14", "15",
326 "16", "17", "18", "19", "20", "21", "22", "23",
327 "24", "25", "26", "27", "28", "29", "30", "31",
328 "vrsave", "vscr",
329 "spe_acc", "spefscr",
330 "sfp"
331 };
332
333 static void getGCCRegNames(const char * const *&Names,
334 unsigned &NumNames) {
335 Names = GCCRegNames;
336 NumNames = llvm::array_lengthof(GCCRegNames);
337 }
338
339 static const TargetInfoImpl::GCCRegAlias GCCRegAliases[] = {
340 // While some of these aliases do map to different registers
341 // they still share the same register name.
342 { { "cc", "cr0", "fr0", "r0", "v0"}, "0" },
343 { { "cr1", "fr1", "r1", "sp", "v1"}, "1" },
344 { { "cr2", "fr2", "r2", "toc", "v2"}, "2" },
345 { { "cr3", "fr3", "r3", "v3"}, "3" },
346 { { "cr4", "fr4", "r4", "v4"}, "4" },
347 { { "cr5", "fr5", "r5", "v5"}, "5" },
348 { { "cr6", "fr6", "r6", "v6"}, "6" },
349 { { "cr7", "fr7", "r7", "v7"}, "7" },
350 { { "fr8", "r8", "v8"}, "8" },
351 { { "fr9", "r9", "v9"}, "9" },
352 { { "fr10", "r10", "v10"}, "10" },
353 { { "fr11", "r11", "v11"}, "11" },
354 { { "fr12", "r12", "v12"}, "12" },
355 { { "fr13", "r13", "v13"}, "13" },
356 { { "fr14", "r14", "v14"}, "14" },
357 { { "fr15", "r15", "v15"}, "15" },
358 { { "fr16", "r16", "v16"}, "16" },
359 { { "fr17", "r17", "v17"}, "17" },
360 { { "fr18", "r18", "v18"}, "18" },
361 { { "fr19", "r19", "v19"}, "19" },
362 { { "fr20", "r20", "v20"}, "20" },
363 { { "fr21", "r21", "v21"}, "21" },
364 { { "fr22", "r22", "v22"}, "22" },
365 { { "fr23", "r23", "v23"}, "23" },
366 { { "fr24", "r24", "v24"}, "24" },
367 { { "fr25", "r25", "v25"}, "25" },
368 { { "fr26", "r26", "v26"}, "26" },
369 { { "fr27", "r27", "v27"}, "27" },
370 { { "fr28", "r28", "v28"}, "28" },
371 { { "fr29", "r29", "v29"}, "29" },
372 { { "fr30", "r30", "v30"}, "30" },
373 { { "fr31", "r31", "v31"}, "31" },
374 };
375
376 static void getGCCRegAliases(const TargetInfoImpl::GCCRegAlias *&Aliases,
377 unsigned &NumAliases) {
378 Aliases = GCCRegAliases;
379 NumAliases = llvm::array_lengthof(GCCRegAliases);
Anders Carlssond04c6e22007-11-27 04:11:28 +0000380 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000381
Anders Carlssond04c6e22007-11-27 04:11:28 +0000382 static bool validateAsmConstraint(char c,
383 TargetInfo::ConstraintInfo &info) {
384 switch (c) {
385 default: return false;
386 case 'O': // Zero
387 return true;
388 case 'b': // Base register
389 case 'f': // Floating point register
390 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
391 return true;
392 }
393 }
394
395 const char *getClobbers() {
396 return 0;
397 }
398
Anders Carlsson44fe49c2007-12-08 19:32:57 +0000399 const char *getTargetPrefix() {
400 return "ppc";
401 }
402
Reid Spencer5f016e22007-07-11 17:01:13 +0000403} // End namespace PPC
404
Reid Spencer5f016e22007-07-11 17:01:13 +0000405/// X86 builtin info.
406namespace X86 {
Reid Spencer5f016e22007-07-11 17:01:13 +0000407 static const Builtin::Info BuiltinInfo[] = {
408#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
Anders Carlsson564f1de2007-12-09 23:17:02 +0000409#include "clang/AST/X86Builtins.def"
Reid Spencer5f016e22007-07-11 17:01:13 +0000410 };
411
412 static void getBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) {
413 Records = BuiltinInfo;
414 NumRecords = LastTSBuiltin-Builtin::FirstTSBuiltin;
415 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000416
417 static const char *GCCRegNames[] = {
418 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
419 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
Anders Carlsson646b2612007-11-25 00:23:10 +0000420 "argp", "flags", "fspr", "dirflag", "frame",
Anders Carlsson3346ae62007-11-24 23:38:12 +0000421 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
422 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
423 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
424 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
425 };
426
427 static void getGCCRegNames(const char * const *&Names,
428 unsigned &NumNames) {
429 Names = GCCRegNames;
430 NumNames = llvm::array_lengthof(GCCRegNames);
431 }
432
433 static const TargetInfoImpl::GCCRegAlias GCCRegAliases[] = {
434 { { "al", "ah", "eax", "rax" }, "ax" },
435 { { "bl", "bh", "ebx", "rbx" }, "bx" },
436 { { "cl", "ch", "ecx", "rcx" }, "cx" },
437 { { "dl", "dh", "edx", "rdx" }, "dx" },
438 { { "esi", "rsi" }, "si" },
439 { { "esp", "rsp" }, "sp" },
440 { { "ebp", "rbp" }, "bp" },
441 };
442
443 static void getGCCRegAliases(const TargetInfoImpl::GCCRegAlias *&Aliases,
444 unsigned &NumAliases) {
445 Aliases = GCCRegAliases;
446 NumAliases = llvm::array_lengthof(GCCRegAliases);
447 }
448
Anders Carlssond04c6e22007-11-27 04:11:28 +0000449 static bool validateAsmConstraint(char c,
450 TargetInfo::ConstraintInfo &info) {
451 switch (c) {
452 default: return false;
453 case 'a': // eax.
454 case 'b': // ebx.
455 case 'c': // ecx.
456 case 'd': // edx.
457 case 'S': // esi.
458 case 'D': // edi.
459 case 'A': // edx:eax.
460 case 't': // top of floating point stack.
461 case 'u': // second from top of floating point stack.
462 case 'q': // a, b, c, d registers or any integer register in 64-bit.
463 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
464 return true;
465 }
466 }
467
468 const char *getClobbers() {
469 return "~{dirflag},~{fpsr},~{flags}";
470 }
471
Anders Carlsson44fe49c2007-12-08 19:32:57 +0000472 const char *getTargetPrefix() {
473 return "x86";
474 }
475
Reid Spencer5f016e22007-07-11 17:01:13 +0000476} // End namespace X86
Chris Lattnerfb344d32007-12-11 04:36:28 +0000477} // end namespace clang.
Reid Spencer5f016e22007-07-11 17:01:13 +0000478
479//===----------------------------------------------------------------------===//
480// Specific target implementations.
481//===----------------------------------------------------------------------===//
482
483
484namespace {
485class DarwinPPCTargetInfo : public DarwinTargetInfo {
486public:
Ted Kremenekae360762007-12-03 22:06:55 +0000487 DarwinPPCTargetInfo(const std::string& triple) : DarwinTargetInfo(triple) {}
488
Chris Lattnerd15fa822007-10-06 06:57:34 +0000489 virtual void getTargetDefines(std::vector<char> &Defines) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000490 DarwinTargetInfo::getTargetDefines(Defines);
491 getPowerPCDefines(Defines, false);
492 }
493 virtual void getTargetBuiltins(const Builtin::Info *&Records,
494 unsigned &NumRecords) const {
495 PPC::getBuiltins(Records, NumRecords);
496 }
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000497 virtual const char *getVAListDeclaration() const {
498 return getPPCVAListDeclaration();
Anders Carlsson3346ae62007-11-24 23:38:12 +0000499 }
Anders Carlsson44fe49c2007-12-08 19:32:57 +0000500 virtual const char *getTargetPrefix() const {
501 return PPC::getTargetPrefix();
502 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000503 virtual void getGCCRegNames(const char * const *&Names,
504 unsigned &NumNames) const {
505 PPC::getGCCRegNames(Names, NumNames);
506 }
507 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
508 unsigned &NumAliases) const {
509 PPC::getGCCRegAliases(Aliases, NumAliases);
510 }
Anders Carlssond04c6e22007-11-27 04:11:28 +0000511 virtual bool validateAsmConstraint(char c,
512 TargetInfo::ConstraintInfo &info) const {
513 return PPC::validateAsmConstraint(c, info);
514 }
515 virtual const char *getClobbers() const {
516 return PPC::getClobbers();
517 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000518};
519} // end anonymous namespace.
520
521namespace {
522class DarwinPPC64TargetInfo : public DarwinTargetInfo {
523public:
Ted Kremenekae360762007-12-03 22:06:55 +0000524 DarwinPPC64TargetInfo(const std::string& triple) : DarwinTargetInfo(triple) {}
525
Chris Lattnerd15fa822007-10-06 06:57:34 +0000526 virtual void getTargetDefines(std::vector<char> &Defines) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000527 DarwinTargetInfo::getTargetDefines(Defines);
528 getPowerPCDefines(Defines, true);
529 }
530 virtual void getTargetBuiltins(const Builtin::Info *&Records,
531 unsigned &NumRecords) const {
532 PPC::getBuiltins(Records, NumRecords);
533 }
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000534 virtual const char *getVAListDeclaration() const {
535 return getPPCVAListDeclaration();
536 }
Anders Carlsson44fe49c2007-12-08 19:32:57 +0000537 virtual const char *getTargetPrefix() const {
538 return PPC::getTargetPrefix();
539 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000540 virtual void getGCCRegNames(const char * const *&Names,
541 unsigned &NumNames) const {
542 PPC::getGCCRegNames(Names, NumNames);
543 }
544 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
545 unsigned &NumAliases) const {
546 PPC::getGCCRegAliases(Aliases, NumAliases);
547 }
Anders Carlssond04c6e22007-11-27 04:11:28 +0000548 virtual bool validateAsmConstraint(char c,
549 TargetInfo::ConstraintInfo &info) const {
550 return PPC::validateAsmConstraint(c, info);
551 }
552 virtual const char *getClobbers() const {
553 return PPC::getClobbers();
554 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000555};
556} // end anonymous namespace.
557
558namespace {
559class DarwinI386TargetInfo : public DarwinTargetInfo {
560public:
Ted Kremenekae360762007-12-03 22:06:55 +0000561 DarwinI386TargetInfo(const std::string& triple) : DarwinTargetInfo(triple) {}
562
Chris Lattnerd15fa822007-10-06 06:57:34 +0000563 virtual void getTargetDefines(std::vector<char> &Defines) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000564 DarwinTargetInfo::getTargetDefines(Defines);
565 getX86Defines(Defines, false);
566 }
567 virtual void getTargetBuiltins(const Builtin::Info *&Records,
568 unsigned &NumRecords) const {
569 X86::getBuiltins(Records, NumRecords);
570 }
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000571 virtual const char *getVAListDeclaration() const {
572 return getI386VAListDeclaration();
Anders Carlsson3346ae62007-11-24 23:38:12 +0000573 }
Anders Carlsson44fe49c2007-12-08 19:32:57 +0000574 virtual const char *getTargetPrefix() const {
575 return X86::getTargetPrefix();
576 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000577 virtual void getGCCRegNames(const char * const *&Names,
578 unsigned &NumNames) const {
579 X86::getGCCRegNames(Names, NumNames);
580 }
581 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
582 unsigned &NumAliases) const {
583 X86::getGCCRegAliases(Aliases, NumAliases);
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000584 }
Anders Carlssond04c6e22007-11-27 04:11:28 +0000585 virtual bool validateAsmConstraint(char c,
586 TargetInfo::ConstraintInfo &info) const {
587 return X86::validateAsmConstraint(c, info);
588 }
589 virtual const char *getClobbers() const {
590 return X86::getClobbers();
591 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000592};
593} // end anonymous namespace.
594
595namespace {
596class DarwinX86_64TargetInfo : public DarwinTargetInfo {
597public:
Ted Kremenekae360762007-12-03 22:06:55 +0000598 DarwinX86_64TargetInfo(const std::string& triple) :DarwinTargetInfo(triple) {}
599
Chris Lattnerd15fa822007-10-06 06:57:34 +0000600 virtual void getTargetDefines(std::vector<char> &Defines) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000601 DarwinTargetInfo::getTargetDefines(Defines);
602 getX86Defines(Defines, true);
603 }
604 virtual void getTargetBuiltins(const Builtin::Info *&Records,
605 unsigned &NumRecords) const {
606 X86::getBuiltins(Records, NumRecords);
607 }
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000608 virtual const char *getVAListDeclaration() const {
609 return getX86_64VAListDeclaration();
Anders Carlsson3346ae62007-11-24 23:38:12 +0000610 }
Anders Carlsson44fe49c2007-12-08 19:32:57 +0000611 virtual const char *getTargetPrefix() const {
612 return X86::getTargetPrefix();
613 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000614 virtual void getGCCRegNames(const char * const *&Names,
615 unsigned &NumNames) const {
616 X86::getGCCRegNames(Names, NumNames);
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000617 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000618 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
619 unsigned &NumAliases) const {
620 X86::getGCCRegAliases(Aliases, NumAliases);
621 }
Anders Carlssond04c6e22007-11-27 04:11:28 +0000622 virtual bool validateAsmConstraint(char c,
623 TargetInfo::ConstraintInfo &info) const {
624 return X86::validateAsmConstraint(c, info);
625 }
626 virtual const char *getClobbers() const {
627 return X86::getClobbers();
628 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000629};
630} // end anonymous namespace.
631
632namespace {
633class LinuxTargetInfo : public DarwinTargetInfo {
634public:
Ted Kremenekae360762007-12-03 22:06:55 +0000635 LinuxTargetInfo(const std::string& triple) : DarwinTargetInfo(triple) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000636 // Note: I have no idea if this is right, just for testing.
637 WCharWidth = 16;
Chris Lattnerd2d2a112007-07-14 01:29:45 +0000638 WCharAlign = 16;
Reid Spencer5f016e22007-07-11 17:01:13 +0000639 }
640
Chris Lattnerd15fa822007-10-06 06:57:34 +0000641 virtual void getTargetDefines(std::vector<char> &Defines) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000642 // TODO: linux-specific stuff.
643 getX86Defines(Defines, false);
644 }
645 virtual void getTargetBuiltins(const Builtin::Info *&Records,
646 unsigned &NumRecords) const {
647 X86::getBuiltins(Records, NumRecords);
648 }
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000649 virtual const char *getVAListDeclaration() const {
650 return getI386VAListDeclaration();
Anders Carlsson3346ae62007-11-24 23:38:12 +0000651 }
Anders Carlsson44fe49c2007-12-08 19:32:57 +0000652 virtual const char *getTargetPrefix() const {
653 return X86::getTargetPrefix();
654 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000655 virtual void getGCCRegNames(const char * const *&Names,
656 unsigned &NumNames) const {
657 X86::getGCCRegNames(Names, NumNames);
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000658 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000659 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
660 unsigned &NumAliases) const {
661 X86::getGCCRegAliases(Aliases, NumAliases);
662 }
Anders Carlssond04c6e22007-11-27 04:11:28 +0000663 virtual bool validateAsmConstraint(char c,
664 TargetInfo::ConstraintInfo &info) const {
665 return X86::validateAsmConstraint(c, info);
666 }
667 virtual const char *getClobbers() const {
668 return X86::getClobbers();
669 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000670};
671} // end anonymous namespace.
672
673
674//===----------------------------------------------------------------------===//
675// Driver code
676//===----------------------------------------------------------------------===//
677
Ted Kremenek8448d382007-12-04 17:07:35 +0000678static inline bool IsX86(const std::string& TT) {
Ted Kremenekae360762007-12-03 22:06:55 +0000679 return (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' &&
680 TT[4] == '-' && TT[1] - '3' < 6);
681}
682
Reid Spencer5f016e22007-07-11 17:01:13 +0000683/// CreateTarget - Create the TargetInfoImpl object for the specified target
684/// enum value.
Ted Kremenekae360762007-12-03 22:06:55 +0000685static TargetInfoImpl *CreateTarget(const std::string& T) {
Chris Lattner82817ba2007-12-05 18:41:05 +0000686 if (T.find("ppc-") == 0 || T.find("powerpc-") == 0)
Ted Kremenek8448d382007-12-04 17:07:35 +0000687 return new DarwinPPCTargetInfo(T);
Chris Lattner82817ba2007-12-05 18:41:05 +0000688 else if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0)
Ted Kremenek8448d382007-12-04 17:07:35 +0000689 return new DarwinPPC64TargetInfo(T);
690 else if (T.find("x86_64-") == 0)
691 return new DarwinX86_64TargetInfo(T);
692 else if (IsX86(T))
693 return new DarwinI386TargetInfo(T);
694 else if (T.find("bogusW16W16-") == 0) // For testing portability.
695 return new LinuxTargetInfo(T);
696 else
697 return NULL;
Reid Spencer5f016e22007-07-11 17:01:13 +0000698}
699
700/// CreateTargetInfo - Return the set of target info objects as specified by
701/// the -arch command line option.
Ted Kremenek9c728dc2007-12-12 22:39:36 +0000702TargetInfo* TargetInfo::CreateTargetInfo(const std::string* TriplesStart,
Ted Kremenekbbced582007-12-12 18:05:32 +0000703 const std::string* TriplesEnd,
704 Diagnostic *Diags) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000705
706 // Create the primary target and target info.
Ted Kremenekbbced582007-12-12 18:05:32 +0000707 TargetInfoImpl* PrimaryTarget = CreateTarget(*TriplesStart);
Ted Kremenekaead4722007-12-03 23:23:21 +0000708
709 if (!PrimaryTarget)
710 return NULL;
711
Ted Kremenek9c728dc2007-12-12 22:39:36 +0000712 TargetInfo *TI = new TargetInfo(PrimaryTarget, Diags);
Reid Spencer5f016e22007-07-11 17:01:13 +0000713
714 // Add all secondary targets.
Ted Kremenekbbced582007-12-12 18:05:32 +0000715 for (const std::string* I=TriplesStart+1; I != TriplesEnd; ++I) {
716 TargetInfoImpl* SecondaryTarget = CreateTarget(*I);
Ted Kremenekaead4722007-12-03 23:23:21 +0000717
718 if (!SecondaryTarget) {
Ted Kremenekbbced582007-12-12 18:05:32 +0000719 fprintf (stderr,
720 "Warning: secondary target '%s' unrecognized.\n",
721 I->c_str());
722
Ted Kremenekaead4722007-12-03 23:23:21 +0000723 continue;
724 }
725
Ted Kremenekbbced582007-12-12 18:05:32 +0000726 TI->AddSecondaryTarget(SecondaryTarget);
Ted Kremenekaead4722007-12-03 23:23:21 +0000727 }
Ted Kremenekae360762007-12-03 22:06:55 +0000728
Reid Spencer5f016e22007-07-11 17:01:13 +0000729 return TI;
730}