blob: dbc0f7af09a5cdddc5e64a616dce2aba0d2e1e95 [file] [log] [blame]
Chris Lattner4b009652007-07-25 00:24:17 +00001//===--- Targets.cpp - Implement -arch option and targets -----------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Chris Lattner and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the -arch command line option and creates a TargetInfo
11// that represents them.
12//
13//===----------------------------------------------------------------------===//
14
15#include "clang.h"
16#include "clang/AST/Builtins.h"
17#include "clang/Basic/Diagnostic.h"
18#include "clang/Basic/TargetInfo.h"
Anders Carlsson7dd1c952007-11-24 23:38:12 +000019#include "llvm/ADT/STLExtras.h"
Chris Lattner4b009652007-07-25 00:24:17 +000020#include "llvm/Support/CommandLine.h"
Ted Kremenek40499482007-12-03 22:06:55 +000021#include <algorithm>
22#include <cctype>
23
Chris Lattner4b009652007-07-25 00:24:17 +000024using namespace clang;
25
Chris Lattner4b009652007-07-25 00:24:17 +000026//===----------------------------------------------------------------------===//
27// Common code shared among targets.
28//===----------------------------------------------------------------------===//
29
Chris Lattner0db667a2007-10-06 06:57:34 +000030static void Define(std::vector<char> &Buf, const char *Macro,
31 const char *Val = "1") {
32 const char *Def = "#define ";
33 Buf.insert(Buf.end(), Def, Def+strlen(Def));
34 Buf.insert(Buf.end(), Macro, Macro+strlen(Macro));
35 Buf.push_back(' ');
36 Buf.insert(Buf.end(), Val, Val+strlen(Val));
37 Buf.push_back('\n');
38}
39
40
Chris Lattner4b009652007-07-25 00:24:17 +000041namespace {
42class DarwinTargetInfo : public TargetInfoImpl {
43public:
Ted Kremenek40499482007-12-03 22:06:55 +000044 DarwinTargetInfo(const std::string& triple) : TargetInfoImpl(triple) {}
45
Chris Lattner0db667a2007-10-06 06:57:34 +000046 virtual void getTargetDefines(std::vector<char> &Defs) const {
Chris Lattner1ed172d2007-10-17 06:04:46 +000047// FIXME: we need a real target configuration system. For now, only define
48// __APPLE__ if the host has it.
49#ifdef __APPLE__
Chris Lattner0db667a2007-10-06 06:57:34 +000050 Define(Defs, "__APPLE__");
51 Define(Defs, "__MACH__");
Chris Lattner1ed172d2007-10-17 06:04:46 +000052#endif
Chris Lattner4b009652007-07-25 00:24:17 +000053
54 if (1) {// -fobjc-gc controls this.
Chris Lattner0db667a2007-10-06 06:57:34 +000055 Define(Defs, "__weak", "");
56 Define(Defs, "__strong", "");
Chris Lattner4b009652007-07-25 00:24:17 +000057 } else {
Chris Lattner0db667a2007-10-06 06:57:34 +000058 Define(Defs, "__weak", "__attribute__((objc_gc(weak)))");
59 Define(Defs, "__strong", "__attribute__((objc_gc(strong)))");
60 Define(Defs, "__OBJC_GC__");
Chris Lattner4b009652007-07-25 00:24:17 +000061 }
62
63 // darwin_constant_cfstrings controls this.
Chris Lattner0db667a2007-10-06 06:57:34 +000064 Define(Defs, "__CONSTANT_CFSTRINGS__");
Chris Lattner4b009652007-07-25 00:24:17 +000065
66 if (0) // darwin_pascal_strings
Chris Lattner0db667a2007-10-06 06:57:34 +000067 Define(Defs, "__PASCAL_STRINGS__");
Chris Lattner4b009652007-07-25 00:24:17 +000068 }
69
70};
71} // end anonymous namespace.
72
73
74/// getPowerPCDefines - Return a set of the PowerPC-specific #defines that are
75/// not tied to a specific subtarget.
Chris Lattner0db667a2007-10-06 06:57:34 +000076static void getPowerPCDefines(std::vector<char> &Defs, bool is64Bit) {
Chris Lattner4b009652007-07-25 00:24:17 +000077 // Target identification.
Chris Lattner0db667a2007-10-06 06:57:34 +000078 Define(Defs, "__ppc__");
79 Define(Defs, "_ARCH_PPC");
80 Define(Defs, "__POWERPC__");
Chris Lattner4b009652007-07-25 00:24:17 +000081 if (is64Bit) {
Chris Lattner0db667a2007-10-06 06:57:34 +000082 Define(Defs, "_ARCH_PPC64");
83 Define(Defs, "_LP64");
84 Define(Defs, "__LP64__");
85 Define(Defs, "__ppc64__");
Chris Lattner4b009652007-07-25 00:24:17 +000086 } else {
Chris Lattner0db667a2007-10-06 06:57:34 +000087 Define(Defs, "__ppc__");
Chris Lattner4b009652007-07-25 00:24:17 +000088 }
89
90 // Target properties.
Chris Lattner0db667a2007-10-06 06:57:34 +000091 Define(Defs, "_BIG_ENDIAN");
92 Define(Defs, "__BIG_ENDIAN__");
Chris Lattner4b009652007-07-25 00:24:17 +000093
94 if (is64Bit) {
Chris Lattner0db667a2007-10-06 06:57:34 +000095 Define(Defs, "__INTMAX_MAX__", "9223372036854775807L");
96 Define(Defs, "__INTMAX_TYPE__", "long int");
97 Define(Defs, "__LONG_MAX__", "9223372036854775807L");
98 Define(Defs, "__PTRDIFF_TYPE__", "long int");
99 Define(Defs, "__UINTMAX_TYPE__", "long unsigned int");
Chris Lattner4b009652007-07-25 00:24:17 +0000100 } else {
Chris Lattner0db667a2007-10-06 06:57:34 +0000101 Define(Defs, "__INTMAX_MAX__", "9223372036854775807LL");
102 Define(Defs, "__INTMAX_TYPE__", "long long int");
103 Define(Defs, "__LONG_MAX__", "2147483647L");
104 Define(Defs, "__PTRDIFF_TYPE__", "int");
105 Define(Defs, "__UINTMAX_TYPE__", "long long unsigned int");
Chris Lattner4b009652007-07-25 00:24:17 +0000106 }
Chris Lattner0db667a2007-10-06 06:57:34 +0000107 Define(Defs, "__INT_MAX__", "2147483647");
108 Define(Defs, "__LONG_LONG_MAX__", "9223372036854775807LL");
109 Define(Defs, "__CHAR_BIT__", "8");
110 Define(Defs, "__SCHAR_MAX__", "127");
111 Define(Defs, "__SHRT_MAX__", "32767");
112 Define(Defs, "__SIZE_TYPE__", "long unsigned int");
Chris Lattner4b009652007-07-25 00:24:17 +0000113
114 // Subtarget options.
Chris Lattner0db667a2007-10-06 06:57:34 +0000115 Define(Defs, "__USER_LABEL_PREFIX__", "_");
116 Define(Defs, "__NATURAL_ALIGNMENT__");
117 Define(Defs, "__REGISTER_PREFIX__", "");
Chris Lattner4b009652007-07-25 00:24:17 +0000118
Chris Lattner0db667a2007-10-06 06:57:34 +0000119 Define(Defs, "__WCHAR_MAX__", "2147483647");
120 Define(Defs, "__WCHAR_TYPE__", "int");
121 Define(Defs, "__WINT_TYPE__", "int");
Chris Lattner4b009652007-07-25 00:24:17 +0000122
123 // Float macros.
Chris Lattner0db667a2007-10-06 06:57:34 +0000124 Define(Defs, "__FLT_DENORM_MIN__", "1.40129846e-45F");
125 Define(Defs, "__FLT_DIG__", "6");
126 Define(Defs, "__FLT_EPSILON__", "1.19209290e-7F");
127 Define(Defs, "__FLT_EVAL_METHOD__", "0");
128 Define(Defs, "__FLT_HAS_INFINITY__");
129 Define(Defs, "__FLT_HAS_QUIET_NAN__");
130 Define(Defs, "__FLT_MANT_DIG__", "24");
131 Define(Defs, "__FLT_MAX_10_EXP__", "38");
132 Define(Defs, "__FLT_MAX_EXP__", "128");
133 Define(Defs, "__FLT_MAX__", "3.40282347e+38F");
134 Define(Defs, "__FLT_MIN_10_EXP__", "(-37)");
135 Define(Defs, "__FLT_MIN_EXP__", "(-125)");
136 Define(Defs, "__FLT_MIN__", "1.17549435e-38F");
137 Define(Defs, "__FLT_RADIX__", "2");
Chris Lattner4b009652007-07-25 00:24:17 +0000138
139 // double macros.
Chris Lattner0db667a2007-10-06 06:57:34 +0000140 Define(Defs, "__DBL_DENORM_MIN__", "4.9406564584124654e-324");
141 Define(Defs, "__DBL_DIG__", "15");
142 Define(Defs, "__DBL_EPSILON__", "2.2204460492503131e-16");
143 Define(Defs, "__DBL_HAS_INFINITY__");
144 Define(Defs, "__DBL_HAS_QUIET_NAN__");
145 Define(Defs, "__DBL_MANT_DIG__", "53");
146 Define(Defs, "__DBL_MAX_10_EXP__", "308");
147 Define(Defs, "__DBL_MAX_EXP__", "1024");
148 Define(Defs, "__DBL_MAX__", "1.7976931348623157e+308");
149 Define(Defs, "__DBL_MIN_10_EXP__", "(-307)");
150 Define(Defs, "__DBL_MIN_EXP__", "(-1021)");
151 Define(Defs, "__DBL_MIN__", "2.2250738585072014e-308");
152 Define(Defs, "__DECIMAL_DIG__", "33");
Chris Lattner4b009652007-07-25 00:24:17 +0000153
154 // 128-bit long double macros.
Chris Lattner0db667a2007-10-06 06:57:34 +0000155 Define(Defs, "__LDBL_DENORM_MIN__",
156 "4.94065645841246544176568792868221e-324L");
157 Define(Defs, "__LDBL_DIG__", "31");
158 Define(Defs, "__LDBL_EPSILON__",
159 "4.94065645841246544176568792868221e-324L");
160 Define(Defs, "__LDBL_HAS_INFINITY__");
161 Define(Defs, "__LDBL_HAS_QUIET_NAN__");
162 Define(Defs, "__LDBL_MANT_DIG__", "106");
163 Define(Defs, "__LDBL_MAX_10_EXP__", "308");
164 Define(Defs, "__LDBL_MAX_EXP__", "1024");
165 Define(Defs, "__LDBL_MAX__",
166 "1.79769313486231580793728971405301e+308L");
167 Define(Defs, "__LDBL_MIN_10_EXP__", "(-291)");
168 Define(Defs, "__LDBL_MIN_EXP__", "(-968)");
169 Define(Defs, "__LDBL_MIN__",
170 "2.00416836000897277799610805135016e-292L");
171 Define(Defs, "__LONG_DOUBLE_128__");
Chris Lattner4b009652007-07-25 00:24:17 +0000172}
173
174/// getX86Defines - Return a set of the X86-specific #defines that are
175/// not tied to a specific subtarget.
Chris Lattner0db667a2007-10-06 06:57:34 +0000176static void getX86Defines(std::vector<char> &Defs, bool is64Bit) {
Chris Lattner4b009652007-07-25 00:24:17 +0000177 // Target identification.
178 if (is64Bit) {
Chris Lattner0db667a2007-10-06 06:57:34 +0000179 Define(Defs, "_LP64");
180 Define(Defs, "__LP64__");
181 Define(Defs, "__amd64__");
182 Define(Defs, "__amd64");
183 Define(Defs, "__x86_64");
184 Define(Defs, "__x86_64__");
Chris Lattner4b009652007-07-25 00:24:17 +0000185 } else {
Chris Lattner0db667a2007-10-06 06:57:34 +0000186 Define(Defs, "__i386__");
187 Define(Defs, "__i386");
188 Define(Defs, "i386");
Chris Lattner4b009652007-07-25 00:24:17 +0000189 }
190
191 // Target properties.
Chris Lattner0db667a2007-10-06 06:57:34 +0000192 Define(Defs, "__LITTLE_ENDIAN__");
Chris Lattner4b009652007-07-25 00:24:17 +0000193
194 if (is64Bit) {
Chris Lattner0db667a2007-10-06 06:57:34 +0000195 Define(Defs, "__INTMAX_MAX__", "9223372036854775807L");
196 Define(Defs, "__INTMAX_TYPE__", "long int");
197 Define(Defs, "__LONG_MAX__", "9223372036854775807L");
198 Define(Defs, "__PTRDIFF_TYPE__", "long int");
199 Define(Defs, "__UINTMAX_TYPE__", "long unsigned int");
Chris Lattner4b009652007-07-25 00:24:17 +0000200 } else {
Chris Lattner0db667a2007-10-06 06:57:34 +0000201 Define(Defs, "__INTMAX_MAX__", "9223372036854775807LL");
202 Define(Defs, "__INTMAX_TYPE__", "long long int");
203 Define(Defs, "__LONG_MAX__", "2147483647L");
204 Define(Defs, "__PTRDIFF_TYPE__", "int");
205 Define(Defs, "__UINTMAX_TYPE__", "long long unsigned int");
Chris Lattner4b009652007-07-25 00:24:17 +0000206 }
Chris Lattner0db667a2007-10-06 06:57:34 +0000207 Define(Defs, "__CHAR_BIT__", "8");
208 Define(Defs, "__INT_MAX__", "2147483647");
209 Define(Defs, "__LONG_LONG_MAX__", "9223372036854775807LL");
210 Define(Defs, "__SCHAR_MAX__", "127");
211 Define(Defs, "__SHRT_MAX__", "32767");
212 Define(Defs, "__SIZE_TYPE__", "long unsigned int");
Chris Lattner4b009652007-07-25 00:24:17 +0000213
214 // Subtarget options.
Chris Lattner0db667a2007-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__", "");
Chris Lattner4b009652007-07-25 00:24:17 +0000224
Chris Lattner0db667a2007-10-06 06:57:34 +0000225 Define(Defs, "__WCHAR_MAX__", "2147483647");
226 Define(Defs, "__WCHAR_TYPE__", "int");
227 Define(Defs, "__WINT_TYPE__", "int");
Chris Lattner4b009652007-07-25 00:24:17 +0000228
229 // Float macros.
Chris Lattner0db667a2007-10-06 06:57:34 +0000230 Define(Defs, "__FLT_DENORM_MIN__", "1.40129846e-45F");
231 Define(Defs, "__FLT_DIG__", "6");
232 Define(Defs, "__FLT_EPSILON__", "1.19209290e-7F");
233 Define(Defs, "__FLT_EVAL_METHOD__", "0");
234 Define(Defs, "__FLT_HAS_INFINITY__");
235 Define(Defs, "__FLT_HAS_QUIET_NAN__");
236 Define(Defs, "__FLT_MANT_DIG__", "24");
237 Define(Defs, "__FLT_MAX_10_EXP__", "38");
238 Define(Defs, "__FLT_MAX_EXP__", "128");
239 Define(Defs, "__FLT_MAX__", "3.40282347e+38F");
240 Define(Defs, "__FLT_MIN_10_EXP__", "(-37)");
241 Define(Defs, "__FLT_MIN_EXP__", "(-125)");
242 Define(Defs, "__FLT_MIN__", "1.17549435e-38F");
243 Define(Defs, "__FLT_RADIX__", "2");
Chris Lattner4b009652007-07-25 00:24:17 +0000244
245 // Double macros.
Chris Lattner0db667a2007-10-06 06:57:34 +0000246 Define(Defs, "__DBL_DENORM_MIN__", "4.9406564584124654e-324");
247 Define(Defs, "__DBL_DIG__", "15");
248 Define(Defs, "__DBL_EPSILON__", "2.2204460492503131e-16");
249 Define(Defs, "__DBL_HAS_INFINITY__");
250 Define(Defs, "__DBL_HAS_QUIET_NAN__");
251 Define(Defs, "__DBL_MANT_DIG__", "53");
252 Define(Defs, "__DBL_MAX_10_EXP__", "308");
253 Define(Defs, "__DBL_MAX_EXP__", "1024");
254 Define(Defs, "__DBL_MAX__", "1.7976931348623157e+308");
255 Define(Defs, "__DBL_MIN_10_EXP__", "(-307)");
256 Define(Defs, "__DBL_MIN_EXP__", "(-1021)");
257 Define(Defs, "__DBL_MIN__", "2.2250738585072014e-308");
258 Define(Defs, "__DECIMAL_DIG__", "21");
Chris Lattner4b009652007-07-25 00:24:17 +0000259
260 // 80-bit Long double macros.
Chris Lattner0db667a2007-10-06 06:57:34 +0000261 Define(Defs, "__LDBL_DENORM_MIN__", "3.64519953188247460253e-4951L");
262 Define(Defs, "__LDBL_DIG__", "18");
263 Define(Defs, "__LDBL_EPSILON__", "1.08420217248550443401e-19L");
264 Define(Defs, "__LDBL_HAS_INFINITY__");
265 Define(Defs, "__LDBL_HAS_QUIET_NAN__");
266 Define(Defs, "__LDBL_MANT_DIG__", "64");
267 Define(Defs, "__LDBL_MAX_10_EXP__", "4932");
268 Define(Defs, "__LDBL_MAX_EXP__", "16384");
269 Define(Defs, "__LDBL_MAX__", "1.18973149535723176502e+4932L");
270 Define(Defs, "__LDBL_MIN_10_EXP__", "(-4931)");
271 Define(Defs, "__LDBL_MIN_EXP__", "(-16381)");
272 Define(Defs, "__LDBL_MIN__", "3.36210314311209350626e-4932L");
Chris Lattner4b009652007-07-25 00:24:17 +0000273}
274
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000275static const char* getI386VAListDeclaration() {
276 return "typedef char* __builtin_va_list;";
277}
278
279static const char* getX86_64VAListDeclaration() {
280 return
281 "typedef struct __va_list_tag {"
282 " unsigned gp_offset;"
283 " unsigned fp_offset;"
284 " void* overflow_arg_area;"
285 " void* reg_save_area;"
286 "} __builtin_va_list[1];";
287}
288
289static const char* getPPCVAListDeclaration() {
290 return
291 "typedef struct __va_list_tag {"
292 " unsigned char gpr;"
293 " unsigned char fpr;"
294 " unsigned short reserved;"
295 " void* overflow_arg_area;"
296 " void* reg_save_area;"
297 "} __builtin_va_list[1];";
298}
299
300
Chris Lattner4b009652007-07-25 00:24:17 +0000301/// PPC builtin info.
302namespace PPC {
303 enum {
304 LastTIBuiltin = Builtin::FirstTSBuiltin-1,
305#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
306#include "PPCBuiltins.def"
307 LastTSBuiltin
308 };
309
310 static const Builtin::Info BuiltinInfo[] = {
311#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
312#include "PPCBuiltins.def"
313 };
314
315 static void getBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) {
316 Records = BuiltinInfo;
317 NumRecords = LastTSBuiltin-Builtin::FirstTSBuiltin;
318 }
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000319
320 static const char * const GCCRegNames[] = {
321 "0", "1", "2", "3", "4", "5", "6", "7",
322 "8", "9", "10", "11", "12", "13", "14", "15",
323 "16", "17", "18", "19", "20", "21", "22", "23",
324 "24", "25", "26", "27", "28", "29", "30", "31",
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 "mq", "lr", "ctr", "ap",
330 "0", "1", "2", "3", "4", "5", "6", "7",
331 "xer",
332 "0", "1", "2", "3", "4", "5", "6", "7",
333 "8", "9", "10", "11", "12", "13", "14", "15",
334 "16", "17", "18", "19", "20", "21", "22", "23",
335 "24", "25", "26", "27", "28", "29", "30", "31",
336 "vrsave", "vscr",
337 "spe_acc", "spefscr",
338 "sfp"
339 };
340
341 static void getGCCRegNames(const char * const *&Names,
342 unsigned &NumNames) {
343 Names = GCCRegNames;
344 NumNames = llvm::array_lengthof(GCCRegNames);
345 }
346
347 static const TargetInfoImpl::GCCRegAlias GCCRegAliases[] = {
348 // While some of these aliases do map to different registers
349 // they still share the same register name.
350 { { "cc", "cr0", "fr0", "r0", "v0"}, "0" },
351 { { "cr1", "fr1", "r1", "sp", "v1"}, "1" },
352 { { "cr2", "fr2", "r2", "toc", "v2"}, "2" },
353 { { "cr3", "fr3", "r3", "v3"}, "3" },
354 { { "cr4", "fr4", "r4", "v4"}, "4" },
355 { { "cr5", "fr5", "r5", "v5"}, "5" },
356 { { "cr6", "fr6", "r6", "v6"}, "6" },
357 { { "cr7", "fr7", "r7", "v7"}, "7" },
358 { { "fr8", "r8", "v8"}, "8" },
359 { { "fr9", "r9", "v9"}, "9" },
360 { { "fr10", "r10", "v10"}, "10" },
361 { { "fr11", "r11", "v11"}, "11" },
362 { { "fr12", "r12", "v12"}, "12" },
363 { { "fr13", "r13", "v13"}, "13" },
364 { { "fr14", "r14", "v14"}, "14" },
365 { { "fr15", "r15", "v15"}, "15" },
366 { { "fr16", "r16", "v16"}, "16" },
367 { { "fr17", "r17", "v17"}, "17" },
368 { { "fr18", "r18", "v18"}, "18" },
369 { { "fr19", "r19", "v19"}, "19" },
370 { { "fr20", "r20", "v20"}, "20" },
371 { { "fr21", "r21", "v21"}, "21" },
372 { { "fr22", "r22", "v22"}, "22" },
373 { { "fr23", "r23", "v23"}, "23" },
374 { { "fr24", "r24", "v24"}, "24" },
375 { { "fr25", "r25", "v25"}, "25" },
376 { { "fr26", "r26", "v26"}, "26" },
377 { { "fr27", "r27", "v27"}, "27" },
378 { { "fr28", "r28", "v28"}, "28" },
379 { { "fr29", "r29", "v29"}, "29" },
380 { { "fr30", "r30", "v30"}, "30" },
381 { { "fr31", "r31", "v31"}, "31" },
382 };
383
384 static void getGCCRegAliases(const TargetInfoImpl::GCCRegAlias *&Aliases,
385 unsigned &NumAliases) {
386 Aliases = GCCRegAliases;
387 NumAliases = llvm::array_lengthof(GCCRegAliases);
Anders Carlsson4ce42302007-11-27 04:11:28 +0000388 }
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000389
Anders Carlsson4ce42302007-11-27 04:11:28 +0000390 static bool validateAsmConstraint(char c,
391 TargetInfo::ConstraintInfo &info) {
392 switch (c) {
393 default: return false;
394 case 'O': // Zero
395 return true;
396 case 'b': // Base register
397 case 'f': // Floating point register
398 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
399 return true;
400 }
401 }
402
403 const char *getClobbers() {
404 return 0;
405 }
406
Chris Lattner4b009652007-07-25 00:24:17 +0000407} // End namespace PPC
408
409
410/// X86 builtin info.
411namespace X86 {
412 enum {
413 LastTIBuiltin = Builtin::FirstTSBuiltin-1,
414#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
415#include "X86Builtins.def"
416 LastTSBuiltin
417 };
418
419 static const Builtin::Info BuiltinInfo[] = {
420#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
421#include "X86Builtins.def"
422 };
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000423
Chris Lattner4b009652007-07-25 00:24:17 +0000424
425 static void getBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) {
426 Records = BuiltinInfo;
427 NumRecords = LastTSBuiltin-Builtin::FirstTSBuiltin;
428 }
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000429
430 static const char *GCCRegNames[] = {
431 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
432 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
Anders Carlssonc411b492007-11-25 00:23:10 +0000433 "argp", "flags", "fspr", "dirflag", "frame",
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000434 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
435 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
436 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
437 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
438 };
439
440 static void getGCCRegNames(const char * const *&Names,
441 unsigned &NumNames) {
442 Names = GCCRegNames;
443 NumNames = llvm::array_lengthof(GCCRegNames);
444 }
445
446 static const TargetInfoImpl::GCCRegAlias GCCRegAliases[] = {
447 { { "al", "ah", "eax", "rax" }, "ax" },
448 { { "bl", "bh", "ebx", "rbx" }, "bx" },
449 { { "cl", "ch", "ecx", "rcx" }, "cx" },
450 { { "dl", "dh", "edx", "rdx" }, "dx" },
451 { { "esi", "rsi" }, "si" },
452 { { "esp", "rsp" }, "sp" },
453 { { "ebp", "rbp" }, "bp" },
454 };
455
456 static void getGCCRegAliases(const TargetInfoImpl::GCCRegAlias *&Aliases,
457 unsigned &NumAliases) {
458 Aliases = GCCRegAliases;
459 NumAliases = llvm::array_lengthof(GCCRegAliases);
460 }
461
Anders Carlsson4ce42302007-11-27 04:11:28 +0000462 static bool validateAsmConstraint(char c,
463 TargetInfo::ConstraintInfo &info) {
464 switch (c) {
465 default: return false;
466 case 'a': // eax.
467 case 'b': // ebx.
468 case 'c': // ecx.
469 case 'd': // edx.
470 case 'S': // esi.
471 case 'D': // edi.
472 case 'A': // edx:eax.
473 case 't': // top of floating point stack.
474 case 'u': // second from top of floating point stack.
475 case 'q': // a, b, c, d registers or any integer register in 64-bit.
476 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
477 return true;
478 }
479 }
480
481 const char *getClobbers() {
482 return "~{dirflag},~{fpsr},~{flags}";
483 }
484
Chris Lattner4b009652007-07-25 00:24:17 +0000485} // End namespace X86
486
487//===----------------------------------------------------------------------===//
488// Specific target implementations.
489//===----------------------------------------------------------------------===//
490
491
492namespace {
493class DarwinPPCTargetInfo : public DarwinTargetInfo {
494public:
Ted Kremenek40499482007-12-03 22:06:55 +0000495 DarwinPPCTargetInfo(const std::string& triple) : DarwinTargetInfo(triple) {}
496
Chris Lattner0db667a2007-10-06 06:57:34 +0000497 virtual void getTargetDefines(std::vector<char> &Defines) const {
Chris Lattner4b009652007-07-25 00:24:17 +0000498 DarwinTargetInfo::getTargetDefines(Defines);
499 getPowerPCDefines(Defines, false);
500 }
501 virtual void getTargetBuiltins(const Builtin::Info *&Records,
502 unsigned &NumRecords) const {
503 PPC::getBuiltins(Records, NumRecords);
504 }
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000505 virtual const char *getVAListDeclaration() const {
506 return getPPCVAListDeclaration();
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000507 }
508 virtual void getGCCRegNames(const char * const *&Names,
509 unsigned &NumNames) const {
510 PPC::getGCCRegNames(Names, NumNames);
511 }
512 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
513 unsigned &NumAliases) const {
514 PPC::getGCCRegAliases(Aliases, NumAliases);
515 }
Anders Carlsson4ce42302007-11-27 04:11:28 +0000516 virtual bool validateAsmConstraint(char c,
517 TargetInfo::ConstraintInfo &info) const {
518 return PPC::validateAsmConstraint(c, info);
519 }
520 virtual const char *getClobbers() const {
521 return PPC::getClobbers();
522 }
Chris Lattner4b009652007-07-25 00:24:17 +0000523};
524} // end anonymous namespace.
525
526namespace {
527class DarwinPPC64TargetInfo : public DarwinTargetInfo {
528public:
Ted Kremenek40499482007-12-03 22:06:55 +0000529 DarwinPPC64TargetInfo(const std::string& triple) : DarwinTargetInfo(triple) {}
530
Chris Lattner0db667a2007-10-06 06:57:34 +0000531 virtual void getTargetDefines(std::vector<char> &Defines) const {
Chris Lattner4b009652007-07-25 00:24:17 +0000532 DarwinTargetInfo::getTargetDefines(Defines);
533 getPowerPCDefines(Defines, true);
534 }
535 virtual void getTargetBuiltins(const Builtin::Info *&Records,
536 unsigned &NumRecords) const {
537 PPC::getBuiltins(Records, NumRecords);
538 }
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000539 virtual const char *getVAListDeclaration() const {
540 return getPPCVAListDeclaration();
541 }
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000542 virtual void getGCCRegNames(const char * const *&Names,
543 unsigned &NumNames) const {
544 PPC::getGCCRegNames(Names, NumNames);
545 }
546 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
547 unsigned &NumAliases) const {
548 PPC::getGCCRegAliases(Aliases, NumAliases);
549 }
Anders Carlsson4ce42302007-11-27 04:11:28 +0000550 virtual bool validateAsmConstraint(char c,
551 TargetInfo::ConstraintInfo &info) const {
552 return PPC::validateAsmConstraint(c, info);
553 }
554 virtual const char *getClobbers() const {
555 return PPC::getClobbers();
556 }
Chris Lattner4b009652007-07-25 00:24:17 +0000557};
558} // end anonymous namespace.
559
560namespace {
561class DarwinI386TargetInfo : public DarwinTargetInfo {
562public:
Ted Kremenek40499482007-12-03 22:06:55 +0000563 DarwinI386TargetInfo(const std::string& triple) : DarwinTargetInfo(triple) {}
564
Chris Lattner0db667a2007-10-06 06:57:34 +0000565 virtual void getTargetDefines(std::vector<char> &Defines) const {
Chris Lattner4b009652007-07-25 00:24:17 +0000566 DarwinTargetInfo::getTargetDefines(Defines);
567 getX86Defines(Defines, false);
568 }
569 virtual void getTargetBuiltins(const Builtin::Info *&Records,
570 unsigned &NumRecords) const {
571 X86::getBuiltins(Records, NumRecords);
572 }
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000573 virtual const char *getVAListDeclaration() const {
574 return getI386VAListDeclaration();
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000575 }
576 virtual void getGCCRegNames(const char * const *&Names,
577 unsigned &NumNames) const {
578 X86::getGCCRegNames(Names, NumNames);
579 }
580 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
581 unsigned &NumAliases) const {
582 X86::getGCCRegAliases(Aliases, NumAliases);
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000583 }
Anders Carlsson4ce42302007-11-27 04:11:28 +0000584 virtual bool validateAsmConstraint(char c,
585 TargetInfo::ConstraintInfo &info) const {
586 return X86::validateAsmConstraint(c, info);
587 }
588 virtual const char *getClobbers() const {
589 return X86::getClobbers();
590 }
Chris Lattner4b009652007-07-25 00:24:17 +0000591};
592} // end anonymous namespace.
593
594namespace {
595class DarwinX86_64TargetInfo : public DarwinTargetInfo {
596public:
Ted Kremenek40499482007-12-03 22:06:55 +0000597 DarwinX86_64TargetInfo(const std::string& triple) :DarwinTargetInfo(triple) {}
598
Chris Lattner0db667a2007-10-06 06:57:34 +0000599 virtual void getTargetDefines(std::vector<char> &Defines) const {
Chris Lattner4b009652007-07-25 00:24:17 +0000600 DarwinTargetInfo::getTargetDefines(Defines);
601 getX86Defines(Defines, true);
602 }
603 virtual void getTargetBuiltins(const Builtin::Info *&Records,
604 unsigned &NumRecords) const {
605 X86::getBuiltins(Records, NumRecords);
606 }
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000607 virtual const char *getVAListDeclaration() const {
608 return getX86_64VAListDeclaration();
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000609 }
610 virtual void getGCCRegNames(const char * const *&Names,
611 unsigned &NumNames) const {
612 X86::getGCCRegNames(Names, NumNames);
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000613 }
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000614 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
615 unsigned &NumAliases) const {
616 X86::getGCCRegAliases(Aliases, NumAliases);
617 }
Anders Carlsson4ce42302007-11-27 04:11:28 +0000618 virtual bool validateAsmConstraint(char c,
619 TargetInfo::ConstraintInfo &info) const {
620 return X86::validateAsmConstraint(c, info);
621 }
622 virtual const char *getClobbers() const {
623 return X86::getClobbers();
624 }
Chris Lattner4b009652007-07-25 00:24:17 +0000625};
626} // end anonymous namespace.
627
628namespace {
629class LinuxTargetInfo : public DarwinTargetInfo {
630public:
Ted Kremenek40499482007-12-03 22:06:55 +0000631 LinuxTargetInfo(const std::string& triple) : DarwinTargetInfo(triple) {
Chris Lattner4b009652007-07-25 00:24:17 +0000632 // Note: I have no idea if this is right, just for testing.
633 WCharWidth = 16;
634 WCharAlign = 16;
635 }
636
Chris Lattner0db667a2007-10-06 06:57:34 +0000637 virtual void getTargetDefines(std::vector<char> &Defines) const {
Chris Lattner4b009652007-07-25 00:24:17 +0000638 // TODO: linux-specific stuff.
639 getX86Defines(Defines, false);
640 }
641 virtual void getTargetBuiltins(const Builtin::Info *&Records,
642 unsigned &NumRecords) const {
643 X86::getBuiltins(Records, NumRecords);
644 }
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000645 virtual const char *getVAListDeclaration() const {
646 return getI386VAListDeclaration();
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000647 }
648 virtual void getGCCRegNames(const char * const *&Names,
649 unsigned &NumNames) const {
650 X86::getGCCRegNames(Names, NumNames);
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000651 }
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000652 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
653 unsigned &NumAliases) const {
654 X86::getGCCRegAliases(Aliases, NumAliases);
655 }
Anders Carlsson4ce42302007-11-27 04:11:28 +0000656 virtual bool validateAsmConstraint(char c,
657 TargetInfo::ConstraintInfo &info) const {
658 return X86::validateAsmConstraint(c, info);
659 }
660 virtual const char *getClobbers() const {
661 return X86::getClobbers();
662 }
Chris Lattner4b009652007-07-25 00:24:17 +0000663};
664} // end anonymous namespace.
665
666
667//===----------------------------------------------------------------------===//
668// Driver code
669//===----------------------------------------------------------------------===//
670
Ted Kremenek40499482007-12-03 22:06:55 +0000671static bool IsX86(const std::string& TT) {
672 return (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' &&
673 TT[4] == '-' && TT[1] - '3' < 6);
674}
675
Chris Lattner4b009652007-07-25 00:24:17 +0000676/// CreateTarget - Create the TargetInfoImpl object for the specified target
677/// enum value.
Ted Kremenek40499482007-12-03 22:06:55 +0000678static TargetInfoImpl *CreateTarget(const std::string& T) {
679 if (T.find("darwin") != std::string::npos) {
680 if (T.find("ppc-") == 0)
681 return new DarwinPPCTargetInfo(T);
682 else if (T.find("ppc64-") == 0)
683 return new DarwinPPC64TargetInfo(T);
684 else if (T.find("x86_64-") == 0)
685 return new DarwinX86_64TargetInfo(T);
686 else if (IsX86(T))
687 return new DarwinI386TargetInfo(T);
688 else if (T.find("bogusW16W16-") == 0) // For testing portability.
689 return new LinuxTargetInfo(T);
Chris Lattner4b009652007-07-25 00:24:17 +0000690 }
Ted Kremenek40499482007-12-03 22:06:55 +0000691 else {
692 // Make a copy of the triple that is all lowercase.
693 std::string T_lower(T);
694 std::transform(T_lower.begin(), T_lower.end(),
695 T_lower.begin(), (int(*)(int)) std::tolower);
696
697 if (T_lower.find("linux") != std::string::npos && IsX86(T))
698 return new LinuxTargetInfo(T);
699 }
700
701 assert (false && "Unknown target!");
Chris Lattner4b009652007-07-25 00:24:17 +0000702}
703
704/// CreateTargetInfo - Return the set of target info objects as specified by
705/// the -arch command line option.
Ted Kremenek40499482007-12-03 22:06:55 +0000706TargetInfo *clang::CreateTargetInfo(const std::vector<std::string>& triples,
707 Diagnostic &Diags) {
Chris Lattner4b009652007-07-25 00:24:17 +0000708
Ted Kremenek40499482007-12-03 22:06:55 +0000709 assert (!triples.empty() && "No target triple.");
710
Chris Lattner4b009652007-07-25 00:24:17 +0000711 // Create the primary target and target info.
Ted Kremenek40499482007-12-03 22:06:55 +0000712 TargetInfo *TI = new TargetInfo(CreateTarget(triples[0]), &Diags);
Chris Lattner4b009652007-07-25 00:24:17 +0000713
714 // Add all secondary targets.
Ted Kremenek40499482007-12-03 22:06:55 +0000715 for (unsigned i = 1, e = triples.size(); i != e; ++i)
716 TI->AddSecondaryTarget(CreateTarget(triples[i]));
717
Chris Lattner4b009652007-07-25 00:24:17 +0000718 return TI;
719}