blob: afe6e74f6663b095ae048b410fdcdd850d195f4a [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");
Lauro Ramos Venancioe0e3abc2008-01-20 04:02:16 +0000197 Define(Defs, "__SIZE_TYPE__", "long unsigned int");
Reid Spencer5f016e22007-07-11 17:01:13 +0000198 } else {
Chris Lattnerd15fa822007-10-06 06:57:34 +0000199 Define(Defs, "__INTMAX_MAX__", "9223372036854775807LL");
200 Define(Defs, "__INTMAX_TYPE__", "long long int");
201 Define(Defs, "__LONG_MAX__", "2147483647L");
202 Define(Defs, "__PTRDIFF_TYPE__", "int");
203 Define(Defs, "__UINTMAX_TYPE__", "long long unsigned int");
Lauro Ramos Venancioe0e3abc2008-01-20 04:02:16 +0000204 Define(Defs, "__SIZE_TYPE__", "unsigned int");
Reid Spencer5f016e22007-07-11 17:01:13 +0000205 }
Chris Lattnerd15fa822007-10-06 06:57:34 +0000206 Define(Defs, "__CHAR_BIT__", "8");
207 Define(Defs, "__INT_MAX__", "2147483647");
208 Define(Defs, "__LONG_LONG_MAX__", "9223372036854775807LL");
209 Define(Defs, "__SCHAR_MAX__", "127");
210 Define(Defs, "__SHRT_MAX__", "32767");
Reid Spencer5f016e22007-07-11 17:01:13 +0000211
212 // Subtarget options.
Chris Lattnerd15fa822007-10-06 06:57:34 +0000213 Define(Defs, "__nocona");
214 Define(Defs, "__nocona__");
215 Define(Defs, "__tune_nocona__");
216 Define(Defs, "__SSE2_MATH__");
217 Define(Defs, "__SSE2__");
218 Define(Defs, "__SSE_MATH__");
219 Define(Defs, "__SSE__");
220 Define(Defs, "__MMX__");
221 Define(Defs, "__REGISTER_PREFIX__", "");
Reid Spencer5f016e22007-07-11 17:01:13 +0000222
Chris Lattnerd15fa822007-10-06 06:57:34 +0000223 Define(Defs, "__WCHAR_MAX__", "2147483647");
224 Define(Defs, "__WCHAR_TYPE__", "int");
225 Define(Defs, "__WINT_TYPE__", "int");
Reid Spencer5f016e22007-07-11 17:01:13 +0000226
227 // Float macros.
Chris Lattnerd15fa822007-10-06 06:57:34 +0000228 Define(Defs, "__FLT_DENORM_MIN__", "1.40129846e-45F");
229 Define(Defs, "__FLT_DIG__", "6");
230 Define(Defs, "__FLT_EPSILON__", "1.19209290e-7F");
231 Define(Defs, "__FLT_EVAL_METHOD__", "0");
232 Define(Defs, "__FLT_HAS_INFINITY__");
233 Define(Defs, "__FLT_HAS_QUIET_NAN__");
234 Define(Defs, "__FLT_MANT_DIG__", "24");
235 Define(Defs, "__FLT_MAX_10_EXP__", "38");
236 Define(Defs, "__FLT_MAX_EXP__", "128");
237 Define(Defs, "__FLT_MAX__", "3.40282347e+38F");
238 Define(Defs, "__FLT_MIN_10_EXP__", "(-37)");
239 Define(Defs, "__FLT_MIN_EXP__", "(-125)");
240 Define(Defs, "__FLT_MIN__", "1.17549435e-38F");
241 Define(Defs, "__FLT_RADIX__", "2");
Reid Spencer5f016e22007-07-11 17:01:13 +0000242
243 // Double macros.
Chris Lattnerd15fa822007-10-06 06:57:34 +0000244 Define(Defs, "__DBL_DENORM_MIN__", "4.9406564584124654e-324");
245 Define(Defs, "__DBL_DIG__", "15");
246 Define(Defs, "__DBL_EPSILON__", "2.2204460492503131e-16");
247 Define(Defs, "__DBL_HAS_INFINITY__");
248 Define(Defs, "__DBL_HAS_QUIET_NAN__");
249 Define(Defs, "__DBL_MANT_DIG__", "53");
250 Define(Defs, "__DBL_MAX_10_EXP__", "308");
251 Define(Defs, "__DBL_MAX_EXP__", "1024");
252 Define(Defs, "__DBL_MAX__", "1.7976931348623157e+308");
253 Define(Defs, "__DBL_MIN_10_EXP__", "(-307)");
254 Define(Defs, "__DBL_MIN_EXP__", "(-1021)");
255 Define(Defs, "__DBL_MIN__", "2.2250738585072014e-308");
256 Define(Defs, "__DECIMAL_DIG__", "21");
Reid Spencer5f016e22007-07-11 17:01:13 +0000257
258 // 80-bit Long double macros.
Chris Lattnerd15fa822007-10-06 06:57:34 +0000259 Define(Defs, "__LDBL_DENORM_MIN__", "3.64519953188247460253e-4951L");
260 Define(Defs, "__LDBL_DIG__", "18");
261 Define(Defs, "__LDBL_EPSILON__", "1.08420217248550443401e-19L");
262 Define(Defs, "__LDBL_HAS_INFINITY__");
263 Define(Defs, "__LDBL_HAS_QUIET_NAN__");
264 Define(Defs, "__LDBL_MANT_DIG__", "64");
265 Define(Defs, "__LDBL_MAX_10_EXP__", "4932");
266 Define(Defs, "__LDBL_MAX_EXP__", "16384");
267 Define(Defs, "__LDBL_MAX__", "1.18973149535723176502e+4932L");
268 Define(Defs, "__LDBL_MIN_10_EXP__", "(-4931)");
269 Define(Defs, "__LDBL_MIN_EXP__", "(-16381)");
270 Define(Defs, "__LDBL_MIN__", "3.36210314311209350626e-4932L");
Reid Spencer5f016e22007-07-11 17:01:13 +0000271}
272
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000273static const char* getI386VAListDeclaration() {
274 return "typedef char* __builtin_va_list;";
275}
276
277static const char* getX86_64VAListDeclaration() {
278 return
279 "typedef struct __va_list_tag {"
280 " unsigned gp_offset;"
281 " unsigned fp_offset;"
282 " void* overflow_arg_area;"
283 " void* reg_save_area;"
284 "} __builtin_va_list[1];";
285}
286
287static const char* getPPCVAListDeclaration() {
288 return
289 "typedef struct __va_list_tag {"
290 " unsigned char gpr;"
291 " unsigned char fpr;"
292 " unsigned short reserved;"
293 " void* overflow_arg_area;"
294 " void* reg_save_area;"
295 "} __builtin_va_list[1];";
296}
297
298
Reid Spencer5f016e22007-07-11 17:01:13 +0000299/// PPC builtin info.
Chris Lattnerfb344d32007-12-11 04:36:28 +0000300namespace clang {
Reid Spencer5f016e22007-07-11 17:01:13 +0000301namespace PPC {
Reid Spencer5f016e22007-07-11 17:01:13 +0000302
303 static const Builtin::Info BuiltinInfo[] = {
304#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
Anders Carlsson564f1de2007-12-09 23:17:02 +0000305#include "clang/AST/PPCBuiltins.def"
Reid Spencer5f016e22007-07-11 17:01:13 +0000306 };
307
308 static void getBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) {
309 Records = BuiltinInfo;
310 NumRecords = LastTSBuiltin-Builtin::FirstTSBuiltin;
311 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000312
313 static const char * const GCCRegNames[] = {
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 "0", "1", "2", "3", "4", "5", "6", "7",
319 "8", "9", "10", "11", "12", "13", "14", "15",
320 "16", "17", "18", "19", "20", "21", "22", "23",
321 "24", "25", "26", "27", "28", "29", "30", "31",
322 "mq", "lr", "ctr", "ap",
323 "0", "1", "2", "3", "4", "5", "6", "7",
324 "xer",
325 "0", "1", "2", "3", "4", "5", "6", "7",
326 "8", "9", "10", "11", "12", "13", "14", "15",
327 "16", "17", "18", "19", "20", "21", "22", "23",
328 "24", "25", "26", "27", "28", "29", "30", "31",
329 "vrsave", "vscr",
330 "spe_acc", "spefscr",
331 "sfp"
332 };
333
334 static void getGCCRegNames(const char * const *&Names,
335 unsigned &NumNames) {
336 Names = GCCRegNames;
337 NumNames = llvm::array_lengthof(GCCRegNames);
338 }
339
340 static const TargetInfoImpl::GCCRegAlias GCCRegAliases[] = {
341 // While some of these aliases do map to different registers
342 // they still share the same register name.
343 { { "cc", "cr0", "fr0", "r0", "v0"}, "0" },
344 { { "cr1", "fr1", "r1", "sp", "v1"}, "1" },
345 { { "cr2", "fr2", "r2", "toc", "v2"}, "2" },
346 { { "cr3", "fr3", "r3", "v3"}, "3" },
347 { { "cr4", "fr4", "r4", "v4"}, "4" },
348 { { "cr5", "fr5", "r5", "v5"}, "5" },
349 { { "cr6", "fr6", "r6", "v6"}, "6" },
350 { { "cr7", "fr7", "r7", "v7"}, "7" },
351 { { "fr8", "r8", "v8"}, "8" },
352 { { "fr9", "r9", "v9"}, "9" },
353 { { "fr10", "r10", "v10"}, "10" },
354 { { "fr11", "r11", "v11"}, "11" },
355 { { "fr12", "r12", "v12"}, "12" },
356 { { "fr13", "r13", "v13"}, "13" },
357 { { "fr14", "r14", "v14"}, "14" },
358 { { "fr15", "r15", "v15"}, "15" },
359 { { "fr16", "r16", "v16"}, "16" },
360 { { "fr17", "r17", "v17"}, "17" },
361 { { "fr18", "r18", "v18"}, "18" },
362 { { "fr19", "r19", "v19"}, "19" },
363 { { "fr20", "r20", "v20"}, "20" },
364 { { "fr21", "r21", "v21"}, "21" },
365 { { "fr22", "r22", "v22"}, "22" },
366 { { "fr23", "r23", "v23"}, "23" },
367 { { "fr24", "r24", "v24"}, "24" },
368 { { "fr25", "r25", "v25"}, "25" },
369 { { "fr26", "r26", "v26"}, "26" },
370 { { "fr27", "r27", "v27"}, "27" },
371 { { "fr28", "r28", "v28"}, "28" },
372 { { "fr29", "r29", "v29"}, "29" },
373 { { "fr30", "r30", "v30"}, "30" },
374 { { "fr31", "r31", "v31"}, "31" },
375 };
376
377 static void getGCCRegAliases(const TargetInfoImpl::GCCRegAlias *&Aliases,
378 unsigned &NumAliases) {
379 Aliases = GCCRegAliases;
380 NumAliases = llvm::array_lengthof(GCCRegAliases);
Anders Carlssond04c6e22007-11-27 04:11:28 +0000381 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000382
Anders Carlssond04c6e22007-11-27 04:11:28 +0000383 static bool validateAsmConstraint(char c,
384 TargetInfo::ConstraintInfo &info) {
385 switch (c) {
386 default: return false;
387 case 'O': // Zero
388 return true;
389 case 'b': // Base register
390 case 'f': // Floating point register
391 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
392 return true;
393 }
394 }
395
396 const char *getClobbers() {
397 return 0;
398 }
399
Anders Carlsson44fe49c2007-12-08 19:32:57 +0000400 const char *getTargetPrefix() {
401 return "ppc";
402 }
403
Reid Spencer5f016e22007-07-11 17:01:13 +0000404} // End namespace PPC
405
Reid Spencer5f016e22007-07-11 17:01:13 +0000406/// X86 builtin info.
407namespace X86 {
Reid Spencer5f016e22007-07-11 17:01:13 +0000408 static const Builtin::Info BuiltinInfo[] = {
409#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
Anders Carlsson564f1de2007-12-09 23:17:02 +0000410#include "clang/AST/X86Builtins.def"
Reid Spencer5f016e22007-07-11 17:01:13 +0000411 };
412
413 static void getBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) {
414 Records = BuiltinInfo;
415 NumRecords = LastTSBuiltin-Builtin::FirstTSBuiltin;
416 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000417
418 static const char *GCCRegNames[] = {
419 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
420 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
Anders Carlsson646b2612007-11-25 00:23:10 +0000421 "argp", "flags", "fspr", "dirflag", "frame",
Anders Carlsson3346ae62007-11-24 23:38:12 +0000422 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
423 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
424 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
425 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
426 };
427
428 static void getGCCRegNames(const char * const *&Names,
429 unsigned &NumNames) {
430 Names = GCCRegNames;
431 NumNames = llvm::array_lengthof(GCCRegNames);
432 }
433
434 static const TargetInfoImpl::GCCRegAlias GCCRegAliases[] = {
435 { { "al", "ah", "eax", "rax" }, "ax" },
436 { { "bl", "bh", "ebx", "rbx" }, "bx" },
437 { { "cl", "ch", "ecx", "rcx" }, "cx" },
438 { { "dl", "dh", "edx", "rdx" }, "dx" },
439 { { "esi", "rsi" }, "si" },
440 { { "esp", "rsp" }, "sp" },
441 { { "ebp", "rbp" }, "bp" },
442 };
443
444 static void getGCCRegAliases(const TargetInfoImpl::GCCRegAlias *&Aliases,
445 unsigned &NumAliases) {
446 Aliases = GCCRegAliases;
447 NumAliases = llvm::array_lengthof(GCCRegAliases);
448 }
449
Anders Carlssond04c6e22007-11-27 04:11:28 +0000450 static bool validateAsmConstraint(char c,
451 TargetInfo::ConstraintInfo &info) {
452 switch (c) {
453 default: return false;
454 case 'a': // eax.
455 case 'b': // ebx.
456 case 'c': // ecx.
457 case 'd': // edx.
458 case 'S': // esi.
459 case 'D': // edi.
460 case 'A': // edx:eax.
461 case 't': // top of floating point stack.
462 case 'u': // second from top of floating point stack.
463 case 'q': // a, b, c, d registers or any integer register in 64-bit.
464 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
465 return true;
466 }
467 }
468
469 const char *getClobbers() {
470 return "~{dirflag},~{fpsr},~{flags}";
471 }
472
Anders Carlsson44fe49c2007-12-08 19:32:57 +0000473 const char *getTargetPrefix() {
474 return "x86";
475 }
476
Reid Spencer5f016e22007-07-11 17:01:13 +0000477} // End namespace X86
Chris Lattnerfb344d32007-12-11 04:36:28 +0000478} // end namespace clang.
Reid Spencer5f016e22007-07-11 17:01:13 +0000479
480//===----------------------------------------------------------------------===//
481// Specific target implementations.
482//===----------------------------------------------------------------------===//
483
484
485namespace {
486class DarwinPPCTargetInfo : public DarwinTargetInfo {
487public:
Ted Kremenekae360762007-12-03 22:06:55 +0000488 DarwinPPCTargetInfo(const std::string& triple) : DarwinTargetInfo(triple) {}
489
Chris Lattnerd15fa822007-10-06 06:57:34 +0000490 virtual void getTargetDefines(std::vector<char> &Defines) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000491 DarwinTargetInfo::getTargetDefines(Defines);
492 getPowerPCDefines(Defines, false);
493 }
494 virtual void getTargetBuiltins(const Builtin::Info *&Records,
495 unsigned &NumRecords) const {
496 PPC::getBuiltins(Records, NumRecords);
497 }
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000498 virtual const char *getVAListDeclaration() const {
499 return getPPCVAListDeclaration();
Anders Carlsson3346ae62007-11-24 23:38:12 +0000500 }
Anders Carlsson44fe49c2007-12-08 19:32:57 +0000501 virtual const char *getTargetPrefix() const {
502 return PPC::getTargetPrefix();
503 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000504 virtual void getGCCRegNames(const char * const *&Names,
505 unsigned &NumNames) const {
506 PPC::getGCCRegNames(Names, NumNames);
507 }
508 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
509 unsigned &NumAliases) const {
510 PPC::getGCCRegAliases(Aliases, NumAliases);
511 }
Anders Carlssond04c6e22007-11-27 04:11:28 +0000512 virtual bool validateAsmConstraint(char c,
513 TargetInfo::ConstraintInfo &info) const {
514 return PPC::validateAsmConstraint(c, info);
515 }
516 virtual const char *getClobbers() const {
517 return PPC::getClobbers();
518 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000519};
520} // end anonymous namespace.
521
522namespace {
523class DarwinPPC64TargetInfo : public DarwinTargetInfo {
524public:
Ted Kremenekae360762007-12-03 22:06:55 +0000525 DarwinPPC64TargetInfo(const std::string& triple) : DarwinTargetInfo(triple) {}
526
Chris Lattnerd15fa822007-10-06 06:57:34 +0000527 virtual void getTargetDefines(std::vector<char> &Defines) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000528 DarwinTargetInfo::getTargetDefines(Defines);
529 getPowerPCDefines(Defines, true);
530 }
531 virtual void getTargetBuiltins(const Builtin::Info *&Records,
532 unsigned &NumRecords) const {
533 PPC::getBuiltins(Records, NumRecords);
534 }
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000535 virtual const char *getVAListDeclaration() const {
536 return getPPCVAListDeclaration();
537 }
Anders Carlsson44fe49c2007-12-08 19:32:57 +0000538 virtual const char *getTargetPrefix() const {
539 return PPC::getTargetPrefix();
540 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000541 virtual void getGCCRegNames(const char * const *&Names,
542 unsigned &NumNames) const {
543 PPC::getGCCRegNames(Names, NumNames);
544 }
545 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
546 unsigned &NumAliases) const {
547 PPC::getGCCRegAliases(Aliases, NumAliases);
548 }
Anders Carlssond04c6e22007-11-27 04:11:28 +0000549 virtual bool validateAsmConstraint(char c,
550 TargetInfo::ConstraintInfo &info) const {
551 return PPC::validateAsmConstraint(c, info);
552 }
553 virtual const char *getClobbers() const {
554 return PPC::getClobbers();
555 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000556};
557} // end anonymous namespace.
558
559namespace {
560class DarwinI386TargetInfo : public DarwinTargetInfo {
561public:
Ted Kremenekae360762007-12-03 22:06:55 +0000562 DarwinI386TargetInfo(const std::string& triple) : DarwinTargetInfo(triple) {}
563
Chris Lattnerd15fa822007-10-06 06:57:34 +0000564 virtual void getTargetDefines(std::vector<char> &Defines) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000565 DarwinTargetInfo::getTargetDefines(Defines);
566 getX86Defines(Defines, false);
567 }
568 virtual void getTargetBuiltins(const Builtin::Info *&Records,
569 unsigned &NumRecords) const {
570 X86::getBuiltins(Records, NumRecords);
571 }
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000572 virtual const char *getVAListDeclaration() const {
573 return getI386VAListDeclaration();
Anders Carlsson3346ae62007-11-24 23:38:12 +0000574 }
Anders Carlsson44fe49c2007-12-08 19:32:57 +0000575 virtual const char *getTargetPrefix() const {
576 return X86::getTargetPrefix();
577 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000578 virtual void getGCCRegNames(const char * const *&Names,
579 unsigned &NumNames) const {
580 X86::getGCCRegNames(Names, NumNames);
581 }
582 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
583 unsigned &NumAliases) const {
584 X86::getGCCRegAliases(Aliases, NumAliases);
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000585 }
Anders Carlssond04c6e22007-11-27 04:11:28 +0000586 virtual bool validateAsmConstraint(char c,
587 TargetInfo::ConstraintInfo &info) const {
588 return X86::validateAsmConstraint(c, info);
589 }
590 virtual const char *getClobbers() const {
591 return X86::getClobbers();
592 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000593};
594} // end anonymous namespace.
595
596namespace {
597class DarwinX86_64TargetInfo : public DarwinTargetInfo {
598public:
Ted Kremenekae360762007-12-03 22:06:55 +0000599 DarwinX86_64TargetInfo(const std::string& triple) :DarwinTargetInfo(triple) {}
600
Chris Lattnerd15fa822007-10-06 06:57:34 +0000601 virtual void getTargetDefines(std::vector<char> &Defines) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000602 DarwinTargetInfo::getTargetDefines(Defines);
603 getX86Defines(Defines, true);
604 }
605 virtual void getTargetBuiltins(const Builtin::Info *&Records,
606 unsigned &NumRecords) const {
607 X86::getBuiltins(Records, NumRecords);
608 }
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000609 virtual const char *getVAListDeclaration() const {
610 return getX86_64VAListDeclaration();
Anders Carlsson3346ae62007-11-24 23:38:12 +0000611 }
Anders Carlsson44fe49c2007-12-08 19:32:57 +0000612 virtual const char *getTargetPrefix() const {
613 return X86::getTargetPrefix();
614 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000615 virtual void getGCCRegNames(const char * const *&Names,
616 unsigned &NumNames) const {
617 X86::getGCCRegNames(Names, NumNames);
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000618 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000619 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
620 unsigned &NumAliases) const {
621 X86::getGCCRegAliases(Aliases, NumAliases);
622 }
Anders Carlssond04c6e22007-11-27 04:11:28 +0000623 virtual bool validateAsmConstraint(char c,
624 TargetInfo::ConstraintInfo &info) const {
625 return X86::validateAsmConstraint(c, info);
626 }
627 virtual const char *getClobbers() const {
628 return X86::getClobbers();
629 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000630};
631} // end anonymous namespace.
632
633namespace {
634class LinuxTargetInfo : public DarwinTargetInfo {
635public:
Ted Kremenekae360762007-12-03 22:06:55 +0000636 LinuxTargetInfo(const std::string& triple) : DarwinTargetInfo(triple) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000637 // Note: I have no idea if this is right, just for testing.
638 WCharWidth = 16;
Chris Lattnerd2d2a112007-07-14 01:29:45 +0000639 WCharAlign = 16;
Reid Spencer5f016e22007-07-11 17:01:13 +0000640 }
641
Chris Lattnerd15fa822007-10-06 06:57:34 +0000642 virtual void getTargetDefines(std::vector<char> &Defines) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000643 // TODO: linux-specific stuff.
644 getX86Defines(Defines, false);
645 }
646 virtual void getTargetBuiltins(const Builtin::Info *&Records,
647 unsigned &NumRecords) const {
648 X86::getBuiltins(Records, NumRecords);
649 }
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000650 virtual const char *getVAListDeclaration() const {
651 return getI386VAListDeclaration();
Anders Carlsson3346ae62007-11-24 23:38:12 +0000652 }
Anders Carlsson44fe49c2007-12-08 19:32:57 +0000653 virtual const char *getTargetPrefix() const {
654 return X86::getTargetPrefix();
655 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000656 virtual void getGCCRegNames(const char * const *&Names,
657 unsigned &NumNames) const {
658 X86::getGCCRegNames(Names, NumNames);
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000659 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000660 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
661 unsigned &NumAliases) const {
662 X86::getGCCRegAliases(Aliases, NumAliases);
663 }
Anders Carlssond04c6e22007-11-27 04:11:28 +0000664 virtual bool validateAsmConstraint(char c,
665 TargetInfo::ConstraintInfo &info) const {
666 return X86::validateAsmConstraint(c, info);
667 }
668 virtual const char *getClobbers() const {
669 return X86::getClobbers();
670 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000671};
672} // end anonymous namespace.
673
674
675//===----------------------------------------------------------------------===//
676// Driver code
677//===----------------------------------------------------------------------===//
678
Ted Kremenek8448d382007-12-04 17:07:35 +0000679static inline bool IsX86(const std::string& TT) {
Ted Kremenekae360762007-12-03 22:06:55 +0000680 return (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' &&
681 TT[4] == '-' && TT[1] - '3' < 6);
682}
683
Reid Spencer5f016e22007-07-11 17:01:13 +0000684/// CreateTarget - Create the TargetInfoImpl object for the specified target
685/// enum value.
Ted Kremenekae360762007-12-03 22:06:55 +0000686static TargetInfoImpl *CreateTarget(const std::string& T) {
Chris Lattner82817ba2007-12-05 18:41:05 +0000687 if (T.find("ppc-") == 0 || T.find("powerpc-") == 0)
Ted Kremenek8448d382007-12-04 17:07:35 +0000688 return new DarwinPPCTargetInfo(T);
Chris Lattner82817ba2007-12-05 18:41:05 +0000689 else if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0)
Ted Kremenek8448d382007-12-04 17:07:35 +0000690 return new DarwinPPC64TargetInfo(T);
691 else if (T.find("x86_64-") == 0)
692 return new DarwinX86_64TargetInfo(T);
693 else if (IsX86(T))
694 return new DarwinI386TargetInfo(T);
695 else if (T.find("bogusW16W16-") == 0) // For testing portability.
696 return new LinuxTargetInfo(T);
697 else
698 return NULL;
Reid Spencer5f016e22007-07-11 17:01:13 +0000699}
700
701/// CreateTargetInfo - Return the set of target info objects as specified by
702/// the -arch command line option.
Ted Kremenek9c728dc2007-12-12 22:39:36 +0000703TargetInfo* TargetInfo::CreateTargetInfo(const std::string* TriplesStart,
Ted Kremenekbbced582007-12-12 18:05:32 +0000704 const std::string* TriplesEnd,
705 Diagnostic *Diags) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000706
707 // Create the primary target and target info.
Ted Kremenekbbced582007-12-12 18:05:32 +0000708 TargetInfoImpl* PrimaryTarget = CreateTarget(*TriplesStart);
Ted Kremenekaead4722007-12-03 23:23:21 +0000709
710 if (!PrimaryTarget)
711 return NULL;
712
Ted Kremenek9c728dc2007-12-12 22:39:36 +0000713 TargetInfo *TI = new TargetInfo(PrimaryTarget, Diags);
Reid Spencer5f016e22007-07-11 17:01:13 +0000714
715 // Add all secondary targets.
Ted Kremenekbbced582007-12-12 18:05:32 +0000716 for (const std::string* I=TriplesStart+1; I != TriplesEnd; ++I) {
717 TargetInfoImpl* SecondaryTarget = CreateTarget(*I);
Ted Kremenekaead4722007-12-03 23:23:21 +0000718
719 if (!SecondaryTarget) {
Ted Kremenekbbced582007-12-12 18:05:32 +0000720 fprintf (stderr,
721 "Warning: secondary target '%s' unrecognized.\n",
722 I->c_str());
723
Ted Kremenekaead4722007-12-03 23:23:21 +0000724 continue;
725 }
726
Ted Kremenekbbced582007-12-12 18:05:32 +0000727 TI->AddSecondaryTarget(SecondaryTarget);
Ted Kremenekaead4722007-12-03 23:23:21 +0000728 }
Ted Kremenekae360762007-12-03 22:06:55 +0000729
Reid Spencer5f016e22007-07-11 17:01:13 +0000730 return TI;
731}