blob: 400090871c84e4f5d224afea432b074469ee8cfb [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
Chris Lattner4b009652007-07-25 00:24:17 +000022using namespace clang;
23
Chris Lattner4b009652007-07-25 00:24:17 +000024//===----------------------------------------------------------------------===//
25// Common code shared among targets.
26//===----------------------------------------------------------------------===//
27
Chris Lattner0db667a2007-10-06 06:57:34 +000028static void Define(std::vector<char> &Buf, const char *Macro,
29 const char *Val = "1") {
30 const char *Def = "#define ";
31 Buf.insert(Buf.end(), Def, Def+strlen(Def));
32 Buf.insert(Buf.end(), Macro, Macro+strlen(Macro));
33 Buf.push_back(' ');
34 Buf.insert(Buf.end(), Val, Val+strlen(Val));
35 Buf.push_back('\n');
36}
37
38
Chris Lattner4b009652007-07-25 00:24:17 +000039namespace {
40class DarwinTargetInfo : public TargetInfoImpl {
41public:
Ted Kremenek40499482007-12-03 22:06:55 +000042 DarwinTargetInfo(const std::string& triple) : TargetInfoImpl(triple) {}
43
Chris Lattner0db667a2007-10-06 06:57:34 +000044 virtual void getTargetDefines(std::vector<char> &Defs) const {
Chris Lattner1ed172d2007-10-17 06:04:46 +000045// FIXME: we need a real target configuration system. For now, only define
46// __APPLE__ if the host has it.
47#ifdef __APPLE__
Chris Lattner0db667a2007-10-06 06:57:34 +000048 Define(Defs, "__APPLE__");
49 Define(Defs, "__MACH__");
Chris Lattner1ed172d2007-10-17 06:04:46 +000050#endif
Chris Lattner4b009652007-07-25 00:24:17 +000051
52 if (1) {// -fobjc-gc controls this.
Chris Lattner0db667a2007-10-06 06:57:34 +000053 Define(Defs, "__weak", "");
54 Define(Defs, "__strong", "");
Chris Lattner4b009652007-07-25 00:24:17 +000055 } else {
Chris Lattner0db667a2007-10-06 06:57:34 +000056 Define(Defs, "__weak", "__attribute__((objc_gc(weak)))");
57 Define(Defs, "__strong", "__attribute__((objc_gc(strong)))");
58 Define(Defs, "__OBJC_GC__");
Chris Lattner4b009652007-07-25 00:24:17 +000059 }
60
61 // darwin_constant_cfstrings controls this.
Chris Lattner0db667a2007-10-06 06:57:34 +000062 Define(Defs, "__CONSTANT_CFSTRINGS__");
Chris Lattner4b009652007-07-25 00:24:17 +000063
64 if (0) // darwin_pascal_strings
Chris Lattner0db667a2007-10-06 06:57:34 +000065 Define(Defs, "__PASCAL_STRINGS__");
Chris Lattner4b009652007-07-25 00:24:17 +000066 }
67
68};
69} // end anonymous namespace.
70
71
72/// getPowerPCDefines - Return a set of the PowerPC-specific #defines that are
73/// not tied to a specific subtarget.
Chris Lattner0db667a2007-10-06 06:57:34 +000074static void getPowerPCDefines(std::vector<char> &Defs, bool is64Bit) {
Chris Lattner4b009652007-07-25 00:24:17 +000075 // Target identification.
Chris Lattner0db667a2007-10-06 06:57:34 +000076 Define(Defs, "__ppc__");
77 Define(Defs, "_ARCH_PPC");
78 Define(Defs, "__POWERPC__");
Chris Lattner4b009652007-07-25 00:24:17 +000079 if (is64Bit) {
Chris Lattner0db667a2007-10-06 06:57:34 +000080 Define(Defs, "_ARCH_PPC64");
81 Define(Defs, "_LP64");
82 Define(Defs, "__LP64__");
83 Define(Defs, "__ppc64__");
Chris Lattner4b009652007-07-25 00:24:17 +000084 } else {
Chris Lattner0db667a2007-10-06 06:57:34 +000085 Define(Defs, "__ppc__");
Chris Lattner4b009652007-07-25 00:24:17 +000086 }
87
88 // Target properties.
Chris Lattner0db667a2007-10-06 06:57:34 +000089 Define(Defs, "_BIG_ENDIAN");
90 Define(Defs, "__BIG_ENDIAN__");
Chris Lattner4b009652007-07-25 00:24:17 +000091
92 if (is64Bit) {
Chris Lattner0db667a2007-10-06 06:57:34 +000093 Define(Defs, "__INTMAX_MAX__", "9223372036854775807L");
94 Define(Defs, "__INTMAX_TYPE__", "long int");
95 Define(Defs, "__LONG_MAX__", "9223372036854775807L");
96 Define(Defs, "__PTRDIFF_TYPE__", "long int");
97 Define(Defs, "__UINTMAX_TYPE__", "long unsigned int");
Chris Lattner4b009652007-07-25 00:24:17 +000098 } else {
Chris Lattner0db667a2007-10-06 06:57:34 +000099 Define(Defs, "__INTMAX_MAX__", "9223372036854775807LL");
100 Define(Defs, "__INTMAX_TYPE__", "long long int");
101 Define(Defs, "__LONG_MAX__", "2147483647L");
102 Define(Defs, "__PTRDIFF_TYPE__", "int");
103 Define(Defs, "__UINTMAX_TYPE__", "long long unsigned int");
Chris Lattner4b009652007-07-25 00:24:17 +0000104 }
Chris Lattner0db667a2007-10-06 06:57:34 +0000105 Define(Defs, "__INT_MAX__", "2147483647");
106 Define(Defs, "__LONG_LONG_MAX__", "9223372036854775807LL");
107 Define(Defs, "__CHAR_BIT__", "8");
108 Define(Defs, "__SCHAR_MAX__", "127");
109 Define(Defs, "__SHRT_MAX__", "32767");
110 Define(Defs, "__SIZE_TYPE__", "long unsigned int");
Chris Lattner4b009652007-07-25 00:24:17 +0000111
112 // Subtarget options.
Chris Lattner0db667a2007-10-06 06:57:34 +0000113 Define(Defs, "__USER_LABEL_PREFIX__", "_");
114 Define(Defs, "__NATURAL_ALIGNMENT__");
115 Define(Defs, "__REGISTER_PREFIX__", "");
Chris Lattner4b009652007-07-25 00:24:17 +0000116
Chris Lattner0db667a2007-10-06 06:57:34 +0000117 Define(Defs, "__WCHAR_MAX__", "2147483647");
118 Define(Defs, "__WCHAR_TYPE__", "int");
119 Define(Defs, "__WINT_TYPE__", "int");
Chris Lattner4b009652007-07-25 00:24:17 +0000120
121 // Float macros.
Chris Lattner0db667a2007-10-06 06:57:34 +0000122 Define(Defs, "__FLT_DENORM_MIN__", "1.40129846e-45F");
123 Define(Defs, "__FLT_DIG__", "6");
124 Define(Defs, "__FLT_EPSILON__", "1.19209290e-7F");
125 Define(Defs, "__FLT_EVAL_METHOD__", "0");
126 Define(Defs, "__FLT_HAS_INFINITY__");
127 Define(Defs, "__FLT_HAS_QUIET_NAN__");
128 Define(Defs, "__FLT_MANT_DIG__", "24");
129 Define(Defs, "__FLT_MAX_10_EXP__", "38");
130 Define(Defs, "__FLT_MAX_EXP__", "128");
131 Define(Defs, "__FLT_MAX__", "3.40282347e+38F");
132 Define(Defs, "__FLT_MIN_10_EXP__", "(-37)");
133 Define(Defs, "__FLT_MIN_EXP__", "(-125)");
134 Define(Defs, "__FLT_MIN__", "1.17549435e-38F");
135 Define(Defs, "__FLT_RADIX__", "2");
Chris Lattner4b009652007-07-25 00:24:17 +0000136
137 // double macros.
Chris Lattner0db667a2007-10-06 06:57:34 +0000138 Define(Defs, "__DBL_DENORM_MIN__", "4.9406564584124654e-324");
139 Define(Defs, "__DBL_DIG__", "15");
140 Define(Defs, "__DBL_EPSILON__", "2.2204460492503131e-16");
141 Define(Defs, "__DBL_HAS_INFINITY__");
142 Define(Defs, "__DBL_HAS_QUIET_NAN__");
143 Define(Defs, "__DBL_MANT_DIG__", "53");
144 Define(Defs, "__DBL_MAX_10_EXP__", "308");
145 Define(Defs, "__DBL_MAX_EXP__", "1024");
146 Define(Defs, "__DBL_MAX__", "1.7976931348623157e+308");
147 Define(Defs, "__DBL_MIN_10_EXP__", "(-307)");
148 Define(Defs, "__DBL_MIN_EXP__", "(-1021)");
149 Define(Defs, "__DBL_MIN__", "2.2250738585072014e-308");
150 Define(Defs, "__DECIMAL_DIG__", "33");
Chris Lattner4b009652007-07-25 00:24:17 +0000151
152 // 128-bit long double macros.
Chris Lattner0db667a2007-10-06 06:57:34 +0000153 Define(Defs, "__LDBL_DENORM_MIN__",
154 "4.94065645841246544176568792868221e-324L");
155 Define(Defs, "__LDBL_DIG__", "31");
156 Define(Defs, "__LDBL_EPSILON__",
157 "4.94065645841246544176568792868221e-324L");
158 Define(Defs, "__LDBL_HAS_INFINITY__");
159 Define(Defs, "__LDBL_HAS_QUIET_NAN__");
160 Define(Defs, "__LDBL_MANT_DIG__", "106");
161 Define(Defs, "__LDBL_MAX_10_EXP__", "308");
162 Define(Defs, "__LDBL_MAX_EXP__", "1024");
163 Define(Defs, "__LDBL_MAX__",
164 "1.79769313486231580793728971405301e+308L");
165 Define(Defs, "__LDBL_MIN_10_EXP__", "(-291)");
166 Define(Defs, "__LDBL_MIN_EXP__", "(-968)");
167 Define(Defs, "__LDBL_MIN__",
168 "2.00416836000897277799610805135016e-292L");
169 Define(Defs, "__LONG_DOUBLE_128__");
Chris Lattner4b009652007-07-25 00:24:17 +0000170}
171
172/// getX86Defines - Return a set of the X86-specific #defines that are
173/// not tied to a specific subtarget.
Chris Lattner0db667a2007-10-06 06:57:34 +0000174static void getX86Defines(std::vector<char> &Defs, bool is64Bit) {
Chris Lattner4b009652007-07-25 00:24:17 +0000175 // Target identification.
176 if (is64Bit) {
Chris Lattner0db667a2007-10-06 06:57:34 +0000177 Define(Defs, "_LP64");
178 Define(Defs, "__LP64__");
179 Define(Defs, "__amd64__");
180 Define(Defs, "__amd64");
181 Define(Defs, "__x86_64");
182 Define(Defs, "__x86_64__");
Chris Lattner4b009652007-07-25 00:24:17 +0000183 } else {
Chris Lattner0db667a2007-10-06 06:57:34 +0000184 Define(Defs, "__i386__");
185 Define(Defs, "__i386");
186 Define(Defs, "i386");
Chris Lattner4b009652007-07-25 00:24:17 +0000187 }
188
189 // Target properties.
Chris Lattner0db667a2007-10-06 06:57:34 +0000190 Define(Defs, "__LITTLE_ENDIAN__");
Chris Lattner4b009652007-07-25 00:24:17 +0000191
192 if (is64Bit) {
Chris Lattner0db667a2007-10-06 06:57:34 +0000193 Define(Defs, "__INTMAX_MAX__", "9223372036854775807L");
194 Define(Defs, "__INTMAX_TYPE__", "long int");
195 Define(Defs, "__LONG_MAX__", "9223372036854775807L");
196 Define(Defs, "__PTRDIFF_TYPE__", "long int");
197 Define(Defs, "__UINTMAX_TYPE__", "long unsigned int");
Chris Lattner4b009652007-07-25 00:24:17 +0000198 } else {
Chris Lattner0db667a2007-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");
Chris Lattner4b009652007-07-25 00:24:17 +0000204 }
Chris Lattner0db667a2007-10-06 06:57:34 +0000205 Define(Defs, "__CHAR_BIT__", "8");
206 Define(Defs, "__INT_MAX__", "2147483647");
207 Define(Defs, "__LONG_LONG_MAX__", "9223372036854775807LL");
208 Define(Defs, "__SCHAR_MAX__", "127");
209 Define(Defs, "__SHRT_MAX__", "32767");
210 Define(Defs, "__SIZE_TYPE__", "long unsigned int");
Chris Lattner4b009652007-07-25 00:24:17 +0000211
212 // Subtarget options.
Chris Lattner0db667a2007-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__", "");
Chris Lattner4b009652007-07-25 00:24:17 +0000222
Chris Lattner0db667a2007-10-06 06:57:34 +0000223 Define(Defs, "__WCHAR_MAX__", "2147483647");
224 Define(Defs, "__WCHAR_TYPE__", "int");
225 Define(Defs, "__WINT_TYPE__", "int");
Chris Lattner4b009652007-07-25 00:24:17 +0000226
227 // Float macros.
Chris Lattner0db667a2007-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");
Chris Lattner4b009652007-07-25 00:24:17 +0000242
243 // Double macros.
Chris Lattner0db667a2007-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");
Chris Lattner4b009652007-07-25 00:24:17 +0000257
258 // 80-bit Long double macros.
Chris Lattner0db667a2007-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");
Chris Lattner4b009652007-07-25 00:24:17 +0000271}
272
Anders Carlsson8b58e8a2007-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
Chris Lattner4b009652007-07-25 00:24:17 +0000299/// PPC builtin info.
300namespace PPC {
301 enum {
302 LastTIBuiltin = Builtin::FirstTSBuiltin-1,
303#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
304#include "PPCBuiltins.def"
305 LastTSBuiltin
306 };
307
308 static const Builtin::Info BuiltinInfo[] = {
309#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
310#include "PPCBuiltins.def"
311 };
312
313 static void getBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) {
314 Records = BuiltinInfo;
315 NumRecords = LastTSBuiltin-Builtin::FirstTSBuiltin;
316 }
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000317
318 static const char * const GCCRegNames[] = {
319 "0", "1", "2", "3", "4", "5", "6", "7",
320 "8", "9", "10", "11", "12", "13", "14", "15",
321 "16", "17", "18", "19", "20", "21", "22", "23",
322 "24", "25", "26", "27", "28", "29", "30", "31",
323 "0", "1", "2", "3", "4", "5", "6", "7",
324 "8", "9", "10", "11", "12", "13", "14", "15",
325 "16", "17", "18", "19", "20", "21", "22", "23",
326 "24", "25", "26", "27", "28", "29", "30", "31",
327 "mq", "lr", "ctr", "ap",
328 "0", "1", "2", "3", "4", "5", "6", "7",
329 "xer",
330 "0", "1", "2", "3", "4", "5", "6", "7",
331 "8", "9", "10", "11", "12", "13", "14", "15",
332 "16", "17", "18", "19", "20", "21", "22", "23",
333 "24", "25", "26", "27", "28", "29", "30", "31",
334 "vrsave", "vscr",
335 "spe_acc", "spefscr",
336 "sfp"
337 };
338
339 static void getGCCRegNames(const char * const *&Names,
340 unsigned &NumNames) {
341 Names = GCCRegNames;
342 NumNames = llvm::array_lengthof(GCCRegNames);
343 }
344
345 static const TargetInfoImpl::GCCRegAlias GCCRegAliases[] = {
346 // While some of these aliases do map to different registers
347 // they still share the same register name.
348 { { "cc", "cr0", "fr0", "r0", "v0"}, "0" },
349 { { "cr1", "fr1", "r1", "sp", "v1"}, "1" },
350 { { "cr2", "fr2", "r2", "toc", "v2"}, "2" },
351 { { "cr3", "fr3", "r3", "v3"}, "3" },
352 { { "cr4", "fr4", "r4", "v4"}, "4" },
353 { { "cr5", "fr5", "r5", "v5"}, "5" },
354 { { "cr6", "fr6", "r6", "v6"}, "6" },
355 { { "cr7", "fr7", "r7", "v7"}, "7" },
356 { { "fr8", "r8", "v8"}, "8" },
357 { { "fr9", "r9", "v9"}, "9" },
358 { { "fr10", "r10", "v10"}, "10" },
359 { { "fr11", "r11", "v11"}, "11" },
360 { { "fr12", "r12", "v12"}, "12" },
361 { { "fr13", "r13", "v13"}, "13" },
362 { { "fr14", "r14", "v14"}, "14" },
363 { { "fr15", "r15", "v15"}, "15" },
364 { { "fr16", "r16", "v16"}, "16" },
365 { { "fr17", "r17", "v17"}, "17" },
366 { { "fr18", "r18", "v18"}, "18" },
367 { { "fr19", "r19", "v19"}, "19" },
368 { { "fr20", "r20", "v20"}, "20" },
369 { { "fr21", "r21", "v21"}, "21" },
370 { { "fr22", "r22", "v22"}, "22" },
371 { { "fr23", "r23", "v23"}, "23" },
372 { { "fr24", "r24", "v24"}, "24" },
373 { { "fr25", "r25", "v25"}, "25" },
374 { { "fr26", "r26", "v26"}, "26" },
375 { { "fr27", "r27", "v27"}, "27" },
376 { { "fr28", "r28", "v28"}, "28" },
377 { { "fr29", "r29", "v29"}, "29" },
378 { { "fr30", "r30", "v30"}, "30" },
379 { { "fr31", "r31", "v31"}, "31" },
380 };
381
382 static void getGCCRegAliases(const TargetInfoImpl::GCCRegAlias *&Aliases,
383 unsigned &NumAliases) {
384 Aliases = GCCRegAliases;
385 NumAliases = llvm::array_lengthof(GCCRegAliases);
Anders Carlsson4ce42302007-11-27 04:11:28 +0000386 }
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000387
Anders Carlsson4ce42302007-11-27 04:11:28 +0000388 static bool validateAsmConstraint(char c,
389 TargetInfo::ConstraintInfo &info) {
390 switch (c) {
391 default: return false;
392 case 'O': // Zero
393 return true;
394 case 'b': // Base register
395 case 'f': // Floating point register
396 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
397 return true;
398 }
399 }
400
401 const char *getClobbers() {
402 return 0;
403 }
404
Anders Carlsson333052c2007-12-08 19:32:57 +0000405 const char *getTargetPrefix() {
406 return "ppc";
407 }
408
Chris Lattner4b009652007-07-25 00:24:17 +0000409} // End namespace PPC
410
411
412/// X86 builtin info.
413namespace X86 {
414 enum {
415 LastTIBuiltin = Builtin::FirstTSBuiltin-1,
416#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
417#include "X86Builtins.def"
418 LastTSBuiltin
419 };
420
421 static const Builtin::Info BuiltinInfo[] = {
422#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
423#include "X86Builtins.def"
424 };
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000425
Chris Lattner4b009652007-07-25 00:24:17 +0000426
427 static void getBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) {
428 Records = BuiltinInfo;
429 NumRecords = LastTSBuiltin-Builtin::FirstTSBuiltin;
430 }
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000431
432 static const char *GCCRegNames[] = {
433 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
434 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
Anders Carlssonc411b492007-11-25 00:23:10 +0000435 "argp", "flags", "fspr", "dirflag", "frame",
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000436 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
437 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
438 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
439 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
440 };
441
442 static void getGCCRegNames(const char * const *&Names,
443 unsigned &NumNames) {
444 Names = GCCRegNames;
445 NumNames = llvm::array_lengthof(GCCRegNames);
446 }
447
448 static const TargetInfoImpl::GCCRegAlias GCCRegAliases[] = {
449 { { "al", "ah", "eax", "rax" }, "ax" },
450 { { "bl", "bh", "ebx", "rbx" }, "bx" },
451 { { "cl", "ch", "ecx", "rcx" }, "cx" },
452 { { "dl", "dh", "edx", "rdx" }, "dx" },
453 { { "esi", "rsi" }, "si" },
454 { { "esp", "rsp" }, "sp" },
455 { { "ebp", "rbp" }, "bp" },
456 };
457
458 static void getGCCRegAliases(const TargetInfoImpl::GCCRegAlias *&Aliases,
459 unsigned &NumAliases) {
460 Aliases = GCCRegAliases;
461 NumAliases = llvm::array_lengthof(GCCRegAliases);
462 }
463
Anders Carlsson4ce42302007-11-27 04:11:28 +0000464 static bool validateAsmConstraint(char c,
465 TargetInfo::ConstraintInfo &info) {
466 switch (c) {
467 default: return false;
468 case 'a': // eax.
469 case 'b': // ebx.
470 case 'c': // ecx.
471 case 'd': // edx.
472 case 'S': // esi.
473 case 'D': // edi.
474 case 'A': // edx:eax.
475 case 't': // top of floating point stack.
476 case 'u': // second from top of floating point stack.
477 case 'q': // a, b, c, d registers or any integer register in 64-bit.
478 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
479 return true;
480 }
481 }
482
483 const char *getClobbers() {
484 return "~{dirflag},~{fpsr},~{flags}";
485 }
486
Anders Carlsson333052c2007-12-08 19:32:57 +0000487 const char *getTargetPrefix() {
488 return "x86";
489 }
490
Chris Lattner4b009652007-07-25 00:24:17 +0000491} // End namespace X86
492
493//===----------------------------------------------------------------------===//
494// Specific target implementations.
495//===----------------------------------------------------------------------===//
496
497
498namespace {
499class DarwinPPCTargetInfo : public DarwinTargetInfo {
500public:
Ted Kremenek40499482007-12-03 22:06:55 +0000501 DarwinPPCTargetInfo(const std::string& triple) : DarwinTargetInfo(triple) {}
502
Chris Lattner0db667a2007-10-06 06:57:34 +0000503 virtual void getTargetDefines(std::vector<char> &Defines) const {
Chris Lattner4b009652007-07-25 00:24:17 +0000504 DarwinTargetInfo::getTargetDefines(Defines);
505 getPowerPCDefines(Defines, false);
506 }
507 virtual void getTargetBuiltins(const Builtin::Info *&Records,
508 unsigned &NumRecords) const {
509 PPC::getBuiltins(Records, NumRecords);
510 }
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000511 virtual const char *getVAListDeclaration() const {
512 return getPPCVAListDeclaration();
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000513 }
Anders Carlsson333052c2007-12-08 19:32:57 +0000514 virtual const char *getTargetPrefix() const {
515 return PPC::getTargetPrefix();
516 }
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000517 virtual void getGCCRegNames(const char * const *&Names,
518 unsigned &NumNames) const {
519 PPC::getGCCRegNames(Names, NumNames);
520 }
521 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
522 unsigned &NumAliases) const {
523 PPC::getGCCRegAliases(Aliases, NumAliases);
524 }
Anders Carlsson4ce42302007-11-27 04:11:28 +0000525 virtual bool validateAsmConstraint(char c,
526 TargetInfo::ConstraintInfo &info) const {
527 return PPC::validateAsmConstraint(c, info);
528 }
529 virtual const char *getClobbers() const {
530 return PPC::getClobbers();
531 }
Chris Lattner4b009652007-07-25 00:24:17 +0000532};
533} // end anonymous namespace.
534
535namespace {
536class DarwinPPC64TargetInfo : public DarwinTargetInfo {
537public:
Ted Kremenek40499482007-12-03 22:06:55 +0000538 DarwinPPC64TargetInfo(const std::string& triple) : DarwinTargetInfo(triple) {}
539
Chris Lattner0db667a2007-10-06 06:57:34 +0000540 virtual void getTargetDefines(std::vector<char> &Defines) const {
Chris Lattner4b009652007-07-25 00:24:17 +0000541 DarwinTargetInfo::getTargetDefines(Defines);
542 getPowerPCDefines(Defines, true);
543 }
544 virtual void getTargetBuiltins(const Builtin::Info *&Records,
545 unsigned &NumRecords) const {
546 PPC::getBuiltins(Records, NumRecords);
547 }
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000548 virtual const char *getVAListDeclaration() const {
549 return getPPCVAListDeclaration();
550 }
Anders Carlsson333052c2007-12-08 19:32:57 +0000551 virtual const char *getTargetPrefix() const {
552 return PPC::getTargetPrefix();
553 }
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000554 virtual void getGCCRegNames(const char * const *&Names,
555 unsigned &NumNames) const {
556 PPC::getGCCRegNames(Names, NumNames);
557 }
558 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
559 unsigned &NumAliases) const {
560 PPC::getGCCRegAliases(Aliases, NumAliases);
561 }
Anders Carlsson4ce42302007-11-27 04:11:28 +0000562 virtual bool validateAsmConstraint(char c,
563 TargetInfo::ConstraintInfo &info) const {
564 return PPC::validateAsmConstraint(c, info);
565 }
566 virtual const char *getClobbers() const {
567 return PPC::getClobbers();
568 }
Chris Lattner4b009652007-07-25 00:24:17 +0000569};
570} // end anonymous namespace.
571
572namespace {
573class DarwinI386TargetInfo : public DarwinTargetInfo {
574public:
Ted Kremenek40499482007-12-03 22:06:55 +0000575 DarwinI386TargetInfo(const std::string& triple) : DarwinTargetInfo(triple) {}
576
Chris Lattner0db667a2007-10-06 06:57:34 +0000577 virtual void getTargetDefines(std::vector<char> &Defines) const {
Chris Lattner4b009652007-07-25 00:24:17 +0000578 DarwinTargetInfo::getTargetDefines(Defines);
579 getX86Defines(Defines, false);
580 }
581 virtual void getTargetBuiltins(const Builtin::Info *&Records,
582 unsigned &NumRecords) const {
583 X86::getBuiltins(Records, NumRecords);
584 }
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000585 virtual const char *getVAListDeclaration() const {
586 return getI386VAListDeclaration();
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000587 }
Anders Carlsson333052c2007-12-08 19:32:57 +0000588 virtual const char *getTargetPrefix() const {
589 return X86::getTargetPrefix();
590 }
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000591 virtual void getGCCRegNames(const char * const *&Names,
592 unsigned &NumNames) const {
593 X86::getGCCRegNames(Names, NumNames);
594 }
595 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
596 unsigned &NumAliases) const {
597 X86::getGCCRegAliases(Aliases, NumAliases);
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000598 }
Anders Carlsson4ce42302007-11-27 04:11:28 +0000599 virtual bool validateAsmConstraint(char c,
600 TargetInfo::ConstraintInfo &info) const {
601 return X86::validateAsmConstraint(c, info);
602 }
603 virtual const char *getClobbers() const {
604 return X86::getClobbers();
605 }
Chris Lattner4b009652007-07-25 00:24:17 +0000606};
607} // end anonymous namespace.
608
609namespace {
610class DarwinX86_64TargetInfo : public DarwinTargetInfo {
611public:
Ted Kremenek40499482007-12-03 22:06:55 +0000612 DarwinX86_64TargetInfo(const std::string& triple) :DarwinTargetInfo(triple) {}
613
Chris Lattner0db667a2007-10-06 06:57:34 +0000614 virtual void getTargetDefines(std::vector<char> &Defines) const {
Chris Lattner4b009652007-07-25 00:24:17 +0000615 DarwinTargetInfo::getTargetDefines(Defines);
616 getX86Defines(Defines, true);
617 }
618 virtual void getTargetBuiltins(const Builtin::Info *&Records,
619 unsigned &NumRecords) const {
620 X86::getBuiltins(Records, NumRecords);
621 }
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000622 virtual const char *getVAListDeclaration() const {
623 return getX86_64VAListDeclaration();
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000624 }
Anders Carlsson333052c2007-12-08 19:32:57 +0000625 virtual const char *getTargetPrefix() const {
626 return X86::getTargetPrefix();
627 }
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000628 virtual void getGCCRegNames(const char * const *&Names,
629 unsigned &NumNames) const {
630 X86::getGCCRegNames(Names, NumNames);
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000631 }
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000632 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
633 unsigned &NumAliases) const {
634 X86::getGCCRegAliases(Aliases, NumAliases);
635 }
Anders Carlsson4ce42302007-11-27 04:11:28 +0000636 virtual bool validateAsmConstraint(char c,
637 TargetInfo::ConstraintInfo &info) const {
638 return X86::validateAsmConstraint(c, info);
639 }
640 virtual const char *getClobbers() const {
641 return X86::getClobbers();
642 }
Chris Lattner4b009652007-07-25 00:24:17 +0000643};
644} // end anonymous namespace.
645
646namespace {
647class LinuxTargetInfo : public DarwinTargetInfo {
648public:
Ted Kremenek40499482007-12-03 22:06:55 +0000649 LinuxTargetInfo(const std::string& triple) : DarwinTargetInfo(triple) {
Chris Lattner4b009652007-07-25 00:24:17 +0000650 // Note: I have no idea if this is right, just for testing.
651 WCharWidth = 16;
652 WCharAlign = 16;
653 }
654
Chris Lattner0db667a2007-10-06 06:57:34 +0000655 virtual void getTargetDefines(std::vector<char> &Defines) const {
Chris Lattner4b009652007-07-25 00:24:17 +0000656 // TODO: linux-specific stuff.
657 getX86Defines(Defines, false);
658 }
659 virtual void getTargetBuiltins(const Builtin::Info *&Records,
660 unsigned &NumRecords) const {
661 X86::getBuiltins(Records, NumRecords);
662 }
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000663 virtual const char *getVAListDeclaration() const {
664 return getI386VAListDeclaration();
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000665 }
Anders Carlsson333052c2007-12-08 19:32:57 +0000666 virtual const char *getTargetPrefix() const {
667 return X86::getTargetPrefix();
668 }
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000669 virtual void getGCCRegNames(const char * const *&Names,
670 unsigned &NumNames) const {
671 X86::getGCCRegNames(Names, NumNames);
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000672 }
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000673 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
674 unsigned &NumAliases) const {
675 X86::getGCCRegAliases(Aliases, NumAliases);
676 }
Anders Carlsson4ce42302007-11-27 04:11:28 +0000677 virtual bool validateAsmConstraint(char c,
678 TargetInfo::ConstraintInfo &info) const {
679 return X86::validateAsmConstraint(c, info);
680 }
681 virtual const char *getClobbers() const {
682 return X86::getClobbers();
683 }
Chris Lattner4b009652007-07-25 00:24:17 +0000684};
685} // end anonymous namespace.
686
687
688//===----------------------------------------------------------------------===//
689// Driver code
690//===----------------------------------------------------------------------===//
691
Ted Kremenekb97d7672007-12-04 17:07:35 +0000692static inline bool IsX86(const std::string& TT) {
Ted Kremenek40499482007-12-03 22:06:55 +0000693 return (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' &&
694 TT[4] == '-' && TT[1] - '3' < 6);
695}
696
Chris Lattner4b009652007-07-25 00:24:17 +0000697/// CreateTarget - Create the TargetInfoImpl object for the specified target
698/// enum value.
Ted Kremenek40499482007-12-03 22:06:55 +0000699static TargetInfoImpl *CreateTarget(const std::string& T) {
Chris Lattner2c63b9f2007-12-05 18:41:05 +0000700 if (T.find("ppc-") == 0 || T.find("powerpc-") == 0)
Ted Kremenekb97d7672007-12-04 17:07:35 +0000701 return new DarwinPPCTargetInfo(T);
Chris Lattner2c63b9f2007-12-05 18:41:05 +0000702 else if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0)
Ted Kremenekb97d7672007-12-04 17:07:35 +0000703 return new DarwinPPC64TargetInfo(T);
704 else if (T.find("x86_64-") == 0)
705 return new DarwinX86_64TargetInfo(T);
706 else if (IsX86(T))
707 return new DarwinI386TargetInfo(T);
708 else if (T.find("bogusW16W16-") == 0) // For testing portability.
709 return new LinuxTargetInfo(T);
710 else
711 return NULL;
Chris Lattner4b009652007-07-25 00:24:17 +0000712}
713
714/// CreateTargetInfo - Return the set of target info objects as specified by
715/// the -arch command line option.
Ted Kremenek40499482007-12-03 22:06:55 +0000716TargetInfo *clang::CreateTargetInfo(const std::vector<std::string>& triples,
Ted Kremenek2939b8a2007-12-05 21:34:36 +0000717 Diagnostic *Diags) {
Chris Lattner4b009652007-07-25 00:24:17 +0000718
Ted Kremenek40499482007-12-03 22:06:55 +0000719 assert (!triples.empty() && "No target triple.");
720
Chris Lattner4b009652007-07-25 00:24:17 +0000721 // Create the primary target and target info.
Ted Kremenekae51f692007-12-03 23:23:21 +0000722 TargetInfoImpl* PrimaryTarget = CreateTarget(triples[0]);
723
724 if (!PrimaryTarget)
725 return NULL;
726
Ted Kremenek2939b8a2007-12-05 21:34:36 +0000727 TargetInfo *TI = new TargetInfo(PrimaryTarget, Diags);
Chris Lattner4b009652007-07-25 00:24:17 +0000728
729 // Add all secondary targets.
Ted Kremenekae51f692007-12-03 23:23:21 +0000730 for (unsigned i = 1, e = triples.size(); i != e; ++i) {
731 TargetInfoImpl* SecondaryTarget = CreateTarget(triples[i]);
732
733 if (!SecondaryTarget) {
734 fprintf (stderr, "Warning: secondary target '%s' unrecognized.\n",
735 triples[i].c_str());
736 continue;
737 }
738
Ted Kremenek40499482007-12-03 22:06:55 +0000739 TI->AddSecondaryTarget(CreateTarget(triples[i]));
Ted Kremenekae51f692007-12-03 23:23:21 +0000740 }
Ted Kremenek40499482007-12-03 22:06:55 +0000741
Chris Lattner4b009652007-07-25 00:24:17 +0000742 return TI;
743}