Targets.cpp revision 5edfe0151c889aab8979ae0efd4bbf155284ac5e
1//===--- Targets.cpp - Implement -arch option and targets -----------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements construction of a TargetInfo object from a
11// target triple.
12//
13//===----------------------------------------------------------------------===//
14
15#include "clang/AST/Builtins.h"
16#include "clang/AST/TargetBuiltins.h"
17#include "clang/Basic/TargetInfo.h"
18#include "llvm/ADT/STLExtras.h"
19#include "llvm/ADT/APFloat.h"
20using namespace clang;
21
22//===----------------------------------------------------------------------===//
23//  Common code shared among targets.
24//===----------------------------------------------------------------------===//
25
26static void Define(std::vector<char> &Buf, const char *Macro,
27                   const char *Val = "1") {
28  const char *Def = "#define ";
29  Buf.insert(Buf.end(), Def, Def+strlen(Def));
30  Buf.insert(Buf.end(), Macro, Macro+strlen(Macro));
31  Buf.push_back(' ');
32  Buf.insert(Buf.end(), Val, Val+strlen(Val));
33  Buf.push_back('\n');
34}
35
36static void getSolarisDefines(std::vector<char> &Defs) {
37  Define(Defs, "__SUN__");
38  Define(Defs, "__SOLARIS__");
39}
40
41static void getDarwinDefines(std::vector<char> &Defs, const char *Triple) {
42  Define(Defs, "__APPLE__");
43  Define(Defs, "__MACH__");
44
45  // Figure out which "darwin number" the target triple is.  "darwin9" -> 10.5.
46  const char *Darwin = strstr(Triple, "-darwin");
47  if (Darwin) {
48    char DarwinStr[] = "1000";
49    Darwin += strlen("-darwin");
50    if (Darwin[0] >= '0' && Darwin[0] <= '9') {
51      unsigned DarwinNo = Darwin[0]-'0';
52      ++Darwin;
53
54      // Handle "darwin11".
55      if (DarwinNo == 1 && Darwin[0] >= '0' && Darwin[0] <= '9') {
56        DarwinNo = 10+Darwin[0]-'0';
57        ++Darwin;
58      }
59
60      if (DarwinNo >= 4 && DarwinNo <= 13) { // 10.0-10.9
61        // darwin7 -> 1030, darwin8 -> 1040, darwin9 -> 1050, etc.
62        DarwinStr[2] = '0' + DarwinNo-4;
63      }
64
65      // Handle minor version: 10.4.9 -> darwin8.9 -> "1049"
66      if (Darwin[0] == '.' && Darwin[1] >= '0' && Darwin[1] <= '9' &&
67          Darwin[2] == '\0')
68        DarwinStr[3] = Darwin[1];
69
70    }
71    Define(Defs, "__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", DarwinStr);
72  }
73}
74
75static void getDragonFlyDefines(std::vector<char> &Defs) {
76  // DragonFly defines; list based off of gcc output
77  Define(Defs, "__DragonFly__");
78  Define(Defs, "__DragonFly_cc_version", "100001");
79  Define(Defs, "__ELF__");
80  Define(Defs, "__KPRINTF_ATTRIBUTE__");
81  Define(Defs, "__tune_i386__");
82  Define(Defs, "unix");
83  Define(Defs, "__unix");
84  Define(Defs, "__unix__");
85}
86
87static void getLinuxDefines(std::vector<char> &Defs) {
88  // Linux defines; list based off of gcc output
89  Define(Defs, "__unix__");
90  Define(Defs, "__unix");
91  Define(Defs, "unix");
92  Define(Defs, "__linux__");
93  Define(Defs, "__linux");
94  Define(Defs, "linux");
95  Define(Defs, "__gnu_linux__");
96}
97
98/// getPowerPCDefines - Return a set of the PowerPC-specific #defines that are
99/// not tied to a specific subtarget.
100static void getPowerPCDefines(std::vector<char> &Defs, bool is64Bit) {
101  // Target identification.
102  Define(Defs, "__ppc__");
103  Define(Defs, "_ARCH_PPC");
104  Define(Defs, "__POWERPC__");
105  if (is64Bit) {
106    Define(Defs, "_ARCH_PPC64");
107    Define(Defs, "_LP64");
108    Define(Defs, "__LP64__");
109    Define(Defs, "__ppc64__");
110  } else {
111    Define(Defs, "__ppc__");
112  }
113
114  // Target properties.
115  Define(Defs, "_BIG_ENDIAN");
116  Define(Defs, "__BIG_ENDIAN__");
117
118  if (is64Bit) {
119    Define(Defs, "__INTMAX_MAX__", "9223372036854775807L");
120    Define(Defs, "__INTMAX_TYPE__", "long int");
121    Define(Defs, "__LONG_MAX__", "9223372036854775807L");
122    Define(Defs, "__PTRDIFF_TYPE__", "long int");
123    Define(Defs, "__UINTMAX_TYPE__", "long unsigned int");
124  } else {
125    Define(Defs, "__INTMAX_MAX__", "9223372036854775807LL");
126    Define(Defs, "__INTMAX_TYPE__", "long long int");
127    Define(Defs, "__LONG_MAX__", "2147483647L");
128    Define(Defs, "__PTRDIFF_TYPE__", "int");
129    Define(Defs, "__UINTMAX_TYPE__", "long long unsigned int");
130  }
131  Define(Defs, "__INT_MAX__", "2147483647");
132  Define(Defs, "__SIZE_TYPE__", "long unsigned int");
133
134  // Subtarget options.
135  Define(Defs, "__NATURAL_ALIGNMENT__");
136  Define(Defs, "__REGISTER_PREFIX__", "");
137
138  Define(Defs, "__WCHAR_MAX__", "2147483647");
139  Define(Defs, "__WCHAR_TYPE__", "int");
140  Define(Defs, "__WINT_TYPE__", "int");
141
142  // Float macros.
143  Define(Defs, "__FLT_DENORM_MIN__", "1.40129846e-45F");
144  Define(Defs, "__FLT_DIG__", "6");
145  Define(Defs, "__FLT_EPSILON__", "1.19209290e-7F");
146  Define(Defs, "__FLT_EVAL_METHOD__", "0");
147  Define(Defs, "__FLT_HAS_INFINITY__");
148  Define(Defs, "__FLT_HAS_QUIET_NAN__");
149  Define(Defs, "__FLT_MANT_DIG__", "24");
150  Define(Defs, "__FLT_MAX_10_EXP__", "38");
151  Define(Defs, "__FLT_MAX_EXP__", "128");
152  Define(Defs, "__FLT_MAX__", "3.40282347e+38F");
153  Define(Defs, "__FLT_MIN_10_EXP__", "(-37)");
154  Define(Defs, "__FLT_MIN_EXP__", "(-125)");
155  Define(Defs, "__FLT_MIN__", "1.17549435e-38F");
156  Define(Defs, "__FLT_RADIX__", "2");
157
158  // double macros.
159  Define(Defs, "__DBL_DENORM_MIN__", "4.9406564584124654e-324");
160  Define(Defs, "__DBL_DIG__", "15");
161  Define(Defs, "__DBL_EPSILON__", "2.2204460492503131e-16");
162  Define(Defs, "__DBL_HAS_INFINITY__");
163  Define(Defs, "__DBL_HAS_QUIET_NAN__");
164  Define(Defs, "__DBL_MANT_DIG__", "53");
165  Define(Defs, "__DBL_MAX_10_EXP__", "308");
166  Define(Defs, "__DBL_MAX_EXP__", "1024");
167  Define(Defs, "__DBL_MAX__", "1.7976931348623157e+308");
168  Define(Defs, "__DBL_MIN_10_EXP__", "(-307)");
169  Define(Defs, "__DBL_MIN_EXP__", "(-1021)");
170  Define(Defs, "__DBL_MIN__", "2.2250738585072014e-308");
171  Define(Defs, "__DECIMAL_DIG__", "33");
172
173  // 128-bit long double macros.
174  Define(Defs, "__LDBL_DENORM_MIN__",
175         "4.94065645841246544176568792868221e-324L");
176  Define(Defs, "__LDBL_DIG__", "31");
177  Define(Defs, "__LDBL_EPSILON__",
178         "4.94065645841246544176568792868221e-324L");
179  Define(Defs, "__LDBL_HAS_INFINITY__");
180  Define(Defs, "__LDBL_HAS_QUIET_NAN__");
181  Define(Defs, "__LDBL_MANT_DIG__", "106");
182  Define(Defs, "__LDBL_MAX_10_EXP__", "308");
183  Define(Defs, "__LDBL_MAX_EXP__", "1024");
184  Define(Defs, "__LDBL_MAX__",
185         "1.79769313486231580793728971405301e+308L");
186  Define(Defs, "__LDBL_MIN_10_EXP__", "(-291)");
187  Define(Defs, "__LDBL_MIN_EXP__", "(-968)");
188  Define(Defs, "__LDBL_MIN__",
189         "2.00416836000897277799610805135016e-292L");
190  Define(Defs, "__LONG_DOUBLE_128__");
191}
192
193/// getX86Defines - Return a set of the X86-specific #defines that are
194/// not tied to a specific subtarget.
195static void getX86Defines(std::vector<char> &Defs, bool is64Bit) {
196  // Target identification.
197  if (is64Bit) {
198    Define(Defs, "_LP64");
199    Define(Defs, "__LP64__");
200    Define(Defs, "__amd64__");
201    Define(Defs, "__amd64");
202    Define(Defs, "__x86_64");
203    Define(Defs, "__x86_64__");
204  } else {
205    Define(Defs, "__i386__");
206    Define(Defs, "__i386");
207    Define(Defs, "i386");
208  }
209
210  // Target properties.
211  Define(Defs, "__LITTLE_ENDIAN__");
212
213  if (is64Bit) {
214    Define(Defs, "__INTMAX_MAX__", "9223372036854775807L");
215    Define(Defs, "__INTMAX_TYPE__", "long int");
216    Define(Defs, "__LONG_MAX__", "9223372036854775807L");
217    Define(Defs, "__PTRDIFF_TYPE__", "long int");
218    Define(Defs, "__UINTMAX_TYPE__", "long unsigned int");
219  } else {
220    Define(Defs, "__INTMAX_MAX__", "9223372036854775807LL");
221    Define(Defs, "__INTMAX_TYPE__", "long long int");
222    Define(Defs, "__LONG_MAX__", "2147483647L");
223    Define(Defs, "__PTRDIFF_TYPE__", "int");
224    Define(Defs, "__UINTMAX_TYPE__", "long long unsigned int");
225  }
226  Define(Defs, "__SIZE_TYPE__", "long unsigned int");
227  Define(Defs, "__INT_MAX__", "2147483647");
228
229  // Subtarget options.
230  Define(Defs, "__nocona");
231  Define(Defs, "__nocona__");
232  Define(Defs, "__tune_nocona__");
233  Define(Defs, "__SSE2_MATH__");
234  Define(Defs, "__SSE2__");
235  Define(Defs, "__SSE_MATH__");
236  Define(Defs, "__SSE__");
237  Define(Defs, "__MMX__");
238  Define(Defs, "__REGISTER_PREFIX__", "");
239
240  Define(Defs, "__WCHAR_MAX__", "2147483647");
241  Define(Defs, "__WCHAR_TYPE__", "int");
242  Define(Defs, "__WINT_TYPE__", "int");
243
244  // Float macros.
245  Define(Defs, "__FLT_DENORM_MIN__", "1.40129846e-45F");
246  Define(Defs, "__FLT_DIG__", "6");
247  Define(Defs, "__FLT_EPSILON__", "1.19209290e-7F");
248  Define(Defs, "__FLT_EVAL_METHOD__", "0");
249  Define(Defs, "__FLT_HAS_INFINITY__");
250  Define(Defs, "__FLT_HAS_QUIET_NAN__");
251  Define(Defs, "__FLT_MANT_DIG__", "24");
252  Define(Defs, "__FLT_MAX_10_EXP__", "38");
253  Define(Defs, "__FLT_MAX_EXP__", "128");
254  Define(Defs, "__FLT_MAX__", "3.40282347e+38F");
255  Define(Defs, "__FLT_MIN_10_EXP__", "(-37)");
256  Define(Defs, "__FLT_MIN_EXP__", "(-125)");
257  Define(Defs, "__FLT_MIN__", "1.17549435e-38F");
258  Define(Defs, "__FLT_RADIX__", "2");
259
260  // Double macros.
261  Define(Defs, "__DBL_DENORM_MIN__", "4.9406564584124654e-324");
262  Define(Defs, "__DBL_DIG__", "15");
263  Define(Defs, "__DBL_EPSILON__", "2.2204460492503131e-16");
264  Define(Defs, "__DBL_HAS_INFINITY__");
265  Define(Defs, "__DBL_HAS_QUIET_NAN__");
266  Define(Defs, "__DBL_MANT_DIG__", "53");
267  Define(Defs, "__DBL_MAX_10_EXP__", "308");
268  Define(Defs, "__DBL_MAX_EXP__", "1024");
269  Define(Defs, "__DBL_MAX__", "1.7976931348623157e+308");
270  Define(Defs, "__DBL_MIN_10_EXP__", "(-307)");
271  Define(Defs, "__DBL_MIN_EXP__", "(-1021)");
272  Define(Defs, "__DBL_MIN__", "2.2250738585072014e-308");
273  Define(Defs, "__DECIMAL_DIG__", "21");
274
275  // 80-bit Long double macros.
276  Define(Defs, "__LDBL_DENORM_MIN__", "3.64519953188247460253e-4951L");
277  Define(Defs, "__LDBL_DIG__", "18");
278  Define(Defs, "__LDBL_EPSILON__", "1.08420217248550443401e-19L");
279  Define(Defs, "__LDBL_HAS_INFINITY__");
280  Define(Defs, "__LDBL_HAS_QUIET_NAN__");
281  Define(Defs, "__LDBL_MANT_DIG__", "64");
282  Define(Defs, "__LDBL_MAX_10_EXP__", "4932");
283  Define(Defs, "__LDBL_MAX_EXP__", "16384");
284  Define(Defs, "__LDBL_MAX__", "1.18973149535723176502e+4932L");
285  Define(Defs, "__LDBL_MIN_10_EXP__", "(-4931)");
286  Define(Defs, "__LDBL_MIN_EXP__", "(-16381)");
287  Define(Defs, "__LDBL_MIN__", "3.36210314311209350626e-4932L");
288}
289
290/// getARMDefines - Return a set of the ARM-specific #defines that are
291/// not tied to a specific subtarget.
292static void getARMDefines(std::vector<char> &Defs) {
293  // Target identification.
294  Define(Defs, "__arm");
295  Define(Defs, "__arm__");
296
297  // Target properties.
298  Define(Defs, "__LITTLE_ENDIAN__");
299
300  Define(Defs, "__INTMAX_MAX__", "9223372036854775807LL");
301  Define(Defs, "__INTMAX_TYPE__", "long long int");
302  Define(Defs, "__LONG_MAX__", "2147483647L");
303  Define(Defs, "__PTRDIFF_TYPE__", "int");
304  Define(Defs, "__UINTMAX_TYPE__", "long long unsigned int");
305  Define(Defs, "__SIZE_TYPE__", "long unsigned int");
306
307  Define(Defs, "__INT_MAX__", "2147483647");
308
309  // Subtarget options.  [hard coded to v6 for now]
310  Define(Defs, "__ARM_ARCH_6K__");
311  Define(Defs, "__ARMEL__");
312  Define(Defs, "__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", "20000");
313
314  Define(Defs, "__WCHAR_MAX__", "2147483647");
315  Define(Defs, "__WCHAR_TYPE__", "int");
316  Define(Defs, "__WINT_TYPE__", "int");
317  Define(Defs, "__DECIMAL_DIG__", "17");
318  Define(Defs, "__FLT_RADIX__", "2");
319
320  // Float macros.
321  Define(Defs, "__FLT_DENORM_MIN__", "1.40129846e-45F");
322  Define(Defs, "__FLT_DIG__", "6");
323  Define(Defs, "__FLT_EPSILON__", "1.19209290e-7F");
324  Define(Defs, "__FLT_EVAL_METHOD__", "0");
325  Define(Defs, "__FLT_HAS_INFINITY__");
326  Define(Defs, "__FLT_HAS_QUIET_NAN__");
327  Define(Defs, "__FLT_MANT_DIG__", "24");
328  Define(Defs, "__FLT_MAX_10_EXP__", "38");
329  Define(Defs, "__FLT_MAX_EXP__", "128");
330  Define(Defs, "__FLT_MAX__", "3.40282347e+38F");
331  Define(Defs, "__FLT_MIN_10_EXP__", "(-37)");
332  Define(Defs, "__FLT_MIN_EXP__", "(-125)");
333  Define(Defs, "__FLT_MIN__", "1.17549435e-38F");
334
335  // Double macros.
336  Define(Defs, "__DBL_DENORM_MIN__", "4.9406564584124654e-324");
337  Define(Defs, "__DBL_DIG__", "15");
338  Define(Defs, "__DBL_EPSILON__", "2.2204460492503131e-16");
339  Define(Defs, "__DBL_HAS_INFINITY__");
340  Define(Defs, "__DBL_HAS_QUIET_NAN__");
341  Define(Defs, "__DBL_MANT_DIG__", "53");
342  Define(Defs, "__DBL_MAX_10_EXP__", "308");
343  Define(Defs, "__DBL_MAX_EXP__", "1024");
344  Define(Defs, "__DBL_MAX__", "1.7976931348623157e+308");
345  Define(Defs, "__DBL_MIN_10_EXP__", "(-307)");
346  Define(Defs, "__DBL_MIN_EXP__", "(-1021)");
347  Define(Defs, "__DBL_MIN__", "2.2250738585072014e-308");
348
349  // 64-bit Long double macros (same as double).
350  Define(Defs, "__LDBL_DENORM_MIN__", "4.9406564584124654e-324");
351  Define(Defs, "__LDBL_DIG__", "15");
352  Define(Defs, "__LDBL_EPSILON__", "2.2204460492503131e-16");
353  Define(Defs, "__LDBL_HAS_INFINITY__");
354  Define(Defs, "__LDBL_HAS_QUIET_NAN__");
355  Define(Defs, "__LDBL_MANT_DIG__", "53");
356  Define(Defs, "__LDBL_MAX_10_EXP__", "308");
357  Define(Defs, "__LDBL_MAX_EXP__", "1024");
358  Define(Defs, "__LDBL_MAX__", "1.7976931348623157e+308");
359  Define(Defs, "__LDBL_MIN_10_EXP__", "(-307)");
360  Define(Defs, "__LDBL_MIN_EXP__", "(-1021)");
361  Define(Defs, "__LDBL_MIN__", "2.2250738585072014e-308");
362}
363
364//===----------------------------------------------------------------------===//
365// Specific target implementations.
366//===----------------------------------------------------------------------===//
367
368namespace {
369// PPC abstract base class
370class PPCTargetInfo : public TargetInfo {
371  static const Builtin::Info BuiltinInfo[];
372  static const char * const GCCRegNames[];
373  static const TargetInfo::GCCRegAlias GCCRegAliases[];
374
375public:
376  PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {
377    CharIsSigned = false;
378  }
379  virtual void getTargetBuiltins(const Builtin::Info *&Records,
380                                 unsigned &NumRecords) const {
381    Records = BuiltinInfo;
382    NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
383  }
384  virtual const char *getVAListDeclaration() const {
385    return "typedef struct __va_list_tag {"
386           "  unsigned char gpr;"
387           "  unsigned char fpr;"
388           "  unsigned short reserved;"
389           "  void* overflow_arg_area;"
390           "  void* reg_save_area;"
391           "} __builtin_va_list[1];";
392  }
393  virtual const char *getTargetPrefix() const {
394    return "ppc";
395  }
396  virtual void getGCCRegNames(const char * const *&Names,
397                              unsigned &NumNames) const;
398  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
399                                unsigned &NumAliases) const;
400  virtual bool validateAsmConstraint(char c,
401                                     TargetInfo::ConstraintInfo &info) const {
402    switch (c) {
403    default: return false;
404    case 'O': // Zero
405      return true;
406    case 'b': // Base register
407    case 'f': // Floating point register
408      info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
409      return true;
410    }
411  }
412  virtual const char *getClobbers() const {
413    return "";
414  }
415};
416
417const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
418#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
419#include "clang/AST/PPCBuiltins.def"
420};
421
422const char * const PPCTargetInfo::GCCRegNames[] = {
423  "0", "1", "2", "3", "4", "5", "6", "7",
424  "8", "9", "10", "11", "12", "13", "14", "15",
425  "16", "17", "18", "19", "20", "21", "22", "23",
426  "24", "25", "26", "27", "28", "29", "30", "31",
427  "0", "1", "2", "3", "4", "5", "6", "7",
428  "8", "9", "10", "11", "12", "13", "14", "15",
429  "16", "17", "18", "19", "20", "21", "22", "23",
430  "24", "25", "26", "27", "28", "29", "30", "31",
431  "mq", "lr", "ctr", "ap",
432  "0", "1", "2", "3", "4", "5", "6", "7",
433  "xer",
434  "0", "1", "2", "3", "4", "5", "6", "7",
435  "8", "9", "10", "11", "12", "13", "14", "15",
436  "16", "17", "18", "19", "20", "21", "22", "23",
437  "24", "25", "26", "27", "28", "29", "30", "31",
438  "vrsave", "vscr",
439  "spe_acc", "spefscr",
440  "sfp"
441};
442
443void PPCTargetInfo::getGCCRegNames(const char * const *&Names,
444                                   unsigned &NumNames) const {
445  Names = GCCRegNames;
446  NumNames = llvm::array_lengthof(GCCRegNames);
447}
448
449const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
450  // While some of these aliases do map to different registers
451  // they still share the same register name.
452  { { "cc", "cr0", "fr0", "r0", "v0"}, "0" },
453  { { "cr1", "fr1", "r1", "sp", "v1"}, "1" },
454  { { "cr2", "fr2", "r2", "toc", "v2"}, "2" },
455  { { "cr3", "fr3", "r3", "v3"}, "3" },
456  { { "cr4", "fr4", "r4", "v4"}, "4" },
457  { { "cr5", "fr5", "r5", "v5"}, "5" },
458  { { "cr6", "fr6", "r6", "v6"}, "6" },
459  { { "cr7", "fr7", "r7", "v7"}, "7" },
460  { { "fr8", "r8", "v8"}, "8" },
461  { { "fr9", "r9", "v9"}, "9" },
462  { { "fr10", "r10", "v10"}, "10" },
463  { { "fr11", "r11", "v11"}, "11" },
464  { { "fr12", "r12", "v12"}, "12" },
465  { { "fr13", "r13", "v13"}, "13" },
466  { { "fr14", "r14", "v14"}, "14" },
467  { { "fr15", "r15", "v15"}, "15" },
468  { { "fr16", "r16", "v16"}, "16" },
469  { { "fr17", "r17", "v17"}, "17" },
470  { { "fr18", "r18", "v18"}, "18" },
471  { { "fr19", "r19", "v19"}, "19" },
472  { { "fr20", "r20", "v20"}, "20" },
473  { { "fr21", "r21", "v21"}, "21" },
474  { { "fr22", "r22", "v22"}, "22" },
475  { { "fr23", "r23", "v23"}, "23" },
476  { { "fr24", "r24", "v24"}, "24" },
477  { { "fr25", "r25", "v25"}, "25" },
478  { { "fr26", "r26", "v26"}, "26" },
479  { { "fr27", "r27", "v27"}, "27" },
480  { { "fr28", "r28", "v28"}, "28" },
481  { { "fr29", "r29", "v29"}, "29" },
482  { { "fr30", "r30", "v30"}, "30" },
483  { { "fr31", "r31", "v31"}, "31" },
484};
485
486void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
487                                     unsigned &NumAliases) const {
488  Aliases = GCCRegAliases;
489  NumAliases = llvm::array_lengthof(GCCRegAliases);
490}
491} // end anonymous namespace.
492
493namespace {
494class PPC32TargetInfo : public PPCTargetInfo {
495public:
496  PPC32TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
497    DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
498                        "i64:64:64-f32:32:32-f64:64:64-v128:128:128";
499  }
500  virtual void getTargetDefines(std::vector<char> &Defines) const {
501    getPowerPCDefines(Defines, false);
502  }
503};
504} // end anonymous namespace.
505
506namespace {
507class PPC64TargetInfo : public PPCTargetInfo {
508public:
509  PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
510    LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
511    DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
512                        "i64:64:64-f32:32:32-f64:64:64-v128:128:128";
513  }
514  virtual void getTargetDefines(std::vector<char> &Defines) const {
515    getPowerPCDefines(Defines, true);
516  }
517};
518} // end anonymous namespace.
519
520namespace {
521class DarwinPPCTargetInfo : public PPC32TargetInfo {
522public:
523  DarwinPPCTargetInfo(const std::string& triple) : PPC32TargetInfo(triple) {}
524  virtual void getTargetDefines(std::vector<char> &Defines) const {
525    PPC32TargetInfo::getTargetDefines(Defines);
526    getDarwinDefines(Defines, getTargetTriple());
527  }
528
529  virtual bool useNeXTRuntimeAsDefault() const { return true; }
530};
531} // end anonymous namespace.
532
533namespace {
534class DarwinPPC64TargetInfo : public PPC64TargetInfo {
535public:
536  DarwinPPC64TargetInfo(const std::string& triple) : PPC64TargetInfo(triple) {}
537  virtual void getTargetDefines(std::vector<char> &Defines) const {
538    PPC64TargetInfo::getTargetDefines(Defines);
539    getDarwinDefines(Defines, getTargetTriple());
540  }
541
542  virtual bool useNeXTRuntimeAsDefault() const { return true; }
543};
544} // end anonymous namespace.
545
546namespace {
547// Namespace for x86 abstract base class
548const Builtin::Info BuiltinInfo[] = {
549#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
550#include "clang/AST/X86Builtins.def"
551};
552
553const char *GCCRegNames[] = {
554  "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
555  "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
556  "argp", "flags", "fspr", "dirflag", "frame",
557  "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
558  "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
559  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
560  "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
561};
562
563const TargetInfo::GCCRegAlias GCCRegAliases[] = {
564  { { "al", "ah", "eax", "rax" }, "ax" },
565  { { "bl", "bh", "ebx", "rbx" }, "bx" },
566  { { "cl", "ch", "ecx", "rcx" }, "cx" },
567  { { "dl", "dh", "edx", "rdx" }, "dx" },
568  { { "esi", "rsi" }, "si" },
569  { { "edi", "rdi" }, "di" },
570  { { "esp", "rsp" }, "sp" },
571  { { "ebp", "rbp" }, "bp" },
572};
573
574// X86 target abstract base class; x86-32 and x86-64 are very close, so
575// most of the implementation can be shared.
576class X86TargetInfo : public TargetInfo {
577public:
578  X86TargetInfo(const std::string& triple) : TargetInfo(triple) {
579    LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
580  }
581  virtual void getTargetBuiltins(const Builtin::Info *&Records,
582                                 unsigned &NumRecords) const {
583    Records = BuiltinInfo;
584    NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
585  }
586  virtual const char *getTargetPrefix() const {
587    return "x86";
588  }
589  virtual void getGCCRegNames(const char * const *&Names,
590                              unsigned &NumNames) const {
591    Names = GCCRegNames;
592    NumNames = llvm::array_lengthof(GCCRegNames);
593  }
594  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
595                                unsigned &NumAliases) const {
596    Aliases = GCCRegAliases;
597    NumAliases = llvm::array_lengthof(GCCRegAliases);
598  }
599  virtual bool validateAsmConstraint(char c,
600                                     TargetInfo::ConstraintInfo &info) const;
601  virtual std::string convertConstraint(const char Constraint) const;
602  virtual const char *getClobbers() const {
603    return "~{dirflag},~{fpsr},~{flags}";
604  }
605};
606
607bool
608X86TargetInfo::validateAsmConstraint(char c,
609                                     TargetInfo::ConstraintInfo &info) const {
610  switch (c) {
611  default: return false;
612  case 'a': // eax.
613  case 'b': // ebx.
614  case 'c': // ecx.
615  case 'd': // edx.
616  case 'S': // esi.
617  case 'D': // edi.
618  case 'A': // edx:eax.
619  case 't': // top of floating point stack.
620  case 'u': // second from top of floating point stack.
621  case 'q': // Any register accessible as [r]l: a, b, c, and d.
622  case 'Q': // Any register accessible as [r]h: a, b, c, and d.
623  case 'Z': // 32-bit integer constant for use with zero-extending x86_64
624            // instructions.
625  case 'N': // unsigned 8-bit integer constant for use with in and out
626            // instructions.
627    info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
628    return true;
629  }
630}
631
632std::string
633X86TargetInfo::convertConstraint(const char Constraint) const {
634  switch (Constraint) {
635  case 'a': return std::string("{ax}");
636  case 'b': return std::string("{bx}");
637  case 'c': return std::string("{cx}");
638  case 'd': return std::string("{dx}");
639  case 'S': return std::string("{si}");
640  case 'D': return std::string("{di}");
641  case 't': // top of floating point stack.
642    return std::string("{st}");
643  case 'u': // second from top of floating point stack.
644    return std::string("{st(1)}"); // second from top of floating point stack.
645  default:
646    return std::string(1, Constraint);
647  }
648}
649} // end anonymous namespace
650
651namespace {
652// X86-32 generic target
653class X86_32TargetInfo : public X86TargetInfo {
654public:
655  X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
656    DoubleAlign = LongLongAlign = 32;
657    LongDoubleWidth = 96;
658    LongDoubleAlign = 32;
659    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
660                        "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
661                        "a0:0:64-f80:32:32";
662  }
663  virtual const char *getVAListDeclaration() const {
664    return "typedef char* __builtin_va_list;";
665  }
666  virtual void getTargetDefines(std::vector<char> &Defines) const {
667    getX86Defines(Defines, false);
668  }
669};
670} // end anonymous namespace
671
672namespace {
673// x86-32 Darwin (OS X) target
674class DarwinI386TargetInfo : public X86_32TargetInfo {
675public:
676  DarwinI386TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
677    LongDoubleWidth = 128;
678    LongDoubleAlign = 128;
679    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
680                        "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
681                        "a0:0:64-f80:128:128";
682  }
683  virtual void getTargetDefines(std::vector<char> &Defines) const {
684    X86_32TargetInfo::getTargetDefines(Defines);
685    getDarwinDefines(Defines, getTargetTriple());
686  }
687  virtual bool useNeXTRuntimeAsDefault() const { return true; }
688};
689} // end anonymous namespace
690
691namespace {
692// x86-32 DragonFly target
693class DragonFlyX86_32TargetInfo : public X86_32TargetInfo {
694public:
695  DragonFlyX86_32TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
696  }
697  virtual void getTargetDefines(std::vector<char> &Defines) const {
698    X86_32TargetInfo::getTargetDefines(Defines);
699    getDragonFlyDefines(Defines);
700  }
701};
702} // end anonymous namespace
703
704namespace {
705// x86-32 Linux target
706class LinuxX86_32TargetInfo : public X86_32TargetInfo {
707public:
708  LinuxX86_32TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
709    UserLabelPrefix = "";
710  }
711  virtual void getTargetDefines(std::vector<char> &Defines) const {
712    X86_32TargetInfo::getTargetDefines(Defines);
713    getLinuxDefines(Defines);
714  }
715};
716} // end anonymous namespace
717
718namespace {
719// x86-32 Windows target
720class WindowsX86_32TargetInfo : public X86_32TargetInfo {
721public:
722  WindowsX86_32TargetInfo(const std::string& triple)
723    : X86_32TargetInfo(triple) {
724    // FIXME: Fix wchar_t.
725    // FIXME: We should probably enable -fms-extensions by default for
726    // this target.
727  }
728  virtual void getTargetDefines(std::vector<char> &Defines) const {
729    X86_32TargetInfo::getTargetDefines(Defines);
730    // This list is based off of the the list of things MingW defines
731    Define(Defines, "__WIN32__");
732    Define(Defines, "__WIN32");
733    Define(Defines, "_WIN32");
734    Define(Defines, "WIN32");
735    Define(Defines, "__WINNT__");
736    Define(Defines, "__WINNT");
737    Define(Defines, "WINNT");
738    Define(Defines, "_X86_");
739    Define(Defines, "__MSVCRT__");
740  }
741};
742} // end anonymous namespace
743
744namespace {
745// x86-64 generic target
746class X86_64TargetInfo : public X86TargetInfo {
747public:
748  X86_64TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
749    LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
750    LongDoubleWidth = 128;
751    LongDoubleAlign = 128;
752    DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
753                        "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
754                        "a0:0:64-f80:128:128";
755  }
756  virtual const char *getVAListDeclaration() const {
757    return "typedef struct __va_list_tag {"
758           "  unsigned gp_offset;"
759           "  unsigned fp_offset;"
760           "  void* overflow_arg_area;"
761           "  void* reg_save_area;"
762           "} __builtin_va_list[1];";
763  }
764  virtual void getTargetDefines(std::vector<char> &Defines) const {
765    getX86Defines(Defines, true);
766  }
767};
768} // end anonymous namespace
769
770namespace {
771// x86-64 Linux target
772class LinuxX86_64TargetInfo : public X86_64TargetInfo {
773public:
774  LinuxX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) {
775    UserLabelPrefix = "";
776  }
777  virtual void getTargetDefines(std::vector<char> &Defines) const {
778    X86_64TargetInfo::getTargetDefines(Defines);
779    getLinuxDefines(Defines);
780  }
781};
782} // end anonymous namespace
783
784namespace {
785// x86-64 Darwin (OS X) target
786class DarwinX86_64TargetInfo : public X86_64TargetInfo {
787public:
788  DarwinX86_64TargetInfo(const std::string& triple) :
789    X86_64TargetInfo(triple) {}
790
791  virtual void getTargetDefines(std::vector<char> &Defines) const {
792    X86_64TargetInfo::getTargetDefines(Defines);
793    getDarwinDefines(Defines, getTargetTriple());
794  }
795
796  virtual bool useNeXTRuntimeAsDefault() const { return true; }
797};
798} // end anonymous namespace.
799
800namespace {
801class ARMTargetInfo : public TargetInfo {
802public:
803  ARMTargetInfo(const std::string& triple) : TargetInfo(triple) {
804    // FIXME: Are the defaults correct for ARM?
805    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
806                        "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:64";
807  }
808  virtual void getTargetDefines(std::vector<char> &Defines) const {
809    getARMDefines(Defines);
810  }
811  virtual void getTargetBuiltins(const Builtin::Info *&Records,
812                                 unsigned &NumRecords) const {
813    // FIXME: Implement.
814    Records = 0;
815    NumRecords = 0;
816  }
817  virtual const char *getVAListDeclaration() const {
818    return "typedef char* __builtin_va_list;";
819  }
820  virtual const char *getTargetPrefix() const {
821    return "arm";
822  }
823  virtual void getGCCRegNames(const char * const *&Names,
824                              unsigned &NumNames) const {
825    // FIXME: Implement.
826    Names = 0;
827    NumNames = 0;
828  }
829  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
830                                unsigned &NumAliases) const {
831    // FIXME: Implement.
832    Aliases = 0;
833    NumAliases = 0;
834  }
835  virtual bool validateAsmConstraint(char c,
836                                     TargetInfo::ConstraintInfo &info) const {
837    // FIXME: Check if this is complete
838    switch (c) {
839    default:
840    case 'l': // r0-r7
841    case 'h': // r8-r15
842    case 'w': // VFP Floating point register single precision
843    case 'P': // VFP Floating point register double precision
844      info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
845      return true;
846    }
847    return false;
848  }
849  virtual const char *getClobbers() const {
850    // FIXME: Is this really right?
851    return "";
852  }
853};
854} // end anonymous namespace.
855
856
857namespace {
858class DarwinARMTargetInfo : public ARMTargetInfo {
859public:
860  DarwinARMTargetInfo(const std::string& triple) : ARMTargetInfo(triple) {}
861
862  virtual void getTargetDefines(std::vector<char> &Defines) const {
863    ARMTargetInfo::getTargetDefines(Defines);
864    getDarwinDefines(Defines, getTargetTriple());
865  }
866};
867} // end anonymous namespace.
868
869namespace {
870class SparcV8TargetInfo : public TargetInfo {
871public:
872  SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
873    // FIXME: Support Sparc quad-precision long double?
874    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
875                        "i64:64:64-f32:32:32-f64:64:64-v64:64:64";
876  }
877  virtual void getTargetDefines(std::vector<char> &Defines) const {
878    // FIXME: This is missing a lot of important defines; some of the
879    // missing stuff is likely to break system headers.
880    Define(Defines, "__sparc");
881    Define(Defines, "__sparc__");
882    Define(Defines, "__sparcv8");
883  }
884  virtual void getTargetBuiltins(const Builtin::Info *&Records,
885                                 unsigned &NumRecords) const {
886    // FIXME: Implement!
887  }
888  virtual const char *getVAListDeclaration() const {
889    return "typedef void* __builtin_va_list;";
890  }
891  virtual const char *getTargetPrefix() const {
892    return "sparc";
893  }
894  virtual void getGCCRegNames(const char * const *&Names,
895                              unsigned &NumNames) const {
896    // FIXME: Implement!
897    Names = 0;
898    NumNames = 0;
899  }
900  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
901                                unsigned &NumAliases) const {
902    // FIXME: Implement!
903    Aliases = 0;
904    NumAliases = 0;
905  }
906  virtual bool validateAsmConstraint(char c,
907                                     TargetInfo::ConstraintInfo &info) const {
908    // FIXME: Implement!
909    return false;
910  }
911  virtual const char *getClobbers() const {
912    // FIXME: Implement!
913    return "";
914  }
915};
916
917} // end anonymous namespace.
918
919namespace {
920class SolarisSparcV8TargetInfo : public SparcV8TargetInfo {
921public:
922  SolarisSparcV8TargetInfo(const std::string& triple) :
923    SparcV8TargetInfo(triple) {}
924
925  virtual void getTargetDefines(std::vector<char> &Defines) const {
926    SparcV8TargetInfo::getTargetDefines(Defines);
927    getSolarisDefines(Defines);
928  }
929};
930} // end anonymous namespace.
931
932namespace {
933  class PIC16TargetInfo : public TargetInfo{
934  public:
935    PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) {
936      // FIXME: Is IntAlign really supposed to be 16?  There seems
937      // little point on a platform with 8-bit loads.
938      IntWidth = IntAlign = LongAlign = LongLongAlign = PointerWidth = 16;
939      PointerAlign = 8;
940      DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8";
941    }
942    virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; }
943    virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; }
944    virtual void getTargetDefines(std::vector<char> &Defines) const {
945      Define(Defines, "__pic16");
946    }
947    virtual void getTargetBuiltins(const Builtin::Info *&Records,
948                                   unsigned &NumRecords) const {}
949    virtual const char *getVAListDeclaration() const { return "";}
950    virtual const char *getClobbers() const {return "";}
951    virtual const char *getTargetPrefix() const {return "";}
952    virtual void getGCCRegNames(const char * const *&Names,
953                                unsigned &NumNames) const {}
954    virtual bool validateAsmConstraint(char c,
955                                       TargetInfo::ConstraintInfo &info) const {
956      return true;
957    }
958    virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
959                                  unsigned &NumAliases) const {}
960    virtual bool useGlobalsForAutomaticVariables() const {return true;}
961  };
962}
963
964//===----------------------------------------------------------------------===//
965// Driver code
966//===----------------------------------------------------------------------===//
967
968static inline bool IsX86(const std::string& TT) {
969  return (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' &&
970          TT[4] == '-' && TT[1] - '3' < 6);
971}
972
973/// CreateTargetInfo - Return the target info object for the specified target
974/// triple.
975TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
976  // OS detection; this isn't really anywhere near complete.
977  // Additions and corrections are welcome.
978  bool isDarwin = T.find("-darwin") != std::string::npos;
979  bool isDragonFly = T.find("-dragonfly") != std::string::npos;
980  bool isSolaris = T.find("-solaris") != std::string::npos;
981  bool isLinux = T.find("-linux") != std::string::npos;
982  bool isWindows = T.find("-windows") != std::string::npos ||
983                   T.find("-win32") != std::string::npos ||
984                   T.find("-mingw") != std::string::npos;
985
986  if (T.find("ppc-") == 0 || T.find("powerpc-") == 0) {
987    if (isDarwin)
988      return new DarwinPPCTargetInfo(T);
989    return new PPC32TargetInfo(T);
990  }
991
992  if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0) {
993    if (isDarwin)
994      return new DarwinPPC64TargetInfo(T);
995    return new PPC64TargetInfo(T);
996  }
997
998  if (T.find("armv6-") == 0 || T.find("arm-") == 0) {
999    if (isDarwin)
1000      return new DarwinARMTargetInfo(T);
1001    return new ARMTargetInfo(T);
1002  }
1003
1004  if (T.find("sparc-") == 0) {
1005    if (isSolaris)
1006      return new SolarisSparcV8TargetInfo(T);
1007    return new SparcV8TargetInfo(T);
1008  }
1009
1010  if (T.find("x86_64-") == 0) {
1011    if (isDarwin)
1012      return new DarwinX86_64TargetInfo(T);
1013    if (isLinux)
1014      return new LinuxX86_64TargetInfo(T);
1015    return new X86_64TargetInfo(T);
1016  }
1017
1018  if (T.find("pic16-") == 0)
1019    return new PIC16TargetInfo(T);
1020
1021  if (IsX86(T)) {
1022    if (isDarwin)
1023      return new DarwinI386TargetInfo(T);
1024    if (isLinux)
1025      return new LinuxX86_32TargetInfo(T);
1026    if (isDragonFly)
1027      return new DragonFlyX86_32TargetInfo(T);
1028    if (isWindows)
1029      return new WindowsX86_32TargetInfo(T);
1030    return new X86_32TargetInfo(T);
1031  }
1032
1033  return NULL;
1034}
1035
1036