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