blob: ed2e0e0a448a34692d3e2be685f27a13a3781103 [file] [log] [blame]
Chris Lattner5ba61f02006-10-14 07:39:34 +00001//===--- Targets.cpp - Implement -arch option and targets -----------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner5b12ab82007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Chris Lattner5ba61f02006-10-14 07:39:34 +00007//
8//===----------------------------------------------------------------------===//
9//
Ted Kremenek6f6ff372007-12-12 18:05:32 +000010// This file implements construction of a TargetInfo object from a
11// target triple.
Chris Lattner5ba61f02006-10-14 07:39:34 +000012//
13//===----------------------------------------------------------------------===//
14
Chris Lattner10a5b382007-01-29 05:24:35 +000015#include "clang/AST/Builtins.h"
Anders Carlsson895af082007-12-09 23:17:02 +000016#include "clang/AST/TargetBuiltins.h"
Chris Lattner5ba61f02006-10-14 07:39:34 +000017#include "clang/Basic/Diagnostic.h"
18#include "clang/Basic/TargetInfo.h"
Anders Carlsson5fa3f342007-11-24 23:38:12 +000019#include "llvm/ADT/STLExtras.h"
Ted Kremenekb0615542007-12-03 22:06:55 +000020
Chris Lattner5ba61f02006-10-14 07:39:34 +000021using namespace clang;
22
Chris Lattner5ba61f02006-10-14 07:39:34 +000023//===----------------------------------------------------------------------===//
Chris Lattner1f5ad112006-10-14 18:32:12 +000024// Common code shared among targets.
Chris Lattner5ba61f02006-10-14 07:39:34 +000025//===----------------------------------------------------------------------===//
26
Chris Lattnerb2d486a2007-10-06 06:57:34 +000027static void Define(std::vector<char> &Buf, const char *Macro,
28 const char *Val = "1") {
29 const char *Def = "#define ";
30 Buf.insert(Buf.end(), Def, Def+strlen(Def));
31 Buf.insert(Buf.end(), Macro, Macro+strlen(Macro));
32 Buf.push_back(' ');
33 Buf.insert(Buf.end(), Val, Val+strlen(Val));
34 Buf.push_back('\n');
35}
36
37
Chris Lattner5ba61f02006-10-14 07:39:34 +000038namespace {
39class DarwinTargetInfo : public TargetInfoImpl {
40public:
Ted Kremenekb0615542007-12-03 22:06:55 +000041 DarwinTargetInfo(const std::string& triple) : TargetInfoImpl(triple) {}
42
Chris Lattnerb2d486a2007-10-06 06:57:34 +000043 virtual void getTargetDefines(std::vector<char> &Defs) const {
Chris Lattner253023b2007-10-17 06:04:46 +000044// FIXME: we need a real target configuration system. For now, only define
45// __APPLE__ if the host has it.
46#ifdef __APPLE__
Chris Lattnerb2d486a2007-10-06 06:57:34 +000047 Define(Defs, "__APPLE__");
48 Define(Defs, "__MACH__");
Chris Lattner253023b2007-10-17 06:04:46 +000049#endif
Chris Lattner9c837532006-10-15 01:05:46 +000050
51 if (1) {// -fobjc-gc controls this.
Chris Lattnerb2d486a2007-10-06 06:57:34 +000052 Define(Defs, "__weak", "");
53 Define(Defs, "__strong", "");
Chris Lattner9c837532006-10-15 01:05:46 +000054 } else {
Chris Lattnerb2d486a2007-10-06 06:57:34 +000055 Define(Defs, "__weak", "__attribute__((objc_gc(weak)))");
56 Define(Defs, "__strong", "__attribute__((objc_gc(strong)))");
57 Define(Defs, "__OBJC_GC__");
Chris Lattner9c837532006-10-15 01:05:46 +000058 }
59
60 // darwin_constant_cfstrings controls this.
Chris Lattnerb2d486a2007-10-06 06:57:34 +000061 Define(Defs, "__CONSTANT_CFSTRINGS__");
Chris Lattner9c837532006-10-15 01:05:46 +000062
63 if (0) // darwin_pascal_strings
Chris Lattnerb2d486a2007-10-06 06:57:34 +000064 Define(Defs, "__PASCAL_STRINGS__");
Chris Lattner1f5ad112006-10-14 18:32:12 +000065 }
66
Chris Lattner5ba61f02006-10-14 07:39:34 +000067};
Gabor Greif49991682008-02-21 16:29:08 +000068
69
70class SolarisTargetInfo : public TargetInfoImpl {
71public:
72 SolarisTargetInfo(const std::string& triple) : TargetInfoImpl(triple) {}
73
74 virtual void getTargetDefines(std::vector<char> &Defs) const {
75// FIXME: we need a real target configuration system. For now, only define
76// __SUN__ if the host has it.
77#ifdef __SUN__
78 Define(Defs, "__SUN__");
79 Define(Defs, "__SOLARIS__");
80#endif
81
82 if (1) {// -fobjc-gc controls this.
83 Define(Defs, "__weak", "");
84 Define(Defs, "__strong", "");
85 } else {
86 Define(Defs, "__weak", "__attribute__((objc_gc(weak)))");
87 Define(Defs, "__strong", "__attribute__((objc_gc(strong)))");
88 Define(Defs, "__OBJC_GC__");
89 }
90 }
91
92};
Chris Lattner5ba61f02006-10-14 07:39:34 +000093} // end anonymous namespace.
94
95
Chris Lattner1f5ad112006-10-14 18:32:12 +000096/// getPowerPCDefines - Return a set of the PowerPC-specific #defines that are
97/// not tied to a specific subtarget.
Chris Lattnerb2d486a2007-10-06 06:57:34 +000098static void getPowerPCDefines(std::vector<char> &Defs, bool is64Bit) {
Chris Lattner9c837532006-10-15 01:05:46 +000099 // Target identification.
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000100 Define(Defs, "__ppc__");
101 Define(Defs, "_ARCH_PPC");
102 Define(Defs, "__POWERPC__");
Chris Lattner9c837532006-10-15 01:05:46 +0000103 if (is64Bit) {
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000104 Define(Defs, "_ARCH_PPC64");
105 Define(Defs, "_LP64");
106 Define(Defs, "__LP64__");
107 Define(Defs, "__ppc64__");
Chris Lattner9c837532006-10-15 01:05:46 +0000108 } else {
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000109 Define(Defs, "__ppc__");
Chris Lattner9c837532006-10-15 01:05:46 +0000110 }
Chris Lattner1f5ad112006-10-14 18:32:12 +0000111
Chris Lattner9c837532006-10-15 01:05:46 +0000112 // Target properties.
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000113 Define(Defs, "_BIG_ENDIAN");
114 Define(Defs, "__BIG_ENDIAN__");
Chris Lattner9c837532006-10-15 01:05:46 +0000115
116 if (is64Bit) {
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000117 Define(Defs, "__INTMAX_MAX__", "9223372036854775807L");
118 Define(Defs, "__INTMAX_TYPE__", "long int");
119 Define(Defs, "__LONG_MAX__", "9223372036854775807L");
120 Define(Defs, "__PTRDIFF_TYPE__", "long int");
121 Define(Defs, "__UINTMAX_TYPE__", "long unsigned int");
Chris Lattner9c837532006-10-15 01:05:46 +0000122 } else {
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000123 Define(Defs, "__INTMAX_MAX__", "9223372036854775807LL");
124 Define(Defs, "__INTMAX_TYPE__", "long long int");
125 Define(Defs, "__LONG_MAX__", "2147483647L");
126 Define(Defs, "__PTRDIFF_TYPE__", "int");
127 Define(Defs, "__UINTMAX_TYPE__", "long long unsigned int");
Chris Lattner9c837532006-10-15 01:05:46 +0000128 }
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000129 Define(Defs, "__INT_MAX__", "2147483647");
130 Define(Defs, "__LONG_LONG_MAX__", "9223372036854775807LL");
131 Define(Defs, "__CHAR_BIT__", "8");
132 Define(Defs, "__SCHAR_MAX__", "127");
133 Define(Defs, "__SHRT_MAX__", "32767");
134 Define(Defs, "__SIZE_TYPE__", "long unsigned int");
Chris Lattner9c837532006-10-15 01:05:46 +0000135
136 // Subtarget options.
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000137 Define(Defs, "__USER_LABEL_PREFIX__", "_");
138 Define(Defs, "__NATURAL_ALIGNMENT__");
139 Define(Defs, "__REGISTER_PREFIX__", "");
Chris Lattner9c837532006-10-15 01:05:46 +0000140
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000141 Define(Defs, "__WCHAR_MAX__", "2147483647");
142 Define(Defs, "__WCHAR_TYPE__", "int");
143 Define(Defs, "__WINT_TYPE__", "int");
Chris Lattner9c837532006-10-15 01:05:46 +0000144
145 // Float macros.
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000146 Define(Defs, "__FLT_DENORM_MIN__", "1.40129846e-45F");
147 Define(Defs, "__FLT_DIG__", "6");
148 Define(Defs, "__FLT_EPSILON__", "1.19209290e-7F");
149 Define(Defs, "__FLT_EVAL_METHOD__", "0");
150 Define(Defs, "__FLT_HAS_INFINITY__");
151 Define(Defs, "__FLT_HAS_QUIET_NAN__");
152 Define(Defs, "__FLT_MANT_DIG__", "24");
153 Define(Defs, "__FLT_MAX_10_EXP__", "38");
154 Define(Defs, "__FLT_MAX_EXP__", "128");
155 Define(Defs, "__FLT_MAX__", "3.40282347e+38F");
156 Define(Defs, "__FLT_MIN_10_EXP__", "(-37)");
157 Define(Defs, "__FLT_MIN_EXP__", "(-125)");
158 Define(Defs, "__FLT_MIN__", "1.17549435e-38F");
159 Define(Defs, "__FLT_RADIX__", "2");
Chris Lattner9c837532006-10-15 01:05:46 +0000160
161 // double macros.
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000162 Define(Defs, "__DBL_DENORM_MIN__", "4.9406564584124654e-324");
163 Define(Defs, "__DBL_DIG__", "15");
164 Define(Defs, "__DBL_EPSILON__", "2.2204460492503131e-16");
165 Define(Defs, "__DBL_HAS_INFINITY__");
166 Define(Defs, "__DBL_HAS_QUIET_NAN__");
167 Define(Defs, "__DBL_MANT_DIG__", "53");
168 Define(Defs, "__DBL_MAX_10_EXP__", "308");
169 Define(Defs, "__DBL_MAX_EXP__", "1024");
170 Define(Defs, "__DBL_MAX__", "1.7976931348623157e+308");
171 Define(Defs, "__DBL_MIN_10_EXP__", "(-307)");
172 Define(Defs, "__DBL_MIN_EXP__", "(-1021)");
173 Define(Defs, "__DBL_MIN__", "2.2250738585072014e-308");
174 Define(Defs, "__DECIMAL_DIG__", "33");
Chris Lattner9c837532006-10-15 01:05:46 +0000175
176 // 128-bit long double macros.
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000177 Define(Defs, "__LDBL_DENORM_MIN__",
178 "4.94065645841246544176568792868221e-324L");
179 Define(Defs, "__LDBL_DIG__", "31");
180 Define(Defs, "__LDBL_EPSILON__",
181 "4.94065645841246544176568792868221e-324L");
182 Define(Defs, "__LDBL_HAS_INFINITY__");
183 Define(Defs, "__LDBL_HAS_QUIET_NAN__");
184 Define(Defs, "__LDBL_MANT_DIG__", "106");
185 Define(Defs, "__LDBL_MAX_10_EXP__", "308");
186 Define(Defs, "__LDBL_MAX_EXP__", "1024");
187 Define(Defs, "__LDBL_MAX__",
188 "1.79769313486231580793728971405301e+308L");
189 Define(Defs, "__LDBL_MIN_10_EXP__", "(-291)");
190 Define(Defs, "__LDBL_MIN_EXP__", "(-968)");
191 Define(Defs, "__LDBL_MIN__",
192 "2.00416836000897277799610805135016e-292L");
193 Define(Defs, "__LONG_DOUBLE_128__");
Chris Lattner1f5ad112006-10-14 18:32:12 +0000194}
195
196/// getX86Defines - Return a set of the X86-specific #defines that are
197/// not tied to a specific subtarget.
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000198static void getX86Defines(std::vector<char> &Defs, bool is64Bit) {
Chris Lattner9c837532006-10-15 01:05:46 +0000199 // Target identification.
200 if (is64Bit) {
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000201 Define(Defs, "_LP64");
202 Define(Defs, "__LP64__");
203 Define(Defs, "__amd64__");
204 Define(Defs, "__amd64");
205 Define(Defs, "__x86_64");
206 Define(Defs, "__x86_64__");
Chris Lattner9c837532006-10-15 01:05:46 +0000207 } else {
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000208 Define(Defs, "__i386__");
209 Define(Defs, "__i386");
210 Define(Defs, "i386");
Chris Lattner9c837532006-10-15 01:05:46 +0000211 }
212
213 // Target properties.
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000214 Define(Defs, "__LITTLE_ENDIAN__");
Chris Lattner9c837532006-10-15 01:05:46 +0000215
216 if (is64Bit) {
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000217 Define(Defs, "__INTMAX_MAX__", "9223372036854775807L");
218 Define(Defs, "__INTMAX_TYPE__", "long int");
219 Define(Defs, "__LONG_MAX__", "9223372036854775807L");
220 Define(Defs, "__PTRDIFF_TYPE__", "long int");
221 Define(Defs, "__UINTMAX_TYPE__", "long unsigned int");
Lauro Ramos Venancio71a9bb22008-01-20 04:02:16 +0000222 Define(Defs, "__SIZE_TYPE__", "long unsigned int");
Chris Lattner9c837532006-10-15 01:05:46 +0000223 } else {
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000224 Define(Defs, "__INTMAX_MAX__", "9223372036854775807LL");
225 Define(Defs, "__INTMAX_TYPE__", "long long int");
226 Define(Defs, "__LONG_MAX__", "2147483647L");
227 Define(Defs, "__PTRDIFF_TYPE__", "int");
228 Define(Defs, "__UINTMAX_TYPE__", "long long unsigned int");
Lauro Ramos Venancio71a9bb22008-01-20 04:02:16 +0000229 Define(Defs, "__SIZE_TYPE__", "unsigned int");
Chris Lattner9c837532006-10-15 01:05:46 +0000230 }
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000231 Define(Defs, "__CHAR_BIT__", "8");
232 Define(Defs, "__INT_MAX__", "2147483647");
233 Define(Defs, "__LONG_LONG_MAX__", "9223372036854775807LL");
234 Define(Defs, "__SCHAR_MAX__", "127");
235 Define(Defs, "__SHRT_MAX__", "32767");
Chris Lattner9c837532006-10-15 01:05:46 +0000236
237 // Subtarget options.
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000238 Define(Defs, "__nocona");
239 Define(Defs, "__nocona__");
240 Define(Defs, "__tune_nocona__");
241 Define(Defs, "__SSE2_MATH__");
242 Define(Defs, "__SSE2__");
243 Define(Defs, "__SSE_MATH__");
244 Define(Defs, "__SSE__");
245 Define(Defs, "__MMX__");
246 Define(Defs, "__REGISTER_PREFIX__", "");
Chris Lattner9c837532006-10-15 01:05:46 +0000247
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000248 Define(Defs, "__WCHAR_MAX__", "2147483647");
249 Define(Defs, "__WCHAR_TYPE__", "int");
250 Define(Defs, "__WINT_TYPE__", "int");
Chris Lattner9c837532006-10-15 01:05:46 +0000251
252 // Float macros.
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000253 Define(Defs, "__FLT_DENORM_MIN__", "1.40129846e-45F");
254 Define(Defs, "__FLT_DIG__", "6");
255 Define(Defs, "__FLT_EPSILON__", "1.19209290e-7F");
256 Define(Defs, "__FLT_EVAL_METHOD__", "0");
257 Define(Defs, "__FLT_HAS_INFINITY__");
258 Define(Defs, "__FLT_HAS_QUIET_NAN__");
259 Define(Defs, "__FLT_MANT_DIG__", "24");
260 Define(Defs, "__FLT_MAX_10_EXP__", "38");
261 Define(Defs, "__FLT_MAX_EXP__", "128");
262 Define(Defs, "__FLT_MAX__", "3.40282347e+38F");
263 Define(Defs, "__FLT_MIN_10_EXP__", "(-37)");
264 Define(Defs, "__FLT_MIN_EXP__", "(-125)");
265 Define(Defs, "__FLT_MIN__", "1.17549435e-38F");
266 Define(Defs, "__FLT_RADIX__", "2");
Chris Lattner9c837532006-10-15 01:05:46 +0000267
268 // Double macros.
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000269 Define(Defs, "__DBL_DENORM_MIN__", "4.9406564584124654e-324");
270 Define(Defs, "__DBL_DIG__", "15");
271 Define(Defs, "__DBL_EPSILON__", "2.2204460492503131e-16");
272 Define(Defs, "__DBL_HAS_INFINITY__");
273 Define(Defs, "__DBL_HAS_QUIET_NAN__");
274 Define(Defs, "__DBL_MANT_DIG__", "53");
275 Define(Defs, "__DBL_MAX_10_EXP__", "308");
276 Define(Defs, "__DBL_MAX_EXP__", "1024");
277 Define(Defs, "__DBL_MAX__", "1.7976931348623157e+308");
278 Define(Defs, "__DBL_MIN_10_EXP__", "(-307)");
279 Define(Defs, "__DBL_MIN_EXP__", "(-1021)");
280 Define(Defs, "__DBL_MIN__", "2.2250738585072014e-308");
281 Define(Defs, "__DECIMAL_DIG__", "21");
Chris Lattner9c837532006-10-15 01:05:46 +0000282
283 // 80-bit Long double macros.
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000284 Define(Defs, "__LDBL_DENORM_MIN__", "3.64519953188247460253e-4951L");
285 Define(Defs, "__LDBL_DIG__", "18");
286 Define(Defs, "__LDBL_EPSILON__", "1.08420217248550443401e-19L");
287 Define(Defs, "__LDBL_HAS_INFINITY__");
288 Define(Defs, "__LDBL_HAS_QUIET_NAN__");
289 Define(Defs, "__LDBL_MANT_DIG__", "64");
290 Define(Defs, "__LDBL_MAX_10_EXP__", "4932");
291 Define(Defs, "__LDBL_MAX_EXP__", "16384");
292 Define(Defs, "__LDBL_MAX__", "1.18973149535723176502e+4932L");
293 Define(Defs, "__LDBL_MIN_10_EXP__", "(-4931)");
294 Define(Defs, "__LDBL_MIN_EXP__", "(-16381)");
295 Define(Defs, "__LDBL_MIN__", "3.36210314311209350626e-4932L");
Chris Lattner1f5ad112006-10-14 18:32:12 +0000296}
297
Anders Carlssona7408e72007-10-13 00:45:48 +0000298static const char* getI386VAListDeclaration() {
299 return "typedef char* __builtin_va_list;";
300}
301
302static const char* getX86_64VAListDeclaration() {
303 return
304 "typedef struct __va_list_tag {"
305 " unsigned gp_offset;"
306 " unsigned fp_offset;"
307 " void* overflow_arg_area;"
308 " void* reg_save_area;"
309 "} __builtin_va_list[1];";
310}
311
312static const char* getPPCVAListDeclaration() {
313 return
314 "typedef struct __va_list_tag {"
315 " unsigned char gpr;"
316 " unsigned char fpr;"
317 " unsigned short reserved;"
318 " void* overflow_arg_area;"
319 " void* reg_save_area;"
320 "} __builtin_va_list[1];";
321}
322
323
Chris Lattner10a5b382007-01-29 05:24:35 +0000324/// PPC builtin info.
Chris Lattner29a16af2007-12-11 04:36:28 +0000325namespace clang {
Chris Lattner10a5b382007-01-29 05:24:35 +0000326namespace PPC {
Chris Lattner10a5b382007-01-29 05:24:35 +0000327
328 static const Builtin::Info BuiltinInfo[] = {
329#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
Anders Carlsson895af082007-12-09 23:17:02 +0000330#include "clang/AST/PPCBuiltins.def"
Chris Lattner10a5b382007-01-29 05:24:35 +0000331 };
332
333 static void getBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) {
334 Records = BuiltinInfo;
335 NumRecords = LastTSBuiltin-Builtin::FirstTSBuiltin;
336 }
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000337
338 static const char * const GCCRegNames[] = {
339 "0", "1", "2", "3", "4", "5", "6", "7",
340 "8", "9", "10", "11", "12", "13", "14", "15",
341 "16", "17", "18", "19", "20", "21", "22", "23",
342 "24", "25", "26", "27", "28", "29", "30", "31",
343 "0", "1", "2", "3", "4", "5", "6", "7",
344 "8", "9", "10", "11", "12", "13", "14", "15",
345 "16", "17", "18", "19", "20", "21", "22", "23",
346 "24", "25", "26", "27", "28", "29", "30", "31",
347 "mq", "lr", "ctr", "ap",
348 "0", "1", "2", "3", "4", "5", "6", "7",
349 "xer",
350 "0", "1", "2", "3", "4", "5", "6", "7",
351 "8", "9", "10", "11", "12", "13", "14", "15",
352 "16", "17", "18", "19", "20", "21", "22", "23",
353 "24", "25", "26", "27", "28", "29", "30", "31",
354 "vrsave", "vscr",
355 "spe_acc", "spefscr",
356 "sfp"
357 };
358
359 static void getGCCRegNames(const char * const *&Names,
360 unsigned &NumNames) {
361 Names = GCCRegNames;
362 NumNames = llvm::array_lengthof(GCCRegNames);
363 }
364
365 static const TargetInfoImpl::GCCRegAlias GCCRegAliases[] = {
366 // While some of these aliases do map to different registers
367 // they still share the same register name.
368 { { "cc", "cr0", "fr0", "r0", "v0"}, "0" },
369 { { "cr1", "fr1", "r1", "sp", "v1"}, "1" },
370 { { "cr2", "fr2", "r2", "toc", "v2"}, "2" },
371 { { "cr3", "fr3", "r3", "v3"}, "3" },
372 { { "cr4", "fr4", "r4", "v4"}, "4" },
373 { { "cr5", "fr5", "r5", "v5"}, "5" },
374 { { "cr6", "fr6", "r6", "v6"}, "6" },
375 { { "cr7", "fr7", "r7", "v7"}, "7" },
376 { { "fr8", "r8", "v8"}, "8" },
377 { { "fr9", "r9", "v9"}, "9" },
378 { { "fr10", "r10", "v10"}, "10" },
379 { { "fr11", "r11", "v11"}, "11" },
380 { { "fr12", "r12", "v12"}, "12" },
381 { { "fr13", "r13", "v13"}, "13" },
382 { { "fr14", "r14", "v14"}, "14" },
383 { { "fr15", "r15", "v15"}, "15" },
384 { { "fr16", "r16", "v16"}, "16" },
385 { { "fr17", "r17", "v17"}, "17" },
386 { { "fr18", "r18", "v18"}, "18" },
387 { { "fr19", "r19", "v19"}, "19" },
388 { { "fr20", "r20", "v20"}, "20" },
389 { { "fr21", "r21", "v21"}, "21" },
390 { { "fr22", "r22", "v22"}, "22" },
391 { { "fr23", "r23", "v23"}, "23" },
392 { { "fr24", "r24", "v24"}, "24" },
393 { { "fr25", "r25", "v25"}, "25" },
394 { { "fr26", "r26", "v26"}, "26" },
395 { { "fr27", "r27", "v27"}, "27" },
396 { { "fr28", "r28", "v28"}, "28" },
397 { { "fr29", "r29", "v29"}, "29" },
398 { { "fr30", "r30", "v30"}, "30" },
399 { { "fr31", "r31", "v31"}, "31" },
400 };
401
402 static void getGCCRegAliases(const TargetInfoImpl::GCCRegAlias *&Aliases,
403 unsigned &NumAliases) {
404 Aliases = GCCRegAliases;
405 NumAliases = llvm::array_lengthof(GCCRegAliases);
Anders Carlssonf511f642007-11-27 04:11:28 +0000406 }
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000407
Anders Carlssonf511f642007-11-27 04:11:28 +0000408 static bool validateAsmConstraint(char c,
409 TargetInfo::ConstraintInfo &info) {
410 switch (c) {
411 default: return false;
412 case 'O': // Zero
413 return true;
414 case 'b': // Base register
415 case 'f': // Floating point register
416 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
417 return true;
418 }
419 }
420
421 const char *getClobbers() {
422 return 0;
423 }
424
Anders Carlsson050f4942007-12-08 19:32:57 +0000425 const char *getTargetPrefix() {
426 return "ppc";
427 }
428
Chris Lattner10a5b382007-01-29 05:24:35 +0000429} // End namespace PPC
430
Chris Lattner10a5b382007-01-29 05:24:35 +0000431/// X86 builtin info.
432namespace X86 {
Chris Lattner10a5b382007-01-29 05:24:35 +0000433 static const Builtin::Info BuiltinInfo[] = {
434#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
Anders Carlsson895af082007-12-09 23:17:02 +0000435#include "clang/AST/X86Builtins.def"
Chris Lattner10a5b382007-01-29 05:24:35 +0000436 };
437
438 static void getBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) {
439 Records = BuiltinInfo;
440 NumRecords = LastTSBuiltin-Builtin::FirstTSBuiltin;
441 }
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000442
443 static const char *GCCRegNames[] = {
444 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
445 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
Anders Carlssonc1636572007-11-25 00:23:10 +0000446 "argp", "flags", "fspr", "dirflag", "frame",
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000447 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
448 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
449 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
450 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
451 };
452
453 static void getGCCRegNames(const char * const *&Names,
454 unsigned &NumNames) {
455 Names = GCCRegNames;
456 NumNames = llvm::array_lengthof(GCCRegNames);
457 }
458
459 static const TargetInfoImpl::GCCRegAlias GCCRegAliases[] = {
460 { { "al", "ah", "eax", "rax" }, "ax" },
461 { { "bl", "bh", "ebx", "rbx" }, "bx" },
462 { { "cl", "ch", "ecx", "rcx" }, "cx" },
463 { { "dl", "dh", "edx", "rdx" }, "dx" },
464 { { "esi", "rsi" }, "si" },
465 { { "esp", "rsp" }, "sp" },
466 { { "ebp", "rbp" }, "bp" },
467 };
468
469 static void getGCCRegAliases(const TargetInfoImpl::GCCRegAlias *&Aliases,
470 unsigned &NumAliases) {
471 Aliases = GCCRegAliases;
472 NumAliases = llvm::array_lengthof(GCCRegAliases);
473 }
474
Anders Carlssonf511f642007-11-27 04:11:28 +0000475 static bool validateAsmConstraint(char c,
476 TargetInfo::ConstraintInfo &info) {
477 switch (c) {
478 default: return false;
479 case 'a': // eax.
480 case 'b': // ebx.
481 case 'c': // ecx.
482 case 'd': // edx.
483 case 'S': // esi.
484 case 'D': // edi.
485 case 'A': // edx:eax.
486 case 't': // top of floating point stack.
487 case 'u': // second from top of floating point stack.
488 case 'q': // a, b, c, d registers or any integer register in 64-bit.
Anders Carlsson196aa532008-02-18 17:00:25 +0000489 case 'Z': // 32-bit integer constant for used with zero-extending x86_64
490 // instructions.
Anders Carlssonf511f642007-11-27 04:11:28 +0000491 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
492 return true;
493 }
494 }
495
Lauro Ramos Venancioc9fbd732008-02-26 18:33:46 +0000496 static std::string convertConstraint(const char Constraint) {
497 switch (Constraint) {
498 case 'a': return std::string("{ax}");
499 case 'b': return std::string("{bx}");
500 case 'c': return std::string("{cx}");
501 case 'd': return std::string("{dx}");
502 case 'S': return std::string("{si}");
503 case 'D': return std::string("{di}");
504 case 't': // top of floating point stack.
505 return std::string("{st}");
506 case 'u': // second from top of floating point stack.
507 return std::string("{st(1)}"); // second from top of floating point stack.
508 case 'A': // edx:eax.
509 case 'q': // a, b, c, d registers or any integer register in 64-bit.
510 case 'Z': // 32-bit integer constant for used with zero-extending x86_64
511 // instructions.
512 assert(false && "Unimplemented inline asm constraint");
513 default:
514 return std::string(1, Constraint);
515 }
516 }
517
Anders Carlssonf511f642007-11-27 04:11:28 +0000518 const char *getClobbers() {
519 return "~{dirflag},~{fpsr},~{flags}";
520 }
521
Anders Carlsson050f4942007-12-08 19:32:57 +0000522 const char *getTargetPrefix() {
523 return "x86";
524 }
525
Chris Lattner10a5b382007-01-29 05:24:35 +0000526} // End namespace X86
Chris Lattner29a16af2007-12-11 04:36:28 +0000527} // end namespace clang.
Chris Lattner10a5b382007-01-29 05:24:35 +0000528
Chris Lattner5ba61f02006-10-14 07:39:34 +0000529//===----------------------------------------------------------------------===//
530// Specific target implementations.
531//===----------------------------------------------------------------------===//
532
Chris Lattner02dffbd2006-10-14 07:50:21 +0000533
Chris Lattner5ba61f02006-10-14 07:39:34 +0000534namespace {
535class DarwinPPCTargetInfo : public DarwinTargetInfo {
536public:
Ted Kremenekb0615542007-12-03 22:06:55 +0000537 DarwinPPCTargetInfo(const std::string& triple) : DarwinTargetInfo(triple) {}
538
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000539 virtual void getTargetDefines(std::vector<char> &Defines) const {
Chris Lattner1f5ad112006-10-14 18:32:12 +0000540 DarwinTargetInfo::getTargetDefines(Defines);
541 getPowerPCDefines(Defines, false);
542 }
Chris Lattner10a5b382007-01-29 05:24:35 +0000543 virtual void getTargetBuiltins(const Builtin::Info *&Records,
544 unsigned &NumRecords) const {
545 PPC::getBuiltins(Records, NumRecords);
546 }
Anders Carlssona7408e72007-10-13 00:45:48 +0000547 virtual const char *getVAListDeclaration() const {
548 return getPPCVAListDeclaration();
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000549 }
Anders Carlsson050f4942007-12-08 19:32:57 +0000550 virtual const char *getTargetPrefix() const {
551 return PPC::getTargetPrefix();
552 }
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000553 virtual void getGCCRegNames(const char * const *&Names,
554 unsigned &NumNames) const {
555 PPC::getGCCRegNames(Names, NumNames);
556 }
557 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
558 unsigned &NumAliases) const {
559 PPC::getGCCRegAliases(Aliases, NumAliases);
560 }
Anders Carlssonf511f642007-11-27 04:11:28 +0000561 virtual bool validateAsmConstraint(char c,
562 TargetInfo::ConstraintInfo &info) const {
563 return PPC::validateAsmConstraint(c, info);
564 }
565 virtual const char *getClobbers() const {
566 return PPC::getClobbers();
567 }
Chris Lattner5ba61f02006-10-14 07:39:34 +0000568};
569} // end anonymous namespace.
570
571namespace {
572class DarwinPPC64TargetInfo : public DarwinTargetInfo {
573public:
Ted Kremenekb0615542007-12-03 22:06:55 +0000574 DarwinPPC64TargetInfo(const std::string& triple) : DarwinTargetInfo(triple) {}
575
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000576 virtual void getTargetDefines(std::vector<char> &Defines) const {
Chris Lattner1f5ad112006-10-14 18:32:12 +0000577 DarwinTargetInfo::getTargetDefines(Defines);
578 getPowerPCDefines(Defines, true);
579 }
Chris Lattner10a5b382007-01-29 05:24:35 +0000580 virtual void getTargetBuiltins(const Builtin::Info *&Records,
581 unsigned &NumRecords) const {
582 PPC::getBuiltins(Records, NumRecords);
583 }
Anders Carlssona7408e72007-10-13 00:45:48 +0000584 virtual const char *getVAListDeclaration() const {
585 return getPPCVAListDeclaration();
586 }
Anders Carlsson050f4942007-12-08 19:32:57 +0000587 virtual const char *getTargetPrefix() const {
588 return PPC::getTargetPrefix();
589 }
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000590 virtual void getGCCRegNames(const char * const *&Names,
591 unsigned &NumNames) const {
592 PPC::getGCCRegNames(Names, NumNames);
593 }
594 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
595 unsigned &NumAliases) const {
596 PPC::getGCCRegAliases(Aliases, NumAliases);
597 }
Anders Carlssonf511f642007-11-27 04:11:28 +0000598 virtual bool validateAsmConstraint(char c,
599 TargetInfo::ConstraintInfo &info) const {
600 return PPC::validateAsmConstraint(c, info);
601 }
602 virtual const char *getClobbers() const {
603 return PPC::getClobbers();
604 }
Chris Lattner5ba61f02006-10-14 07:39:34 +0000605};
606} // end anonymous namespace.
607
608namespace {
609class DarwinI386TargetInfo : public DarwinTargetInfo {
610public:
Ted Kremenekb0615542007-12-03 22:06:55 +0000611 DarwinI386TargetInfo(const std::string& triple) : DarwinTargetInfo(triple) {}
612
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000613 virtual void getTargetDefines(std::vector<char> &Defines) const {
Chris Lattner1f5ad112006-10-14 18:32:12 +0000614 DarwinTargetInfo::getTargetDefines(Defines);
615 getX86Defines(Defines, false);
616 }
Chris Lattner10a5b382007-01-29 05:24:35 +0000617 virtual void getTargetBuiltins(const Builtin::Info *&Records,
618 unsigned &NumRecords) const {
619 X86::getBuiltins(Records, NumRecords);
620 }
Anders Carlssona7408e72007-10-13 00:45:48 +0000621 virtual const char *getVAListDeclaration() const {
622 return getI386VAListDeclaration();
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000623 }
Anders Carlsson050f4942007-12-08 19:32:57 +0000624 virtual const char *getTargetPrefix() const {
625 return X86::getTargetPrefix();
626 }
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000627 virtual void getGCCRegNames(const char * const *&Names,
628 unsigned &NumNames) const {
629 X86::getGCCRegNames(Names, NumNames);
630 }
631 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
632 unsigned &NumAliases) const {
633 X86::getGCCRegAliases(Aliases, NumAliases);
Anders Carlssona7408e72007-10-13 00:45:48 +0000634 }
Anders Carlssonf511f642007-11-27 04:11:28 +0000635 virtual bool validateAsmConstraint(char c,
636 TargetInfo::ConstraintInfo &info) const {
637 return X86::validateAsmConstraint(c, info);
638 }
Lauro Ramos Venancioc9fbd732008-02-26 18:33:46 +0000639
640 virtual std::string convertConstraint(const char Constraint) const {
641 return X86::convertConstraint(Constraint);
642 }
643
Anders Carlssonf511f642007-11-27 04:11:28 +0000644 virtual const char *getClobbers() const {
645 return X86::getClobbers();
646 }
Chris Lattner5ba61f02006-10-14 07:39:34 +0000647};
648} // end anonymous namespace.
649
650namespace {
651class DarwinX86_64TargetInfo : public DarwinTargetInfo {
652public:
Ted Kremenekb0615542007-12-03 22:06:55 +0000653 DarwinX86_64TargetInfo(const std::string& triple) :DarwinTargetInfo(triple) {}
654
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000655 virtual void getTargetDefines(std::vector<char> &Defines) const {
Chris Lattner1f5ad112006-10-14 18:32:12 +0000656 DarwinTargetInfo::getTargetDefines(Defines);
657 getX86Defines(Defines, true);
658 }
Chris Lattner10a5b382007-01-29 05:24:35 +0000659 virtual void getTargetBuiltins(const Builtin::Info *&Records,
660 unsigned &NumRecords) const {
661 X86::getBuiltins(Records, NumRecords);
662 }
Anders Carlssona7408e72007-10-13 00:45:48 +0000663 virtual const char *getVAListDeclaration() const {
664 return getX86_64VAListDeclaration();
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000665 }
Anders Carlsson050f4942007-12-08 19:32:57 +0000666 virtual const char *getTargetPrefix() const {
667 return X86::getTargetPrefix();
668 }
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000669 virtual void getGCCRegNames(const char * const *&Names,
670 unsigned &NumNames) const {
671 X86::getGCCRegNames(Names, NumNames);
Anders Carlssona7408e72007-10-13 00:45:48 +0000672 }
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000673 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
674 unsigned &NumAliases) const {
675 X86::getGCCRegAliases(Aliases, NumAliases);
676 }
Anders Carlssonf511f642007-11-27 04:11:28 +0000677 virtual bool validateAsmConstraint(char c,
678 TargetInfo::ConstraintInfo &info) const {
679 return X86::validateAsmConstraint(c, info);
Lauro Ramos Venancioc9fbd732008-02-26 18:33:46 +0000680 }
681 virtual std::string convertConstraint(const char Constraint) const {
682 return X86::convertConstraint(Constraint);
683 }
Anders Carlssonf511f642007-11-27 04:11:28 +0000684 virtual const char *getClobbers() const {
685 return X86::getClobbers();
686 }
Chris Lattner5ba61f02006-10-14 07:39:34 +0000687};
688} // end anonymous namespace.
689
690namespace {
Gabor Greif49991682008-02-21 16:29:08 +0000691class SolarisSparcV8TargetInfo : public SolarisTargetInfo {
692public:
693 SolarisSparcV8TargetInfo(const std::string& triple) : SolarisTargetInfo(triple) {}
694
695 virtual void getTargetDefines(std::vector<char> &Defines) const {
696 SolarisTargetInfo::getTargetDefines(Defines);
697// getSparcDefines(Defines, false);
698 Define(Defines, "__sparc");
699 Define(Defines, "__sparcv8");
700 }
701 virtual void getTargetBuiltins(const Builtin::Info *&Records,
702 unsigned &NumRecords) const {
703 PPC::getBuiltins(Records, NumRecords);
704 }
705 virtual const char *getVAListDeclaration() const {
706 return getPPCVAListDeclaration();
707 }
708 virtual const char *getTargetPrefix() const {
709 return PPC::getTargetPrefix();
710 }
711 virtual void getGCCRegNames(const char * const *&Names,
712 unsigned &NumNames) const {
713 PPC::getGCCRegNames(Names, NumNames);
714 }
715 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
716 unsigned &NumAliases) const {
717 PPC::getGCCRegAliases(Aliases, NumAliases);
718 }
719 virtual bool validateAsmConstraint(char c,
720 TargetInfo::ConstraintInfo &info) const {
721 return PPC::validateAsmConstraint(c, info);
722 }
723 virtual const char *getClobbers() const {
724 return PPC::getClobbers();
725 }
726};
727
728} // end anonymous namespace.
729
730namespace {
Chris Lattner5ba61f02006-10-14 07:39:34 +0000731class LinuxTargetInfo : public DarwinTargetInfo {
732public:
Ted Kremenekb0615542007-12-03 22:06:55 +0000733 LinuxTargetInfo(const std::string& triple) : DarwinTargetInfo(triple) {
Chris Lattner5ba61f02006-10-14 07:39:34 +0000734 // Note: I have no idea if this is right, just for testing.
Chris Lattnerd5a828b2007-04-05 06:57:57 +0000735 WCharWidth = 16;
Chris Lattner4481b422007-07-14 01:29:45 +0000736 WCharAlign = 16;
Chris Lattner5ba61f02006-10-14 07:39:34 +0000737 }
Chris Lattner1f5ad112006-10-14 18:32:12 +0000738
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000739 virtual void getTargetDefines(std::vector<char> &Defines) const {
Chris Lattner1f5ad112006-10-14 18:32:12 +0000740 // TODO: linux-specific stuff.
741 getX86Defines(Defines, false);
742 }
Chris Lattner10a5b382007-01-29 05:24:35 +0000743 virtual void getTargetBuiltins(const Builtin::Info *&Records,
744 unsigned &NumRecords) const {
745 X86::getBuiltins(Records, NumRecords);
746 }
Anders Carlssona7408e72007-10-13 00:45:48 +0000747 virtual const char *getVAListDeclaration() const {
748 return getI386VAListDeclaration();
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000749 }
Anders Carlsson050f4942007-12-08 19:32:57 +0000750 virtual const char *getTargetPrefix() const {
751 return X86::getTargetPrefix();
752 }
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000753 virtual void getGCCRegNames(const char * const *&Names,
754 unsigned &NumNames) const {
755 X86::getGCCRegNames(Names, NumNames);
Anders Carlssona7408e72007-10-13 00:45:48 +0000756 }
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000757 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
758 unsigned &NumAliases) const {
759 X86::getGCCRegAliases(Aliases, NumAliases);
760 }
Anders Carlssonf511f642007-11-27 04:11:28 +0000761 virtual bool validateAsmConstraint(char c,
762 TargetInfo::ConstraintInfo &info) const {
763 return X86::validateAsmConstraint(c, info);
764 }
Lauro Ramos Venancioc9fbd732008-02-26 18:33:46 +0000765 virtual std::string convertConstraint(const char Constraint) const {
766 return X86::convertConstraint(Constraint);
767 }
Anders Carlssonf511f642007-11-27 04:11:28 +0000768 virtual const char *getClobbers() const {
769 return X86::getClobbers();
770 }
Chris Lattner5ba61f02006-10-14 07:39:34 +0000771};
772} // end anonymous namespace.
773
774
775//===----------------------------------------------------------------------===//
776// Driver code
777//===----------------------------------------------------------------------===//
778
Ted Kremenek0c2bea22007-12-04 17:07:35 +0000779static inline bool IsX86(const std::string& TT) {
Ted Kremenekb0615542007-12-03 22:06:55 +0000780 return (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' &&
781 TT[4] == '-' && TT[1] - '3' < 6);
782}
783
Chris Lattner5ba61f02006-10-14 07:39:34 +0000784/// CreateTarget - Create the TargetInfoImpl object for the specified target
785/// enum value.
Ted Kremenekb0615542007-12-03 22:06:55 +0000786static TargetInfoImpl *CreateTarget(const std::string& T) {
Chris Lattner36021a92007-12-05 18:41:05 +0000787 if (T.find("ppc-") == 0 || T.find("powerpc-") == 0)
Ted Kremenek0c2bea22007-12-04 17:07:35 +0000788 return new DarwinPPCTargetInfo(T);
Chris Lattner36021a92007-12-05 18:41:05 +0000789 else if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0)
Ted Kremenek0c2bea22007-12-04 17:07:35 +0000790 return new DarwinPPC64TargetInfo(T);
Gabor Greif49991682008-02-21 16:29:08 +0000791 else if (T.find("sparc-") == 0)
792 return new SolarisSparcV8TargetInfo(T); // ugly hack
Ted Kremenek0c2bea22007-12-04 17:07:35 +0000793 else if (T.find("x86_64-") == 0)
794 return new DarwinX86_64TargetInfo(T);
795 else if (IsX86(T))
796 return new DarwinI386TargetInfo(T);
797 else if (T.find("bogusW16W16-") == 0) // For testing portability.
798 return new LinuxTargetInfo(T);
799 else
800 return NULL;
Chris Lattner5ba61f02006-10-14 07:39:34 +0000801}
802
803/// CreateTargetInfo - Return the set of target info objects as specified by
804/// the -arch command line option.
Ted Kremenek1daa3cf2007-12-12 22:39:36 +0000805TargetInfo* TargetInfo::CreateTargetInfo(const std::string* TriplesStart,
Ted Kremenek6f6ff372007-12-12 18:05:32 +0000806 const std::string* TriplesEnd,
807 Diagnostic *Diags) {
Chris Lattner5ba61f02006-10-14 07:39:34 +0000808
809 // Create the primary target and target info.
Ted Kremenek6f6ff372007-12-12 18:05:32 +0000810 TargetInfoImpl* PrimaryTarget = CreateTarget(*TriplesStart);
Ted Kremenekeead4052007-12-03 23:23:21 +0000811
812 if (!PrimaryTarget)
813 return NULL;
814
Ted Kremenek1daa3cf2007-12-12 22:39:36 +0000815 TargetInfo *TI = new TargetInfo(PrimaryTarget, Diags);
Chris Lattner5ba61f02006-10-14 07:39:34 +0000816
817 // Add all secondary targets.
Ted Kremenek6f6ff372007-12-12 18:05:32 +0000818 for (const std::string* I=TriplesStart+1; I != TriplesEnd; ++I) {
819 TargetInfoImpl* SecondaryTarget = CreateTarget(*I);
Ted Kremenekeead4052007-12-03 23:23:21 +0000820
821 if (!SecondaryTarget) {
Ted Kremenek6f6ff372007-12-12 18:05:32 +0000822 fprintf (stderr,
823 "Warning: secondary target '%s' unrecognized.\n",
824 I->c_str());
825
Ted Kremenekeead4052007-12-03 23:23:21 +0000826 continue;
827 }
828
Ted Kremenek6f6ff372007-12-12 18:05:32 +0000829 TI->AddSecondaryTarget(SecondaryTarget);
Ted Kremenekeead4052007-12-03 23:23:21 +0000830 }
Ted Kremenekb0615542007-12-03 22:06:55 +0000831
Chris Lattner5ba61f02006-10-14 07:39:34 +0000832 return TI;
833}