blob: 336beb925d07f84c9507571c618247966fed20dd [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//
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 Carlsson3346ae62007-11-24 23:38:12 +000019#include "llvm/ADT/STLExtras.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000020#include "llvm/Support/CommandLine.h"
Ted Kremenekae360762007-12-03 22:06:55 +000021
Reid Spencer5f016e22007-07-11 17:01:13 +000022using namespace clang;
23
Reid Spencer5f016e22007-07-11 17:01:13 +000024//===----------------------------------------------------------------------===//
25// Common code shared among targets.
26//===----------------------------------------------------------------------===//
27
Chris Lattnerd15fa822007-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
Reid Spencer5f016e22007-07-11 17:01:13 +000039namespace {
40class DarwinTargetInfo : public TargetInfoImpl {
41public:
Ted Kremenekae360762007-12-03 22:06:55 +000042 DarwinTargetInfo(const std::string& triple) : TargetInfoImpl(triple) {}
43
Chris Lattnerd15fa822007-10-06 06:57:34 +000044 virtual void getTargetDefines(std::vector<char> &Defs) const {
Chris Lattner338128b2007-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 Lattnerd15fa822007-10-06 06:57:34 +000048 Define(Defs, "__APPLE__");
49 Define(Defs, "__MACH__");
Chris Lattner338128b2007-10-17 06:04:46 +000050#endif
Reid Spencer5f016e22007-07-11 17:01:13 +000051
52 if (1) {// -fobjc-gc controls this.
Chris Lattnerd15fa822007-10-06 06:57:34 +000053 Define(Defs, "__weak", "");
54 Define(Defs, "__strong", "");
Reid Spencer5f016e22007-07-11 17:01:13 +000055 } else {
Chris Lattnerd15fa822007-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__");
Reid Spencer5f016e22007-07-11 17:01:13 +000059 }
60
61 // darwin_constant_cfstrings controls this.
Chris Lattnerd15fa822007-10-06 06:57:34 +000062 Define(Defs, "__CONSTANT_CFSTRINGS__");
Reid Spencer5f016e22007-07-11 17:01:13 +000063
64 if (0) // darwin_pascal_strings
Chris Lattnerd15fa822007-10-06 06:57:34 +000065 Define(Defs, "__PASCAL_STRINGS__");
Reid Spencer5f016e22007-07-11 17:01:13 +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 Lattnerd15fa822007-10-06 06:57:34 +000074static void getPowerPCDefines(std::vector<char> &Defs, bool is64Bit) {
Reid Spencer5f016e22007-07-11 17:01:13 +000075 // Target identification.
Chris Lattnerd15fa822007-10-06 06:57:34 +000076 Define(Defs, "__ppc__");
77 Define(Defs, "_ARCH_PPC");
78 Define(Defs, "__POWERPC__");
Reid Spencer5f016e22007-07-11 17:01:13 +000079 if (is64Bit) {
Chris Lattnerd15fa822007-10-06 06:57:34 +000080 Define(Defs, "_ARCH_PPC64");
81 Define(Defs, "_LP64");
82 Define(Defs, "__LP64__");
83 Define(Defs, "__ppc64__");
Reid Spencer5f016e22007-07-11 17:01:13 +000084 } else {
Chris Lattnerd15fa822007-10-06 06:57:34 +000085 Define(Defs, "__ppc__");
Reid Spencer5f016e22007-07-11 17:01:13 +000086 }
87
88 // Target properties.
Chris Lattnerd15fa822007-10-06 06:57:34 +000089 Define(Defs, "_BIG_ENDIAN");
90 Define(Defs, "__BIG_ENDIAN__");
Reid Spencer5f016e22007-07-11 17:01:13 +000091
92 if (is64Bit) {
Chris Lattnerd15fa822007-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");
Reid Spencer5f016e22007-07-11 17:01:13 +000098 } else {
Chris Lattnerd15fa822007-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");
Reid Spencer5f016e22007-07-11 17:01:13 +0000104 }
Chris Lattnerd15fa822007-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");
Reid Spencer5f016e22007-07-11 17:01:13 +0000111
112 // Subtarget options.
Chris Lattnerd15fa822007-10-06 06:57:34 +0000113 Define(Defs, "__USER_LABEL_PREFIX__", "_");
114 Define(Defs, "__NATURAL_ALIGNMENT__");
115 Define(Defs, "__REGISTER_PREFIX__", "");
Reid Spencer5f016e22007-07-11 17:01:13 +0000116
Chris Lattnerd15fa822007-10-06 06:57:34 +0000117 Define(Defs, "__WCHAR_MAX__", "2147483647");
118 Define(Defs, "__WCHAR_TYPE__", "int");
119 Define(Defs, "__WINT_TYPE__", "int");
Reid Spencer5f016e22007-07-11 17:01:13 +0000120
121 // Float macros.
Chris Lattnerd15fa822007-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");
Reid Spencer5f016e22007-07-11 17:01:13 +0000136
137 // double macros.
Chris Lattnerd15fa822007-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");
Reid Spencer5f016e22007-07-11 17:01:13 +0000151
152 // 128-bit long double macros.
Chris Lattnerd15fa822007-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__");
Reid Spencer5f016e22007-07-11 17:01:13 +0000170}
171
172/// getX86Defines - Return a set of the X86-specific #defines that are
173/// not tied to a specific subtarget.
Chris Lattnerd15fa822007-10-06 06:57:34 +0000174static void getX86Defines(std::vector<char> &Defs, bool is64Bit) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000175 // Target identification.
176 if (is64Bit) {
Chris Lattnerd15fa822007-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__");
Reid Spencer5f016e22007-07-11 17:01:13 +0000183 } else {
Chris Lattnerd15fa822007-10-06 06:57:34 +0000184 Define(Defs, "__i386__");
185 Define(Defs, "__i386");
186 Define(Defs, "i386");
Reid Spencer5f016e22007-07-11 17:01:13 +0000187 }
188
189 // Target properties.
Chris Lattnerd15fa822007-10-06 06:57:34 +0000190 Define(Defs, "__LITTLE_ENDIAN__");
Reid Spencer5f016e22007-07-11 17:01:13 +0000191
192 if (is64Bit) {
Chris Lattnerd15fa822007-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");
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");
Reid Spencer5f016e22007-07-11 17:01:13 +0000204 }
Chris Lattnerd15fa822007-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");
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.
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 Carlsson3346ae62007-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 Carlssond04c6e22007-11-27 04:11:28 +0000386 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000387
Anders Carlssond04c6e22007-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
Reid Spencer5f016e22007-07-11 17:01:13 +0000405} // End namespace PPC
406
407
408/// X86 builtin info.
409namespace X86 {
410 enum {
411 LastTIBuiltin = Builtin::FirstTSBuiltin-1,
412#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
413#include "X86Builtins.def"
414 LastTSBuiltin
415 };
416
417 static const Builtin::Info BuiltinInfo[] = {
418#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
419#include "X86Builtins.def"
420 };
Anders Carlsson3346ae62007-11-24 23:38:12 +0000421
Reid Spencer5f016e22007-07-11 17:01:13 +0000422
423 static void getBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) {
424 Records = BuiltinInfo;
425 NumRecords = LastTSBuiltin-Builtin::FirstTSBuiltin;
426 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000427
428 static const char *GCCRegNames[] = {
429 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
430 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
Anders Carlsson646b2612007-11-25 00:23:10 +0000431 "argp", "flags", "fspr", "dirflag", "frame",
Anders Carlsson3346ae62007-11-24 23:38:12 +0000432 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
433 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
434 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
435 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
436 };
437
438 static void getGCCRegNames(const char * const *&Names,
439 unsigned &NumNames) {
440 Names = GCCRegNames;
441 NumNames = llvm::array_lengthof(GCCRegNames);
442 }
443
444 static const TargetInfoImpl::GCCRegAlias GCCRegAliases[] = {
445 { { "al", "ah", "eax", "rax" }, "ax" },
446 { { "bl", "bh", "ebx", "rbx" }, "bx" },
447 { { "cl", "ch", "ecx", "rcx" }, "cx" },
448 { { "dl", "dh", "edx", "rdx" }, "dx" },
449 { { "esi", "rsi" }, "si" },
450 { { "esp", "rsp" }, "sp" },
451 { { "ebp", "rbp" }, "bp" },
452 };
453
454 static void getGCCRegAliases(const TargetInfoImpl::GCCRegAlias *&Aliases,
455 unsigned &NumAliases) {
456 Aliases = GCCRegAliases;
457 NumAliases = llvm::array_lengthof(GCCRegAliases);
458 }
459
Anders Carlssond04c6e22007-11-27 04:11:28 +0000460 static bool validateAsmConstraint(char c,
461 TargetInfo::ConstraintInfo &info) {
462 switch (c) {
463 default: return false;
464 case 'a': // eax.
465 case 'b': // ebx.
466 case 'c': // ecx.
467 case 'd': // edx.
468 case 'S': // esi.
469 case 'D': // edi.
470 case 'A': // edx:eax.
471 case 't': // top of floating point stack.
472 case 'u': // second from top of floating point stack.
473 case 'q': // a, b, c, d registers or any integer register in 64-bit.
474 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
475 return true;
476 }
477 }
478
479 const char *getClobbers() {
480 return "~{dirflag},~{fpsr},~{flags}";
481 }
482
Reid Spencer5f016e22007-07-11 17:01:13 +0000483} // End namespace X86
484
485//===----------------------------------------------------------------------===//
486// Specific target implementations.
487//===----------------------------------------------------------------------===//
488
489
490namespace {
491class DarwinPPCTargetInfo : public DarwinTargetInfo {
492public:
Ted Kremenekae360762007-12-03 22:06:55 +0000493 DarwinPPCTargetInfo(const std::string& triple) : DarwinTargetInfo(triple) {}
494
Chris Lattnerd15fa822007-10-06 06:57:34 +0000495 virtual void getTargetDefines(std::vector<char> &Defines) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000496 DarwinTargetInfo::getTargetDefines(Defines);
497 getPowerPCDefines(Defines, false);
498 }
499 virtual void getTargetBuiltins(const Builtin::Info *&Records,
500 unsigned &NumRecords) const {
501 PPC::getBuiltins(Records, NumRecords);
502 }
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000503 virtual const char *getVAListDeclaration() const {
504 return getPPCVAListDeclaration();
Anders Carlsson3346ae62007-11-24 23:38:12 +0000505 }
506 virtual void getGCCRegNames(const char * const *&Names,
507 unsigned &NumNames) const {
508 PPC::getGCCRegNames(Names, NumNames);
509 }
510 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
511 unsigned &NumAliases) const {
512 PPC::getGCCRegAliases(Aliases, NumAliases);
513 }
Anders Carlssond04c6e22007-11-27 04:11:28 +0000514 virtual bool validateAsmConstraint(char c,
515 TargetInfo::ConstraintInfo &info) const {
516 return PPC::validateAsmConstraint(c, info);
517 }
518 virtual const char *getClobbers() const {
519 return PPC::getClobbers();
520 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000521};
522} // end anonymous namespace.
523
524namespace {
525class DarwinPPC64TargetInfo : public DarwinTargetInfo {
526public:
Ted Kremenekae360762007-12-03 22:06:55 +0000527 DarwinPPC64TargetInfo(const std::string& triple) : DarwinTargetInfo(triple) {}
528
Chris Lattnerd15fa822007-10-06 06:57:34 +0000529 virtual void getTargetDefines(std::vector<char> &Defines) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000530 DarwinTargetInfo::getTargetDefines(Defines);
531 getPowerPCDefines(Defines, true);
532 }
533 virtual void getTargetBuiltins(const Builtin::Info *&Records,
534 unsigned &NumRecords) const {
535 PPC::getBuiltins(Records, NumRecords);
536 }
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000537 virtual const char *getVAListDeclaration() const {
538 return getPPCVAListDeclaration();
539 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000540 virtual void getGCCRegNames(const char * const *&Names,
541 unsigned &NumNames) const {
542 PPC::getGCCRegNames(Names, NumNames);
543 }
544 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
545 unsigned &NumAliases) const {
546 PPC::getGCCRegAliases(Aliases, NumAliases);
547 }
Anders Carlssond04c6e22007-11-27 04:11:28 +0000548 virtual bool validateAsmConstraint(char c,
549 TargetInfo::ConstraintInfo &info) const {
550 return PPC::validateAsmConstraint(c, info);
551 }
552 virtual const char *getClobbers() const {
553 return PPC::getClobbers();
554 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000555};
556} // end anonymous namespace.
557
558namespace {
559class DarwinI386TargetInfo : public DarwinTargetInfo {
560public:
Ted Kremenekae360762007-12-03 22:06:55 +0000561 DarwinI386TargetInfo(const std::string& triple) : DarwinTargetInfo(triple) {}
562
Chris Lattnerd15fa822007-10-06 06:57:34 +0000563 virtual void getTargetDefines(std::vector<char> &Defines) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000564 DarwinTargetInfo::getTargetDefines(Defines);
565 getX86Defines(Defines, false);
566 }
567 virtual void getTargetBuiltins(const Builtin::Info *&Records,
568 unsigned &NumRecords) const {
569 X86::getBuiltins(Records, NumRecords);
570 }
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000571 virtual const char *getVAListDeclaration() const {
572 return getI386VAListDeclaration();
Anders Carlsson3346ae62007-11-24 23:38:12 +0000573 }
574 virtual void getGCCRegNames(const char * const *&Names,
575 unsigned &NumNames) const {
576 X86::getGCCRegNames(Names, NumNames);
577 }
578 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
579 unsigned &NumAliases) const {
580 X86::getGCCRegAliases(Aliases, NumAliases);
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000581 }
Anders Carlssond04c6e22007-11-27 04:11:28 +0000582 virtual bool validateAsmConstraint(char c,
583 TargetInfo::ConstraintInfo &info) const {
584 return X86::validateAsmConstraint(c, info);
585 }
586 virtual const char *getClobbers() const {
587 return X86::getClobbers();
588 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000589};
590} // end anonymous namespace.
591
592namespace {
593class DarwinX86_64TargetInfo : public DarwinTargetInfo {
594public:
Ted Kremenekae360762007-12-03 22:06:55 +0000595 DarwinX86_64TargetInfo(const std::string& triple) :DarwinTargetInfo(triple) {}
596
Chris Lattnerd15fa822007-10-06 06:57:34 +0000597 virtual void getTargetDefines(std::vector<char> &Defines) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000598 DarwinTargetInfo::getTargetDefines(Defines);
599 getX86Defines(Defines, true);
600 }
601 virtual void getTargetBuiltins(const Builtin::Info *&Records,
602 unsigned &NumRecords) const {
603 X86::getBuiltins(Records, NumRecords);
604 }
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000605 virtual const char *getVAListDeclaration() const {
606 return getX86_64VAListDeclaration();
Anders Carlsson3346ae62007-11-24 23:38:12 +0000607 }
608 virtual void getGCCRegNames(const char * const *&Names,
609 unsigned &NumNames) const {
610 X86::getGCCRegNames(Names, NumNames);
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000611 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000612 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
613 unsigned &NumAliases) const {
614 X86::getGCCRegAliases(Aliases, NumAliases);
615 }
Anders Carlssond04c6e22007-11-27 04:11:28 +0000616 virtual bool validateAsmConstraint(char c,
617 TargetInfo::ConstraintInfo &info) const {
618 return X86::validateAsmConstraint(c, info);
619 }
620 virtual const char *getClobbers() const {
621 return X86::getClobbers();
622 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000623};
624} // end anonymous namespace.
625
626namespace {
627class LinuxTargetInfo : public DarwinTargetInfo {
628public:
Ted Kremenekae360762007-12-03 22:06:55 +0000629 LinuxTargetInfo(const std::string& triple) : DarwinTargetInfo(triple) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000630 // Note: I have no idea if this is right, just for testing.
631 WCharWidth = 16;
Chris Lattnerd2d2a112007-07-14 01:29:45 +0000632 WCharAlign = 16;
Reid Spencer5f016e22007-07-11 17:01:13 +0000633 }
634
Chris Lattnerd15fa822007-10-06 06:57:34 +0000635 virtual void getTargetDefines(std::vector<char> &Defines) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000636 // TODO: linux-specific stuff.
637 getX86Defines(Defines, false);
638 }
639 virtual void getTargetBuiltins(const Builtin::Info *&Records,
640 unsigned &NumRecords) const {
641 X86::getBuiltins(Records, NumRecords);
642 }
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000643 virtual const char *getVAListDeclaration() const {
644 return getI386VAListDeclaration();
Anders Carlsson3346ae62007-11-24 23:38:12 +0000645 }
646 virtual void getGCCRegNames(const char * const *&Names,
647 unsigned &NumNames) const {
648 X86::getGCCRegNames(Names, NumNames);
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000649 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000650 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
651 unsigned &NumAliases) const {
652 X86::getGCCRegAliases(Aliases, NumAliases);
653 }
Anders Carlssond04c6e22007-11-27 04:11:28 +0000654 virtual bool validateAsmConstraint(char c,
655 TargetInfo::ConstraintInfo &info) const {
656 return X86::validateAsmConstraint(c, info);
657 }
658 virtual const char *getClobbers() const {
659 return X86::getClobbers();
660 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000661};
662} // end anonymous namespace.
663
664
665//===----------------------------------------------------------------------===//
666// Driver code
667//===----------------------------------------------------------------------===//
668
Ted Kremenek8448d382007-12-04 17:07:35 +0000669static inline bool IsX86(const std::string& TT) {
Ted Kremenekae360762007-12-03 22:06:55 +0000670 return (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' &&
671 TT[4] == '-' && TT[1] - '3' < 6);
672}
673
Reid Spencer5f016e22007-07-11 17:01:13 +0000674/// CreateTarget - Create the TargetInfoImpl object for the specified target
675/// enum value.
Ted Kremenekae360762007-12-03 22:06:55 +0000676static TargetInfoImpl *CreateTarget(const std::string& T) {
Chris Lattner82817ba2007-12-05 18:41:05 +0000677 if (T.find("ppc-") == 0 || T.find("powerpc-") == 0)
Ted Kremenek8448d382007-12-04 17:07:35 +0000678 return new DarwinPPCTargetInfo(T);
Chris Lattner82817ba2007-12-05 18:41:05 +0000679 else if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0)
Ted Kremenek8448d382007-12-04 17:07:35 +0000680 return new DarwinPPC64TargetInfo(T);
681 else if (T.find("x86_64-") == 0)
682 return new DarwinX86_64TargetInfo(T);
683 else if (IsX86(T))
684 return new DarwinI386TargetInfo(T);
685 else if (T.find("bogusW16W16-") == 0) // For testing portability.
686 return new LinuxTargetInfo(T);
687 else
688 return NULL;
Reid Spencer5f016e22007-07-11 17:01:13 +0000689}
690
691/// CreateTargetInfo - Return the set of target info objects as specified by
692/// the -arch command line option.
Ted Kremenekae360762007-12-03 22:06:55 +0000693TargetInfo *clang::CreateTargetInfo(const std::vector<std::string>& triples,
694 Diagnostic &Diags) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000695
Ted Kremenekae360762007-12-03 22:06:55 +0000696 assert (!triples.empty() && "No target triple.");
697
Reid Spencer5f016e22007-07-11 17:01:13 +0000698 // Create the primary target and target info.
Ted Kremenekaead4722007-12-03 23:23:21 +0000699 TargetInfoImpl* PrimaryTarget = CreateTarget(triples[0]);
700
701 if (!PrimaryTarget)
702 return NULL;
703
704 TargetInfo *TI = new TargetInfo(PrimaryTarget, &Diags);
Reid Spencer5f016e22007-07-11 17:01:13 +0000705
706 // Add all secondary targets.
Ted Kremenekaead4722007-12-03 23:23:21 +0000707 for (unsigned i = 1, e = triples.size(); i != e; ++i) {
708 TargetInfoImpl* SecondaryTarget = CreateTarget(triples[i]);
709
710 if (!SecondaryTarget) {
711 fprintf (stderr, "Warning: secondary target '%s' unrecognized.\n",
712 triples[i].c_str());
713 continue;
714 }
715
Ted Kremenekae360762007-12-03 22:06:55 +0000716 TI->AddSecondaryTarget(CreateTarget(triples[i]));
Ted Kremenekaead4722007-12-03 23:23:21 +0000717 }
Ted Kremenekae360762007-12-03 22:06:55 +0000718
Reid Spencer5f016e22007-07-11 17:01:13 +0000719 return TI;
720}