blob: a809b94a062646fe2a49b9f691a7476f35edc1db [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"
Anders Carlsson564f1de2007-12-09 23:17:02 +000017#include "clang/AST/TargetBuiltins.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000018#include "clang/Basic/Diagnostic.h"
19#include "clang/Basic/TargetInfo.h"
Anders Carlsson564f1de2007-12-09 23:17:02 +000020
Anders Carlsson3346ae62007-11-24 23:38:12 +000021#include "llvm/ADT/STLExtras.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000022#include "llvm/Support/CommandLine.h"
Ted Kremenekae360762007-12-03 22:06:55 +000023
Reid Spencer5f016e22007-07-11 17:01:13 +000024using namespace clang;
25
Reid Spencer5f016e22007-07-11 17:01:13 +000026//===----------------------------------------------------------------------===//
27// Common code shared among targets.
28//===----------------------------------------------------------------------===//
29
Chris Lattnerd15fa822007-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
Reid Spencer5f016e22007-07-11 17:01:13 +000041namespace {
42class DarwinTargetInfo : public TargetInfoImpl {
43public:
Ted Kremenekae360762007-12-03 22:06:55 +000044 DarwinTargetInfo(const std::string& triple) : TargetInfoImpl(triple) {}
45
Chris Lattnerd15fa822007-10-06 06:57:34 +000046 virtual void getTargetDefines(std::vector<char> &Defs) const {
Chris Lattner338128b2007-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 Lattnerd15fa822007-10-06 06:57:34 +000050 Define(Defs, "__APPLE__");
51 Define(Defs, "__MACH__");
Chris Lattner338128b2007-10-17 06:04:46 +000052#endif
Reid Spencer5f016e22007-07-11 17:01:13 +000053
54 if (1) {// -fobjc-gc controls this.
Chris Lattnerd15fa822007-10-06 06:57:34 +000055 Define(Defs, "__weak", "");
56 Define(Defs, "__strong", "");
Reid Spencer5f016e22007-07-11 17:01:13 +000057 } else {
Chris Lattnerd15fa822007-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__");
Reid Spencer5f016e22007-07-11 17:01:13 +000061 }
62
63 // darwin_constant_cfstrings controls this.
Chris Lattnerd15fa822007-10-06 06:57:34 +000064 Define(Defs, "__CONSTANT_CFSTRINGS__");
Reid Spencer5f016e22007-07-11 17:01:13 +000065
66 if (0) // darwin_pascal_strings
Chris Lattnerd15fa822007-10-06 06:57:34 +000067 Define(Defs, "__PASCAL_STRINGS__");
Reid Spencer5f016e22007-07-11 17:01:13 +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 Lattnerd15fa822007-10-06 06:57:34 +000076static void getPowerPCDefines(std::vector<char> &Defs, bool is64Bit) {
Reid Spencer5f016e22007-07-11 17:01:13 +000077 // Target identification.
Chris Lattnerd15fa822007-10-06 06:57:34 +000078 Define(Defs, "__ppc__");
79 Define(Defs, "_ARCH_PPC");
80 Define(Defs, "__POWERPC__");
Reid Spencer5f016e22007-07-11 17:01:13 +000081 if (is64Bit) {
Chris Lattnerd15fa822007-10-06 06:57:34 +000082 Define(Defs, "_ARCH_PPC64");
83 Define(Defs, "_LP64");
84 Define(Defs, "__LP64__");
85 Define(Defs, "__ppc64__");
Reid Spencer5f016e22007-07-11 17:01:13 +000086 } else {
Chris Lattnerd15fa822007-10-06 06:57:34 +000087 Define(Defs, "__ppc__");
Reid Spencer5f016e22007-07-11 17:01:13 +000088 }
89
90 // Target properties.
Chris Lattnerd15fa822007-10-06 06:57:34 +000091 Define(Defs, "_BIG_ENDIAN");
92 Define(Defs, "__BIG_ENDIAN__");
Reid Spencer5f016e22007-07-11 17:01:13 +000093
94 if (is64Bit) {
Chris Lattnerd15fa822007-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");
Reid Spencer5f016e22007-07-11 17:01:13 +0000100 } else {
Chris Lattnerd15fa822007-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");
Reid Spencer5f016e22007-07-11 17:01:13 +0000106 }
Chris Lattnerd15fa822007-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");
Reid Spencer5f016e22007-07-11 17:01:13 +0000113
114 // Subtarget options.
Chris Lattnerd15fa822007-10-06 06:57:34 +0000115 Define(Defs, "__USER_LABEL_PREFIX__", "_");
116 Define(Defs, "__NATURAL_ALIGNMENT__");
117 Define(Defs, "__REGISTER_PREFIX__", "");
Reid Spencer5f016e22007-07-11 17:01:13 +0000118
Chris Lattnerd15fa822007-10-06 06:57:34 +0000119 Define(Defs, "__WCHAR_MAX__", "2147483647");
120 Define(Defs, "__WCHAR_TYPE__", "int");
121 Define(Defs, "__WINT_TYPE__", "int");
Reid Spencer5f016e22007-07-11 17:01:13 +0000122
123 // Float macros.
Chris Lattnerd15fa822007-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");
Reid Spencer5f016e22007-07-11 17:01:13 +0000138
139 // double macros.
Chris Lattnerd15fa822007-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");
Reid Spencer5f016e22007-07-11 17:01:13 +0000153
154 // 128-bit long double macros.
Chris Lattnerd15fa822007-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__");
Reid Spencer5f016e22007-07-11 17:01:13 +0000172}
173
174/// getX86Defines - Return a set of the X86-specific #defines that are
175/// not tied to a specific subtarget.
Chris Lattnerd15fa822007-10-06 06:57:34 +0000176static void getX86Defines(std::vector<char> &Defs, bool is64Bit) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000177 // Target identification.
178 if (is64Bit) {
Chris Lattnerd15fa822007-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__");
Reid Spencer5f016e22007-07-11 17:01:13 +0000185 } else {
Chris Lattnerd15fa822007-10-06 06:57:34 +0000186 Define(Defs, "__i386__");
187 Define(Defs, "__i386");
188 Define(Defs, "i386");
Reid Spencer5f016e22007-07-11 17:01:13 +0000189 }
190
191 // Target properties.
Chris Lattnerd15fa822007-10-06 06:57:34 +0000192 Define(Defs, "__LITTLE_ENDIAN__");
Reid Spencer5f016e22007-07-11 17:01:13 +0000193
194 if (is64Bit) {
Chris Lattnerd15fa822007-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");
Reid Spencer5f016e22007-07-11 17:01:13 +0000200 } else {
Chris Lattnerd15fa822007-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");
Reid Spencer5f016e22007-07-11 17:01:13 +0000206 }
Chris Lattnerd15fa822007-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");
Reid Spencer5f016e22007-07-11 17:01:13 +0000213
214 // Subtarget options.
Chris Lattnerd15fa822007-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__", "");
Reid Spencer5f016e22007-07-11 17:01:13 +0000224
Chris Lattnerd15fa822007-10-06 06:57:34 +0000225 Define(Defs, "__WCHAR_MAX__", "2147483647");
226 Define(Defs, "__WCHAR_TYPE__", "int");
227 Define(Defs, "__WINT_TYPE__", "int");
Reid Spencer5f016e22007-07-11 17:01:13 +0000228
229 // Float macros.
Chris Lattnerd15fa822007-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");
Reid Spencer5f016e22007-07-11 17:01:13 +0000244
245 // Double macros.
Chris Lattnerd15fa822007-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");
Reid Spencer5f016e22007-07-11 17:01:13 +0000259
260 // 80-bit Long double macros.
Chris Lattnerd15fa822007-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");
Reid Spencer5f016e22007-07-11 17:01:13 +0000273}
274
Anders Carlssonfb5e5ba2007-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
Reid Spencer5f016e22007-07-11 17:01:13 +0000301/// PPC builtin info.
302namespace PPC {
Reid Spencer5f016e22007-07-11 17:01:13 +0000303
304 static const Builtin::Info BuiltinInfo[] = {
305#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
Anders Carlsson564f1de2007-12-09 23:17:02 +0000306#include "clang/AST/PPCBuiltins.def"
Reid Spencer5f016e22007-07-11 17:01:13 +0000307 };
308
309 static void getBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) {
310 Records = BuiltinInfo;
311 NumRecords = LastTSBuiltin-Builtin::FirstTSBuiltin;
312 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000313
314 static const char * const GCCRegNames[] = {
315 "0", "1", "2", "3", "4", "5", "6", "7",
316 "8", "9", "10", "11", "12", "13", "14", "15",
317 "16", "17", "18", "19", "20", "21", "22", "23",
318 "24", "25", "26", "27", "28", "29", "30", "31",
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 "mq", "lr", "ctr", "ap",
324 "0", "1", "2", "3", "4", "5", "6", "7",
325 "xer",
326 "0", "1", "2", "3", "4", "5", "6", "7",
327 "8", "9", "10", "11", "12", "13", "14", "15",
328 "16", "17", "18", "19", "20", "21", "22", "23",
329 "24", "25", "26", "27", "28", "29", "30", "31",
330 "vrsave", "vscr",
331 "spe_acc", "spefscr",
332 "sfp"
333 };
334
335 static void getGCCRegNames(const char * const *&Names,
336 unsigned &NumNames) {
337 Names = GCCRegNames;
338 NumNames = llvm::array_lengthof(GCCRegNames);
339 }
340
341 static const TargetInfoImpl::GCCRegAlias GCCRegAliases[] = {
342 // While some of these aliases do map to different registers
343 // they still share the same register name.
344 { { "cc", "cr0", "fr0", "r0", "v0"}, "0" },
345 { { "cr1", "fr1", "r1", "sp", "v1"}, "1" },
346 { { "cr2", "fr2", "r2", "toc", "v2"}, "2" },
347 { { "cr3", "fr3", "r3", "v3"}, "3" },
348 { { "cr4", "fr4", "r4", "v4"}, "4" },
349 { { "cr5", "fr5", "r5", "v5"}, "5" },
350 { { "cr6", "fr6", "r6", "v6"}, "6" },
351 { { "cr7", "fr7", "r7", "v7"}, "7" },
352 { { "fr8", "r8", "v8"}, "8" },
353 { { "fr9", "r9", "v9"}, "9" },
354 { { "fr10", "r10", "v10"}, "10" },
355 { { "fr11", "r11", "v11"}, "11" },
356 { { "fr12", "r12", "v12"}, "12" },
357 { { "fr13", "r13", "v13"}, "13" },
358 { { "fr14", "r14", "v14"}, "14" },
359 { { "fr15", "r15", "v15"}, "15" },
360 { { "fr16", "r16", "v16"}, "16" },
361 { { "fr17", "r17", "v17"}, "17" },
362 { { "fr18", "r18", "v18"}, "18" },
363 { { "fr19", "r19", "v19"}, "19" },
364 { { "fr20", "r20", "v20"}, "20" },
365 { { "fr21", "r21", "v21"}, "21" },
366 { { "fr22", "r22", "v22"}, "22" },
367 { { "fr23", "r23", "v23"}, "23" },
368 { { "fr24", "r24", "v24"}, "24" },
369 { { "fr25", "r25", "v25"}, "25" },
370 { { "fr26", "r26", "v26"}, "26" },
371 { { "fr27", "r27", "v27"}, "27" },
372 { { "fr28", "r28", "v28"}, "28" },
373 { { "fr29", "r29", "v29"}, "29" },
374 { { "fr30", "r30", "v30"}, "30" },
375 { { "fr31", "r31", "v31"}, "31" },
376 };
377
378 static void getGCCRegAliases(const TargetInfoImpl::GCCRegAlias *&Aliases,
379 unsigned &NumAliases) {
380 Aliases = GCCRegAliases;
381 NumAliases = llvm::array_lengthof(GCCRegAliases);
Anders Carlssond04c6e22007-11-27 04:11:28 +0000382 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000383
Anders Carlssond04c6e22007-11-27 04:11:28 +0000384 static bool validateAsmConstraint(char c,
385 TargetInfo::ConstraintInfo &info) {
386 switch (c) {
387 default: return false;
388 case 'O': // Zero
389 return true;
390 case 'b': // Base register
391 case 'f': // Floating point register
392 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
393 return true;
394 }
395 }
396
397 const char *getClobbers() {
398 return 0;
399 }
400
Anders Carlsson44fe49c2007-12-08 19:32:57 +0000401 const char *getTargetPrefix() {
402 return "ppc";
403 }
404
Reid Spencer5f016e22007-07-11 17:01:13 +0000405} // End namespace PPC
406
407
408/// X86 builtin info.
409namespace X86 {
Reid Spencer5f016e22007-07-11 17:01:13 +0000410 static const Builtin::Info BuiltinInfo[] = {
411#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
Anders Carlsson564f1de2007-12-09 23:17:02 +0000412#include "clang/AST/X86Builtins.def"
Reid Spencer5f016e22007-07-11 17:01:13 +0000413 };
414
415 static void getBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) {
416 Records = BuiltinInfo;
417 NumRecords = LastTSBuiltin-Builtin::FirstTSBuiltin;
418 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000419
420 static const char *GCCRegNames[] = {
421 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
422 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
Anders Carlsson646b2612007-11-25 00:23:10 +0000423 "argp", "flags", "fspr", "dirflag", "frame",
Anders Carlsson3346ae62007-11-24 23:38:12 +0000424 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
425 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
426 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
427 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
428 };
429
430 static void getGCCRegNames(const char * const *&Names,
431 unsigned &NumNames) {
432 Names = GCCRegNames;
433 NumNames = llvm::array_lengthof(GCCRegNames);
434 }
435
436 static const TargetInfoImpl::GCCRegAlias GCCRegAliases[] = {
437 { { "al", "ah", "eax", "rax" }, "ax" },
438 { { "bl", "bh", "ebx", "rbx" }, "bx" },
439 { { "cl", "ch", "ecx", "rcx" }, "cx" },
440 { { "dl", "dh", "edx", "rdx" }, "dx" },
441 { { "esi", "rsi" }, "si" },
442 { { "esp", "rsp" }, "sp" },
443 { { "ebp", "rbp" }, "bp" },
444 };
445
446 static void getGCCRegAliases(const TargetInfoImpl::GCCRegAlias *&Aliases,
447 unsigned &NumAliases) {
448 Aliases = GCCRegAliases;
449 NumAliases = llvm::array_lengthof(GCCRegAliases);
450 }
451
Anders Carlssond04c6e22007-11-27 04:11:28 +0000452 static bool validateAsmConstraint(char c,
453 TargetInfo::ConstraintInfo &info) {
454 switch (c) {
455 default: return false;
456 case 'a': // eax.
457 case 'b': // ebx.
458 case 'c': // ecx.
459 case 'd': // edx.
460 case 'S': // esi.
461 case 'D': // edi.
462 case 'A': // edx:eax.
463 case 't': // top of floating point stack.
464 case 'u': // second from top of floating point stack.
465 case 'q': // a, b, c, d registers or any integer register in 64-bit.
466 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
467 return true;
468 }
469 }
470
471 const char *getClobbers() {
472 return "~{dirflag},~{fpsr},~{flags}";
473 }
474
Anders Carlsson44fe49c2007-12-08 19:32:57 +0000475 const char *getTargetPrefix() {
476 return "x86";
477 }
478
Reid Spencer5f016e22007-07-11 17:01:13 +0000479} // End namespace X86
480
481//===----------------------------------------------------------------------===//
482// Specific target implementations.
483//===----------------------------------------------------------------------===//
484
485
486namespace {
487class DarwinPPCTargetInfo : public DarwinTargetInfo {
488public:
Ted Kremenekae360762007-12-03 22:06:55 +0000489 DarwinPPCTargetInfo(const std::string& triple) : DarwinTargetInfo(triple) {}
490
Chris Lattnerd15fa822007-10-06 06:57:34 +0000491 virtual void getTargetDefines(std::vector<char> &Defines) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000492 DarwinTargetInfo::getTargetDefines(Defines);
493 getPowerPCDefines(Defines, false);
494 }
495 virtual void getTargetBuiltins(const Builtin::Info *&Records,
496 unsigned &NumRecords) const {
497 PPC::getBuiltins(Records, NumRecords);
498 }
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000499 virtual const char *getVAListDeclaration() const {
500 return getPPCVAListDeclaration();
Anders Carlsson3346ae62007-11-24 23:38:12 +0000501 }
Anders Carlsson44fe49c2007-12-08 19:32:57 +0000502 virtual const char *getTargetPrefix() const {
503 return PPC::getTargetPrefix();
504 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000505 virtual void getGCCRegNames(const char * const *&Names,
506 unsigned &NumNames) const {
507 PPC::getGCCRegNames(Names, NumNames);
508 }
509 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
510 unsigned &NumAliases) const {
511 PPC::getGCCRegAliases(Aliases, NumAliases);
512 }
Anders Carlssond04c6e22007-11-27 04:11:28 +0000513 virtual bool validateAsmConstraint(char c,
514 TargetInfo::ConstraintInfo &info) const {
515 return PPC::validateAsmConstraint(c, info);
516 }
517 virtual const char *getClobbers() const {
518 return PPC::getClobbers();
519 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000520};
521} // end anonymous namespace.
522
523namespace {
524class DarwinPPC64TargetInfo : public DarwinTargetInfo {
525public:
Ted Kremenekae360762007-12-03 22:06:55 +0000526 DarwinPPC64TargetInfo(const std::string& triple) : DarwinTargetInfo(triple) {}
527
Chris Lattnerd15fa822007-10-06 06:57:34 +0000528 virtual void getTargetDefines(std::vector<char> &Defines) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000529 DarwinTargetInfo::getTargetDefines(Defines);
530 getPowerPCDefines(Defines, true);
531 }
532 virtual void getTargetBuiltins(const Builtin::Info *&Records,
533 unsigned &NumRecords) const {
534 PPC::getBuiltins(Records, NumRecords);
535 }
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000536 virtual const char *getVAListDeclaration() const {
537 return getPPCVAListDeclaration();
538 }
Anders Carlsson44fe49c2007-12-08 19:32:57 +0000539 virtual const char *getTargetPrefix() const {
540 return PPC::getTargetPrefix();
541 }
Anders Carlsson3346ae62007-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 Carlssond04c6e22007-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 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000557};
558} // end anonymous namespace.
559
560namespace {
561class DarwinI386TargetInfo : public DarwinTargetInfo {
562public:
Ted Kremenekae360762007-12-03 22:06:55 +0000563 DarwinI386TargetInfo(const std::string& triple) : DarwinTargetInfo(triple) {}
564
Chris Lattnerd15fa822007-10-06 06:57:34 +0000565 virtual void getTargetDefines(std::vector<char> &Defines) const {
Reid Spencer5f016e22007-07-11 17:01:13 +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 Carlssonfb5e5ba2007-10-13 00:45:48 +0000573 virtual const char *getVAListDeclaration() const {
574 return getI386VAListDeclaration();
Anders Carlsson3346ae62007-11-24 23:38:12 +0000575 }
Anders Carlsson44fe49c2007-12-08 19:32:57 +0000576 virtual const char *getTargetPrefix() const {
577 return X86::getTargetPrefix();
578 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000579 virtual void getGCCRegNames(const char * const *&Names,
580 unsigned &NumNames) const {
581 X86::getGCCRegNames(Names, NumNames);
582 }
583 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
584 unsigned &NumAliases) const {
585 X86::getGCCRegAliases(Aliases, NumAliases);
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000586 }
Anders Carlssond04c6e22007-11-27 04:11:28 +0000587 virtual bool validateAsmConstraint(char c,
588 TargetInfo::ConstraintInfo &info) const {
589 return X86::validateAsmConstraint(c, info);
590 }
591 virtual const char *getClobbers() const {
592 return X86::getClobbers();
593 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000594};
595} // end anonymous namespace.
596
597namespace {
598class DarwinX86_64TargetInfo : public DarwinTargetInfo {
599public:
Ted Kremenekae360762007-12-03 22:06:55 +0000600 DarwinX86_64TargetInfo(const std::string& triple) :DarwinTargetInfo(triple) {}
601
Chris Lattnerd15fa822007-10-06 06:57:34 +0000602 virtual void getTargetDefines(std::vector<char> &Defines) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000603 DarwinTargetInfo::getTargetDefines(Defines);
604 getX86Defines(Defines, true);
605 }
606 virtual void getTargetBuiltins(const Builtin::Info *&Records,
607 unsigned &NumRecords) const {
608 X86::getBuiltins(Records, NumRecords);
609 }
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000610 virtual const char *getVAListDeclaration() const {
611 return getX86_64VAListDeclaration();
Anders Carlsson3346ae62007-11-24 23:38:12 +0000612 }
Anders Carlsson44fe49c2007-12-08 19:32:57 +0000613 virtual const char *getTargetPrefix() const {
614 return X86::getTargetPrefix();
615 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000616 virtual void getGCCRegNames(const char * const *&Names,
617 unsigned &NumNames) const {
618 X86::getGCCRegNames(Names, NumNames);
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000619 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000620 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
621 unsigned &NumAliases) const {
622 X86::getGCCRegAliases(Aliases, NumAliases);
623 }
Anders Carlssond04c6e22007-11-27 04:11:28 +0000624 virtual bool validateAsmConstraint(char c,
625 TargetInfo::ConstraintInfo &info) const {
626 return X86::validateAsmConstraint(c, info);
627 }
628 virtual const char *getClobbers() const {
629 return X86::getClobbers();
630 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000631};
632} // end anonymous namespace.
633
634namespace {
635class LinuxTargetInfo : public DarwinTargetInfo {
636public:
Ted Kremenekae360762007-12-03 22:06:55 +0000637 LinuxTargetInfo(const std::string& triple) : DarwinTargetInfo(triple) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000638 // Note: I have no idea if this is right, just for testing.
639 WCharWidth = 16;
Chris Lattnerd2d2a112007-07-14 01:29:45 +0000640 WCharAlign = 16;
Reid Spencer5f016e22007-07-11 17:01:13 +0000641 }
642
Chris Lattnerd15fa822007-10-06 06:57:34 +0000643 virtual void getTargetDefines(std::vector<char> &Defines) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000644 // TODO: linux-specific stuff.
645 getX86Defines(Defines, false);
646 }
647 virtual void getTargetBuiltins(const Builtin::Info *&Records,
648 unsigned &NumRecords) const {
649 X86::getBuiltins(Records, NumRecords);
650 }
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000651 virtual const char *getVAListDeclaration() const {
652 return getI386VAListDeclaration();
Anders Carlsson3346ae62007-11-24 23:38:12 +0000653 }
Anders Carlsson44fe49c2007-12-08 19:32:57 +0000654 virtual const char *getTargetPrefix() const {
655 return X86::getTargetPrefix();
656 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000657 virtual void getGCCRegNames(const char * const *&Names,
658 unsigned &NumNames) const {
659 X86::getGCCRegNames(Names, NumNames);
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000660 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000661 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
662 unsigned &NumAliases) const {
663 X86::getGCCRegAliases(Aliases, NumAliases);
664 }
Anders Carlssond04c6e22007-11-27 04:11:28 +0000665 virtual bool validateAsmConstraint(char c,
666 TargetInfo::ConstraintInfo &info) const {
667 return X86::validateAsmConstraint(c, info);
668 }
669 virtual const char *getClobbers() const {
670 return X86::getClobbers();
671 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000672};
673} // end anonymous namespace.
674
675
676//===----------------------------------------------------------------------===//
677// Driver code
678//===----------------------------------------------------------------------===//
679
Ted Kremenek8448d382007-12-04 17:07:35 +0000680static inline bool IsX86(const std::string& TT) {
Ted Kremenekae360762007-12-03 22:06:55 +0000681 return (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' &&
682 TT[4] == '-' && TT[1] - '3' < 6);
683}
684
Reid Spencer5f016e22007-07-11 17:01:13 +0000685/// CreateTarget - Create the TargetInfoImpl object for the specified target
686/// enum value.
Ted Kremenekae360762007-12-03 22:06:55 +0000687static TargetInfoImpl *CreateTarget(const std::string& T) {
Chris Lattner82817ba2007-12-05 18:41:05 +0000688 if (T.find("ppc-") == 0 || T.find("powerpc-") == 0)
Ted Kremenek8448d382007-12-04 17:07:35 +0000689 return new DarwinPPCTargetInfo(T);
Chris Lattner82817ba2007-12-05 18:41:05 +0000690 else if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0)
Ted Kremenek8448d382007-12-04 17:07:35 +0000691 return new DarwinPPC64TargetInfo(T);
692 else if (T.find("x86_64-") == 0)
693 return new DarwinX86_64TargetInfo(T);
694 else if (IsX86(T))
695 return new DarwinI386TargetInfo(T);
696 else if (T.find("bogusW16W16-") == 0) // For testing portability.
697 return new LinuxTargetInfo(T);
698 else
699 return NULL;
Reid Spencer5f016e22007-07-11 17:01:13 +0000700}
701
702/// CreateTargetInfo - Return the set of target info objects as specified by
703/// the -arch command line option.
Ted Kremenekae360762007-12-03 22:06:55 +0000704TargetInfo *clang::CreateTargetInfo(const std::vector<std::string>& triples,
Ted Kremenekacc9f332007-12-05 21:34:36 +0000705 Diagnostic *Diags) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000706
Ted Kremenekae360762007-12-03 22:06:55 +0000707 assert (!triples.empty() && "No target triple.");
708
Reid Spencer5f016e22007-07-11 17:01:13 +0000709 // Create the primary target and target info.
Ted Kremenekaead4722007-12-03 23:23:21 +0000710 TargetInfoImpl* PrimaryTarget = CreateTarget(triples[0]);
711
712 if (!PrimaryTarget)
713 return NULL;
714
Ted Kremenekacc9f332007-12-05 21:34:36 +0000715 TargetInfo *TI = new TargetInfo(PrimaryTarget, Diags);
Reid Spencer5f016e22007-07-11 17:01:13 +0000716
717 // Add all secondary targets.
Ted Kremenekaead4722007-12-03 23:23:21 +0000718 for (unsigned i = 1, e = triples.size(); i != e; ++i) {
719 TargetInfoImpl* SecondaryTarget = CreateTarget(triples[i]);
720
721 if (!SecondaryTarget) {
722 fprintf (stderr, "Warning: secondary target '%s' unrecognized.\n",
723 triples[i].c_str());
724 continue;
725 }
726
Ted Kremenekae360762007-12-03 22:06:55 +0000727 TI->AddSecondaryTarget(CreateTarget(triples[i]));
Ted Kremenekaead4722007-12-03 23:23:21 +0000728 }
Ted Kremenekae360762007-12-03 22:06:55 +0000729
Reid Spencer5f016e22007-07-11 17:01:13 +0000730 return TI;
731}