blob: ce55ec8046535a12c466abdd498f064efdb13c48 [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
Douglas Gregor9eebd972009-02-16 21:58:21 +000015// FIXME: Layering violation
Chris Lattner10a5b382007-01-29 05:24:35 +000016#include "clang/AST/Builtins.h"
Anders Carlsson895af082007-12-09 23:17:02 +000017#include "clang/AST/TargetBuiltins.h"
Chris Lattner5ba61f02006-10-14 07:39:34 +000018#include "clang/Basic/TargetInfo.h"
Chris Lattnerc7c6dd42008-12-04 22:54:33 +000019#include "clang/Basic/LangOptions.h"
Anders Carlsson5fa3f342007-11-24 23:38:12 +000020#include "llvm/ADT/STLExtras.h"
Eli Friedman7cef49e2008-05-20 14:27:34 +000021#include "llvm/ADT/APFloat.h"
Chris Lattner1e1c0b92009-03-20 16:06:38 +000022#include "llvm/ADT/SmallString.h"
Chris Lattner5ba61f02006-10-14 07:39:34 +000023using namespace clang;
24
Chris Lattner5ba61f02006-10-14 07:39:34 +000025//===----------------------------------------------------------------------===//
Chris Lattner1f5ad112006-10-14 18:32:12 +000026// Common code shared among targets.
Chris Lattner5ba61f02006-10-14 07:39:34 +000027//===----------------------------------------------------------------------===//
28
Chris Lattnerb2d486a2007-10-06 06:57:34 +000029static void Define(std::vector<char> &Buf, const char *Macro,
30 const char *Val = "1") {
31 const char *Def = "#define ";
32 Buf.insert(Buf.end(), Def, Def+strlen(Def));
33 Buf.insert(Buf.end(), Macro, Macro+strlen(Macro));
34 Buf.push_back(' ');
35 Buf.insert(Buf.end(), Val, Val+strlen(Val));
36 Buf.push_back('\n');
37}
38
Chris Lattner1e1c0b92009-03-20 16:06:38 +000039/// DefineStd - Define a macro name and standard variants. For example if
40/// MacroName is "unix", then this will define "__unix", "__unix__", and "unix"
41/// when in GNU mode.
42static void DefineStd(std::vector<char> &Buf, const char *MacroName,
43 const LangOptions &Opts) {
44 assert(MacroName[0] != '_' && "Identifier should be in the user's namespace");
45
46 // If in GNU mode (e.g. -std=gnu99 but not -std=c99) define the raw identifier
47 // in the user's namespace.
48 if (Opts.GNUMode)
49 Define(Buf, MacroName);
50
51 // Define __unix.
52 llvm::SmallString<20> TmpStr;
53 TmpStr = "__";
54 TmpStr += MacroName;
55 Define(Buf, TmpStr.c_str());
56
57 // Define __unix__.
58 TmpStr += "__";
59 Define(Buf, TmpStr.c_str());
60}
61
Chris Lattner09d98f52008-10-05 21:50:58 +000062//===----------------------------------------------------------------------===//
63// Defines specific to certain operating systems.
64//===----------------------------------------------------------------------===//
65
Eli Friedmanda8f5a92008-08-20 07:28:14 +000066static void getSolarisDefines(std::vector<char> &Defs) {
67 Define(Defs, "__SUN__");
68 Define(Defs, "__SOLARIS__");
69}
Chris Lattner5ba61f02006-10-14 07:39:34 +000070
Chris Lattnera1321f12009-03-20 15:55:34 +000071static void getFreeBSDDefines(const LangOptions &Opts, bool is64Bit,
72 const char *Triple, std::vector<char> &Defs) {
Chris Lattner3c3e2cc2008-10-16 17:04:31 +000073 // FreeBSD defines; list based off of gcc output
74
75 const char *FreeBSD = strstr(Triple, "-freebsd");
76 FreeBSD += strlen("-freebsd");
77 char release[] = "X";
78 release[0] = FreeBSD[0];
79 char version[] = "X00001";
80 version[0] = FreeBSD[0];
81
82 Define(Defs, "__FreeBSD__", release);
83 Define(Defs, "__FreeBSD_cc_version", version);
84 Define(Defs, "__KPRINTF_ATTRIBUTE__");
Chris Lattner1e1c0b92009-03-20 16:06:38 +000085 DefineStd(Defs, "unix", Opts);
Anton Korobeynikov7e965952009-02-14 16:42:50 +000086 Define(Defs, "__ELF__", "1");
Chris Lattner3c3e2cc2008-10-16 17:04:31 +000087 if (is64Bit) {
88 Define(Defs, "__LP64__");
89 }
90}
91
Chris Lattnera1321f12009-03-20 15:55:34 +000092static void getDragonFlyDefines(const LangOptions &Opts,
93 std::vector<char> &Defs) {
Chris Lattner09d98f52008-10-05 21:50:58 +000094 // DragonFly defines; list based off of gcc output
95 Define(Defs, "__DragonFly__");
96 Define(Defs, "__DragonFly_cc_version", "100001");
97 Define(Defs, "__ELF__");
98 Define(Defs, "__KPRINTF_ATTRIBUTE__");
99 Define(Defs, "__tune_i386__");
Chris Lattner1e1c0b92009-03-20 16:06:38 +0000100 DefineStd(Defs, "unix", Opts);
Chris Lattner09d98f52008-10-05 21:50:58 +0000101}
102
Chris Lattnera1321f12009-03-20 15:55:34 +0000103static void getLinuxDefines(const LangOptions &Opts, std::vector<char> &Defs) {
Chris Lattner09d98f52008-10-05 21:50:58 +0000104 // Linux defines; list based off of gcc output
Chris Lattner1e1c0b92009-03-20 16:06:38 +0000105 DefineStd(Defs, "unix", Opts);
106 DefineStd(Defs, "linux", Opts);
Chris Lattner09d98f52008-10-05 21:50:58 +0000107 Define(Defs, "__gnu_linux__");
Argyrios Kyrtzidisd831cac2009-02-14 15:02:45 +0000108 Define(Defs, "__ELF__", "1");
Chris Lattner09d98f52008-10-05 21:50:58 +0000109}
110
Chris Lattner2ca529c2008-12-04 23:20:07 +0000111/// getDarwinNumber - Parse the 'darwin number' out of the specific targe
112/// triple. For example, if we have darwin8.5 return 8,5,4. If any entry is
113/// not defined, return 0's. Return true if we have -darwin in the string or
114/// false otherwise.
115static bool getDarwinNumber(const char *Triple, unsigned &Maj, unsigned &Min) {
116 Maj = Min = 0;
117 const char *Darwin = strstr(Triple, "-darwin");
118 if (Darwin == 0) return false;
119
120 Darwin += strlen("-darwin");
121 if (Darwin[0] < '0' || Darwin[0] > '9')
122 return true;
123
124 Maj = Darwin[0]-'0';
125 ++Darwin;
126
127 // Handle "darwin11".
128 if (Maj == 1 && Darwin[0] >= '0' && Darwin[0] <= '9') {
129 Maj = 10+Darwin[0]-'0';
130 ++Darwin;
131 }
132
133 // Handle minor version: 10.4.9 -> darwin8.9 -> "1049"
134 if (Darwin[0] == '.' && Darwin[1] >= '0' && Darwin[1] <= '9' &&
135 Darwin[2] == '\0')
136 Min = Darwin[1]-'0';
137
138 return true;
139}
140
Chris Lattnerb3793bb2008-09-30 01:00:25 +0000141static void getDarwinDefines(std::vector<char> &Defs, const char *Triple) {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000142 Define(Defs, "__APPLE__");
143 Define(Defs, "__MACH__");
Chris Lattner81813122009-02-05 07:19:24 +0000144 Define(Defs, "OBJC_NEW_PROPERTIES");
145
146 // FIXME: OBJC_ZEROCOST_EXCEPTIONS when using zero cost eh.
Chris Lattnerb3793bb2008-09-30 01:00:25 +0000147
148 // Figure out which "darwin number" the target triple is. "darwin9" -> 10.5.
Chris Lattner2ca529c2008-12-04 23:20:07 +0000149 unsigned Maj, Min;
150 if (getDarwinNumber(Triple, Maj, Min)) {
Chris Lattner97d74942008-09-30 20:30:12 +0000151 char DarwinStr[] = "1000";
Chris Lattner2ca529c2008-12-04 23:20:07 +0000152 if (Maj >= 4 && Maj <= 13) { // 10.0-10.9
153 // darwin7 -> 1030, darwin8 -> 1040, darwin9 -> 1050, etc.
154 DarwinStr[2] = '0' + Maj-4;
Chris Lattnerb3793bb2008-09-30 01:00:25 +0000155 }
Chris Lattner2ca529c2008-12-04 23:20:07 +0000156
157 // Handle minor version: 10.4.9 -> darwin8.9 -> "1049"
158 DarwinStr[3] = Min+'0';
Chris Lattner97d74942008-09-30 20:30:12 +0000159 Define(Defs, "__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", DarwinStr);
Chris Lattnerb3793bb2008-09-30 01:00:25 +0000160 }
Eli Friedman3fd920a2008-08-20 02:34:37 +0000161}
Chris Lattner5ba61f02006-10-14 07:39:34 +0000162
Chris Lattner2ca529c2008-12-04 23:20:07 +0000163/// GetDarwinLanguageOptions - Set the default language options for darwin.
164static void GetDarwinLanguageOptions(LangOptions &Opts,
165 const char *Triple) {
166 Opts.NeXTRuntime = true;
167
168 unsigned Maj, Min;
169 if (!getDarwinNumber(Triple, Maj, Min))
170 return;
171
172 // Blocks default to on for 10.6 (darwin10) and beyond.
Fariborz Jahanian13de2532009-02-12 17:54:33 +0000173 // As does nonfragile-abi for 64bit mode
Fariborz Jahanian240f2b72009-02-24 23:34:44 +0000174 if (Maj > 9)
Chris Lattner2ca529c2008-12-04 23:20:07 +0000175 Opts.Blocks = 1;
Fariborz Jahanian240f2b72009-02-24 23:34:44 +0000176
Fariborz Jahanian30b3ac52009-02-24 23:38:42 +0000177 if (Maj >= 9 && Opts.ObjC1 && !strncmp(Triple, "x86_64", 6))
178 Opts.ObjCNonFragileABI = 1;
Chris Lattner2ca529c2008-12-04 23:20:07 +0000179}
180
181
Chris Lattner09d98f52008-10-05 21:50:58 +0000182//===----------------------------------------------------------------------===//
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000183// Specific target implementations.
184//===----------------------------------------------------------------------===//
Anders Carlssona7408e72007-10-13 00:45:48 +0000185
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000186namespace {
187// PPC abstract base class
188class PPCTargetInfo : public TargetInfo {
189 static const Builtin::Info BuiltinInfo[];
190 static const char * const GCCRegNames[];
191 static const TargetInfo::GCCRegAlias GCCRegAliases[];
192
193public:
194 PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {
195 CharIsSigned = false;
196 }
197 virtual void getTargetBuiltins(const Builtin::Info *&Records,
198 unsigned &NumRecords) const {
Chris Lattner10a5b382007-01-29 05:24:35 +0000199 Records = BuiltinInfo;
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000200 NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner10a5b382007-01-29 05:24:35 +0000201 }
Chris Lattnerecd49032009-03-02 22:27:17 +0000202
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000203 virtual void getTargetDefines(const LangOptions &Opts,
204 std::vector<char> &Defines) const;
Chris Lattnerecd49032009-03-02 22:27:17 +0000205
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000206 virtual const char *getVAListDeclaration() const {
Chris Lattner69f9bc22008-10-27 01:11:29 +0000207 return "typedef char* __builtin_va_list;";
208 // This is the right definition for ABI/V4: System V.4/eabi.
209 /*return "typedef struct __va_list_tag {"
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000210 " unsigned char gpr;"
211 " unsigned char fpr;"
212 " unsigned short reserved;"
213 " void* overflow_arg_area;"
214 " void* reg_save_area;"
Chris Lattner69f9bc22008-10-27 01:11:29 +0000215 "} __builtin_va_list[1];";*/
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000216 }
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000217 virtual const char *getTargetPrefix() const {
218 return "ppc";
Anders Carlssonf511f642007-11-27 04:11:28 +0000219 }
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000220 virtual void getGCCRegNames(const char * const *&Names,
221 unsigned &NumNames) const;
222 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
223 unsigned &NumAliases) const;
Anders Carlsson58436352009-02-28 17:11:49 +0000224 virtual bool validateAsmConstraint(const char *&Name,
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000225 TargetInfo::ConstraintInfo &info) const {
Anders Carlsson58436352009-02-28 17:11:49 +0000226 switch (*Name) {
Anders Carlssonf511f642007-11-27 04:11:28 +0000227 default: return false;
228 case 'O': // Zero
229 return true;
230 case 'b': // Base register
231 case 'f': // Floating point register
232 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
233 return true;
234 }
235 }
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000236 virtual const char *getClobbers() const {
237 return "";
Anders Carlssonf511f642007-11-27 04:11:28 +0000238 }
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000239};
Anders Carlssonf511f642007-11-27 04:11:28 +0000240
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000241const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
Douglas Gregor9eebd972009-02-16 21:58:21 +0000242#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
243#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000244#include "clang/AST/PPCBuiltins.def"
245};
Chris Lattnerecd49032009-03-02 22:27:17 +0000246
247
248/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
249/// #defines that are not tied to a specific subtarget.
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000250void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
251 std::vector<char> &Defs) const {
Chris Lattnerecd49032009-03-02 22:27:17 +0000252 // Target identification.
253 Define(Defs, "__ppc__");
254 Define(Defs, "_ARCH_PPC");
255 Define(Defs, "__POWERPC__");
256 if (PointerWidth == 64) {
257 Define(Defs, "_ARCH_PPC64");
258 Define(Defs, "_LP64");
259 Define(Defs, "__LP64__");
260 Define(Defs, "__ppc64__");
261 } else {
262 Define(Defs, "__ppc__");
263 }
264
265 // Target properties.
266 Define(Defs, "_BIG_ENDIAN");
267 Define(Defs, "__BIG_ENDIAN__");
268
269 // Subtarget options.
270 Define(Defs, "__NATURAL_ALIGNMENT__");
271 Define(Defs, "__REGISTER_PREFIX__", "");
272
273 // FIXME: Should be controlled by command line option.
274 Define(Defs, "__LONG_DOUBLE_128__");
275}
276
Chris Lattner17df24e2008-04-21 18:56:49 +0000277
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000278const char * const PPCTargetInfo::GCCRegNames[] = {
279 "0", "1", "2", "3", "4", "5", "6", "7",
280 "8", "9", "10", "11", "12", "13", "14", "15",
281 "16", "17", "18", "19", "20", "21", "22", "23",
282 "24", "25", "26", "27", "28", "29", "30", "31",
283 "0", "1", "2", "3", "4", "5", "6", "7",
284 "8", "9", "10", "11", "12", "13", "14", "15",
285 "16", "17", "18", "19", "20", "21", "22", "23",
286 "24", "25", "26", "27", "28", "29", "30", "31",
287 "mq", "lr", "ctr", "ap",
288 "0", "1", "2", "3", "4", "5", "6", "7",
289 "xer",
290 "0", "1", "2", "3", "4", "5", "6", "7",
291 "8", "9", "10", "11", "12", "13", "14", "15",
292 "16", "17", "18", "19", "20", "21", "22", "23",
293 "24", "25", "26", "27", "28", "29", "30", "31",
294 "vrsave", "vscr",
295 "spe_acc", "spefscr",
296 "sfp"
297};
Chris Lattner10a5b382007-01-29 05:24:35 +0000298
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000299void PPCTargetInfo::getGCCRegNames(const char * const *&Names,
300 unsigned &NumNames) const {
301 Names = GCCRegNames;
302 NumNames = llvm::array_lengthof(GCCRegNames);
303}
Chris Lattner5ba61f02006-10-14 07:39:34 +0000304
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000305const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
306 // While some of these aliases do map to different registers
307 // they still share the same register name.
308 { { "cc", "cr0", "fr0", "r0", "v0"}, "0" },
309 { { "cr1", "fr1", "r1", "sp", "v1"}, "1" },
310 { { "cr2", "fr2", "r2", "toc", "v2"}, "2" },
311 { { "cr3", "fr3", "r3", "v3"}, "3" },
312 { { "cr4", "fr4", "r4", "v4"}, "4" },
313 { { "cr5", "fr5", "r5", "v5"}, "5" },
314 { { "cr6", "fr6", "r6", "v6"}, "6" },
315 { { "cr7", "fr7", "r7", "v7"}, "7" },
316 { { "fr8", "r8", "v8"}, "8" },
317 { { "fr9", "r9", "v9"}, "9" },
318 { { "fr10", "r10", "v10"}, "10" },
319 { { "fr11", "r11", "v11"}, "11" },
320 { { "fr12", "r12", "v12"}, "12" },
321 { { "fr13", "r13", "v13"}, "13" },
322 { { "fr14", "r14", "v14"}, "14" },
323 { { "fr15", "r15", "v15"}, "15" },
324 { { "fr16", "r16", "v16"}, "16" },
325 { { "fr17", "r17", "v17"}, "17" },
326 { { "fr18", "r18", "v18"}, "18" },
327 { { "fr19", "r19", "v19"}, "19" },
328 { { "fr20", "r20", "v20"}, "20" },
329 { { "fr21", "r21", "v21"}, "21" },
330 { { "fr22", "r22", "v22"}, "22" },
331 { { "fr23", "r23", "v23"}, "23" },
332 { { "fr24", "r24", "v24"}, "24" },
333 { { "fr25", "r25", "v25"}, "25" },
334 { { "fr26", "r26", "v26"}, "26" },
335 { { "fr27", "r27", "v27"}, "27" },
336 { { "fr28", "r28", "v28"}, "28" },
337 { { "fr29", "r29", "v29"}, "29" },
338 { { "fr30", "r30", "v30"}, "30" },
339 { { "fr31", "r31", "v31"}, "31" },
340};
341
342void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
343 unsigned &NumAliases) const {
344 Aliases = GCCRegAliases;
345 NumAliases = llvm::array_lengthof(GCCRegAliases);
346}
347} // end anonymous namespace.
Chris Lattner02dffbd2006-10-14 07:50:21 +0000348
Chris Lattner5ba61f02006-10-14 07:39:34 +0000349namespace {
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000350class PPC32TargetInfo : public PPCTargetInfo {
Chris Lattner5ba61f02006-10-14 07:39:34 +0000351public:
Eli Friedman873f65a2008-08-21 00:13:15 +0000352 PPC32TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
353 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
354 "i64:64:64-f32:32:32-f64:64:64-v128:128:128";
355 }
Chris Lattner5ba61f02006-10-14 07:39:34 +0000356};
357} // end anonymous namespace.
358
359namespace {
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000360class PPC64TargetInfo : public PPCTargetInfo {
Chris Lattner5ba61f02006-10-14 07:39:34 +0000361public:
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000362 PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
Chris Lattnerba7a6c12008-05-09 06:17:04 +0000363 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedman873f65a2008-08-21 00:13:15 +0000364 DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
365 "i64:64:64-f32:32:32-f64:64:64-v128:128:128";
Chris Lattnerba7a6c12008-05-09 06:17:04 +0000366 }
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000367};
368} // end anonymous namespace.
369
Chris Lattner2ca529c2008-12-04 23:20:07 +0000370
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000371namespace {
372class DarwinPPCTargetInfo : public PPC32TargetInfo {
373public:
374 DarwinPPCTargetInfo(const std::string& triple) : PPC32TargetInfo(triple) {}
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000375 virtual void getTargetDefines(const LangOptions &Opts,
376 std::vector<char> &Defines) const {
377 PPC32TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerb3793bb2008-09-30 01:00:25 +0000378 getDarwinDefines(Defines, getTargetTriple());
Chris Lattner10a5b382007-01-29 05:24:35 +0000379 }
Daniel Dunbarb8767ac2008-08-23 08:43:39 +0000380
Chris Lattnerc7c6dd42008-12-04 22:54:33 +0000381 /// getDefaultLangOptions - Allow the target to specify default settings for
382 /// various language options. These may be overridden by command line
383 /// options.
384 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattner2ca529c2008-12-04 23:20:07 +0000385 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattnerc7c6dd42008-12-04 22:54:33 +0000386 }
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000387};
388} // end anonymous namespace.
389
390namespace {
391class DarwinPPC64TargetInfo : public PPC64TargetInfo {
392public:
393 DarwinPPC64TargetInfo(const std::string& triple) : PPC64TargetInfo(triple) {}
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000394 virtual void getTargetDefines(const LangOptions &Opts,
395 std::vector<char> &Defines) const {
396 PPC64TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerb3793bb2008-09-30 01:00:25 +0000397 getDarwinDefines(Defines, getTargetTriple());
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000398 }
Daniel Dunbarb8767ac2008-08-23 08:43:39 +0000399
Chris Lattnerc7c6dd42008-12-04 22:54:33 +0000400 /// getDefaultLangOptions - Allow the target to specify default settings for
401 /// various language options. These may be overridden by command line
402 /// options.
403 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattner2ca529c2008-12-04 23:20:07 +0000404 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattnerc7c6dd42008-12-04 22:54:33 +0000405 }
Chris Lattner5ba61f02006-10-14 07:39:34 +0000406};
407} // end anonymous namespace.
408
409namespace {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000410// Namespace for x86 abstract base class
411const Builtin::Info BuiltinInfo[] = {
Douglas Gregor9eebd972009-02-16 21:58:21 +0000412#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
413#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
Eli Friedman3fd920a2008-08-20 02:34:37 +0000414#include "clang/AST/X86Builtins.def"
415};
Eli Friedmanb5366062008-05-20 14:21:01 +0000416
Eli Friedman3fd920a2008-08-20 02:34:37 +0000417const char *GCCRegNames[] = {
418 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
419 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
420 "argp", "flags", "fspr", "dirflag", "frame",
421 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
422 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
423 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
424 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
425};
426
427const TargetInfo::GCCRegAlias GCCRegAliases[] = {
428 { { "al", "ah", "eax", "rax" }, "ax" },
429 { { "bl", "bh", "ebx", "rbx" }, "bx" },
430 { { "cl", "ch", "ecx", "rcx" }, "cx" },
431 { { "dl", "dh", "edx", "rdx" }, "dx" },
432 { { "esi", "rsi" }, "si" },
433 { { "edi", "rdi" }, "di" },
434 { { "esp", "rsp" }, "sp" },
435 { { "ebp", "rbp" }, "bp" },
436};
437
438// X86 target abstract base class; x86-32 and x86-64 are very close, so
439// most of the implementation can be shared.
440class X86TargetInfo : public TargetInfo {
Chris Lattner96e43572009-03-02 22:40:39 +0000441 enum X86SSEEnum {
442 NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42
443 } SSELevel;
Eli Friedman3fd920a2008-08-20 02:34:37 +0000444public:
Chris Lattner96e43572009-03-02 22:40:39 +0000445 X86TargetInfo(const std::string& triple)
Chris Lattner5c352962009-03-03 19:56:18 +0000446 : TargetInfo(triple),
447 // FIXME: hard coding to SSE2 for now. This should change to NoMMXSSE so
448 // that the driver controls this.
449 SSELevel(SSE2) {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000450 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
Chris Lattner1f5ad112006-10-14 18:32:12 +0000451 }
Chris Lattner10a5b382007-01-29 05:24:35 +0000452 virtual void getTargetBuiltins(const Builtin::Info *&Records,
453 unsigned &NumRecords) const {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000454 Records = BuiltinInfo;
455 NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner10a5b382007-01-29 05:24:35 +0000456 }
Anders Carlsson050f4942007-12-08 19:32:57 +0000457 virtual const char *getTargetPrefix() const {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000458 return "x86";
Anders Carlsson050f4942007-12-08 19:32:57 +0000459 }
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000460 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedman3fd920a2008-08-20 02:34:37 +0000461 unsigned &NumNames) const {
462 Names = GCCRegNames;
463 NumNames = llvm::array_lengthof(GCCRegNames);
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000464 }
465 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
466 unsigned &NumAliases) const {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000467 Aliases = GCCRegAliases;
468 NumAliases = llvm::array_lengthof(GCCRegAliases);
Anders Carlssona7408e72007-10-13 00:45:48 +0000469 }
Anders Carlsson58436352009-02-28 17:11:49 +0000470 virtual bool validateAsmConstraint(const char *&Name,
Eli Friedman3fd920a2008-08-20 02:34:37 +0000471 TargetInfo::ConstraintInfo &info) const;
472 virtual std::string convertConstraint(const char Constraint) const;
Anders Carlssonf511f642007-11-27 04:11:28 +0000473 virtual const char *getClobbers() const {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000474 return "~{dirflag},~{fpsr},~{flags}";
475 }
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000476 virtual void getTargetDefines(const LangOptions &Opts,
477 std::vector<char> &Defines) const;
Chris Lattnerc25d8a72009-03-02 22:20:04 +0000478
Chris Lattner5c352962009-03-03 19:56:18 +0000479 virtual int HandleTargetFeatures(std::string *StrArray, unsigned NumStrs,
480 std::string &ErrorReason);
Chris Lattner5ba61f02006-10-14 07:39:34 +0000481};
Chris Lattnerc25d8a72009-03-02 22:20:04 +0000482
483/// HandleTargetOptions - Handle target-specific options like -msse2 and
484/// friends. An array of arguments is passed in: if they are all valid, this
485/// should handle them and return -1. If there is an error, the index of the
486/// invalid argument should be returned along with an optional error string.
Chris Lattner5c352962009-03-03 19:56:18 +0000487int X86TargetInfo::HandleTargetFeatures(std::string *StrArray, unsigned NumStrs,
488 std::string &ErrorReason) {
489 for (unsigned i = 0; i != NumStrs; ++i) {
490 const std::string &Feature = StrArray[i];
491 if (Feature.size() < 2) return i;
492 // Ignore explicitly disabled features.
493 if (Feature[0] == '-') continue;
494
495 // Feature strings are of the form "+feature".
496 if (Feature[0] != '+') return i;
497
498 // The set of supported subtarget features is defined in
499 // lib/Target/X86/X86.td. Here we recognize and map onto our internal
500 // state.
501 if (Feature == "+mmx")
502 SSELevel = std::max(SSELevel, MMX);
503 else if (Feature == "+sse")
504 SSELevel = std::max(SSELevel, SSE1);
505 else if (Feature == "+sse2")
506 SSELevel = std::max(SSELevel, SSE2);
507 else if (Feature == "+sse3")
508 SSELevel = std::max(SSELevel, SSE3);
509 else if (Feature == "+ssse3")
510 SSELevel = std::max(SSELevel, SSSE3);
511 else if (Feature == "+sse41")
512 SSELevel = std::max(SSELevel, SSE41);
513 else if (Feature == "+sse42")
514 SSELevel = std::max(SSELevel, SSE42);
515 else if (Feature == "+64bit" || Feature == "+slow-bt-mem")
516 // Ignore these features.
517 continue;
518 else
519 return i;
520 }
521 return -1;
Chris Lattnerc25d8a72009-03-02 22:20:04 +0000522}
Chris Lattnerecd49032009-03-02 22:27:17 +0000523
524/// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines
525/// that are not tied to a specific subtarget.
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000526void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
527 std::vector<char> &Defs) const {
Chris Lattnerecd49032009-03-02 22:27:17 +0000528 // Target identification.
529 if (PointerWidth == 64) {
530 Define(Defs, "_LP64");
531 Define(Defs, "__LP64__");
532 Define(Defs, "__amd64__");
533 Define(Defs, "__amd64");
534 Define(Defs, "__x86_64");
535 Define(Defs, "__x86_64__");
536 Define(Defs, "__SSE3__");
537 } else {
Chris Lattner1e1c0b92009-03-20 16:06:38 +0000538 DefineStd(Defs, "i386", Opts);
Chris Lattnerecd49032009-03-02 22:27:17 +0000539 }
540
541 // Target properties.
542 Define(Defs, "__LITTLE_ENDIAN__");
543
544 // Subtarget options.
545 Define(Defs, "__nocona");
546 Define(Defs, "__nocona__");
547 Define(Defs, "__tune_nocona__");
Chris Lattnerecd49032009-03-02 22:27:17 +0000548 Define(Defs, "__REGISTER_PREFIX__", "");
Chris Lattner96e43572009-03-02 22:40:39 +0000549
550 // Each case falls through to the previous one here.
551 switch (SSELevel) {
552 case SSE42:
553 Define(Defs, "__SSE4_2__");
554 case SSE41:
555 Define(Defs, "__SSE4_1__");
556 case SSSE3:
557 Define(Defs, "__SSSE3__");
558 case SSE3:
559 Define(Defs, "__SSE3__");
560 case SSE2:
561 Define(Defs, "__SSE2__");
562 Define(Defs, "__SSE2_MATH__"); // -mfp-math=sse always implied.
563 case SSE1:
564 Define(Defs, "__SSE__");
565 Define(Defs, "__SSE_MATH__"); // -mfp-math=sse always implied.
566 case MMX:
567 Define(Defs, "__MMX__");
568 case NoMMXSSE:
569 break;
570 }
Chris Lattnerecd49032009-03-02 22:27:17 +0000571}
572
Eli Friedman3fd920a2008-08-20 02:34:37 +0000573
574bool
Anders Carlsson58436352009-02-28 17:11:49 +0000575X86TargetInfo::validateAsmConstraint(const char *&Name,
Eli Friedman3fd920a2008-08-20 02:34:37 +0000576 TargetInfo::ConstraintInfo &info) const {
Anders Carlsson58436352009-02-28 17:11:49 +0000577 switch (*Name) {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000578 default: return false;
579 case 'a': // eax.
580 case 'b': // ebx.
581 case 'c': // ecx.
582 case 'd': // edx.
583 case 'S': // esi.
584 case 'D': // edi.
585 case 'A': // edx:eax.
586 case 't': // top of floating point stack.
587 case 'u': // second from top of floating point stack.
588 case 'q': // Any register accessible as [r]l: a, b, c, and d.
Anders Carlsson83661ac2008-10-06 00:41:45 +0000589 case 'y': // Any MMX register.
Anders Carlsson5f7ee682008-10-06 19:17:39 +0000590 case 'x': // Any SSE register.
Eli Friedman3fd920a2008-08-20 02:34:37 +0000591 case 'Q': // Any register accessible as [r]h: a, b, c, and d.
Anders Carlssona0b89212009-01-24 18:03:09 +0000592 case 'e': // 32-bit signed integer constant for use with zero-extending
593 // x86_64 instructions.
594 case 'Z': // 32-bit unsigned integer constant for use with zero-extending
595 // x86_64 instructions.
Eli Friedman3fd920a2008-08-20 02:34:37 +0000596 case 'N': // unsigned 8-bit integer constant for use with in and out
597 // instructions.
598 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
599 return true;
600 }
601}
602
603std::string
604X86TargetInfo::convertConstraint(const char Constraint) const {
605 switch (Constraint) {
606 case 'a': return std::string("{ax}");
607 case 'b': return std::string("{bx}");
608 case 'c': return std::string("{cx}");
609 case 'd': return std::string("{dx}");
610 case 'S': return std::string("{si}");
611 case 'D': return std::string("{di}");
612 case 't': // top of floating point stack.
613 return std::string("{st}");
614 case 'u': // second from top of floating point stack.
615 return std::string("{st(1)}"); // second from top of floating point stack.
616 default:
617 return std::string(1, Constraint);
618 }
619}
Eli Friedman3fd920a2008-08-20 02:34:37 +0000620} // end anonymous namespace
Chris Lattner5ba61f02006-10-14 07:39:34 +0000621
622namespace {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000623// X86-32 generic target
624class X86_32TargetInfo : public X86TargetInfo {
Chris Lattner5ba61f02006-10-14 07:39:34 +0000625public:
Eli Friedman3fd920a2008-08-20 02:34:37 +0000626 X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
627 DoubleAlign = LongLongAlign = 32;
628 LongDoubleWidth = 96;
629 LongDoubleAlign = 32;
Eli Friedman873f65a2008-08-21 00:13:15 +0000630 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
631 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
632 "a0:0:64-f80:32:32";
Eli Friedman32ca82a2009-03-29 20:31:09 +0000633 SizeType = UnsignedInt;
634 PtrDiffType = SignedInt;
635 IntPtrType = SignedInt;
Eli Friedman3fd920a2008-08-20 02:34:37 +0000636 }
637 virtual const char *getVAListDeclaration() const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +0000638 return "typedef char* __builtin_va_list;";
Eli Friedman3fd920a2008-08-20 02:34:37 +0000639 }
Eli Friedman3fd920a2008-08-20 02:34:37 +0000640};
641} // end anonymous namespace
642
643namespace {
644// x86-32 Darwin (OS X) target
645class DarwinI386TargetInfo : public X86_32TargetInfo {
646public:
647 DarwinI386TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
648 LongDoubleWidth = 128;
649 LongDoubleAlign = 128;
Eli Friedman32ca82a2009-03-29 20:31:09 +0000650 SizeType = UnsignedLong;
651 IntPtrType = SignedLong;
Eli Friedman873f65a2008-08-21 00:13:15 +0000652 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
653 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
654 "a0:0:64-f80:128:128";
Eli Friedman3fd920a2008-08-20 02:34:37 +0000655 }
Daniel Dunbar08b216a2009-03-31 23:42:16 +0000656
657 virtual const char *getStringSymbolPrefix(bool IsConstant) const {
658 return IsConstant ? "\01LC" : "\01lC";
659 }
660
661 virtual const char *getCFStringSymbolPrefix() const {
662 return "\01LC";
663 }
664
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000665 virtual void getTargetDefines(const LangOptions &Opts,
666 std::vector<char> &Defines) const {
667 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerb3793bb2008-09-30 01:00:25 +0000668 getDarwinDefines(Defines, getTargetTriple());
Eli Friedman3fd920a2008-08-20 02:34:37 +0000669 }
Daniel Dunbar08b216a2009-03-31 23:42:16 +0000670
Chris Lattnerc7c6dd42008-12-04 22:54:33 +0000671 /// getDefaultLangOptions - Allow the target to specify default settings for
672 /// various language options. These may be overridden by command line
673 /// options.
674 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattner2ca529c2008-12-04 23:20:07 +0000675 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattnerc7c6dd42008-12-04 22:54:33 +0000676 }
Eli Friedman3fd920a2008-08-20 02:34:37 +0000677};
678} // end anonymous namespace
679
680namespace {
Chris Lattner3c3e2cc2008-10-16 17:04:31 +0000681// x86-32 FreeBSD target
682class FreeBSDX86_32TargetInfo : public X86_32TargetInfo {
683public:
Eli Friedmand50881c2008-11-02 02:43:55 +0000684 FreeBSDX86_32TargetInfo(const std::string& triple) :
Eli Friedman32ca82a2009-03-29 20:31:09 +0000685 X86_32TargetInfo(triple) { }
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000686 virtual void getTargetDefines(const LangOptions &Opts,
687 std::vector<char> &Defines) const {
688 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnera1321f12009-03-20 15:55:34 +0000689 getFreeBSDDefines(Opts, 0, getTargetTriple(), Defines);
Chris Lattner3c3e2cc2008-10-16 17:04:31 +0000690 }
691};
692} // end anonymous namespace
693
694namespace {
Chris Lattner5637ef52008-08-23 18:23:14 +0000695// x86-32 DragonFly target
696class DragonFlyX86_32TargetInfo : public X86_32TargetInfo {
697public:
Eli Friedmand50881c2008-11-02 02:43:55 +0000698 DragonFlyX86_32TargetInfo(const std::string& triple) :
Eli Friedman32ca82a2009-03-29 20:31:09 +0000699 X86_32TargetInfo(triple) { }
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000700 virtual void getTargetDefines(const LangOptions &Opts,
701 std::vector<char> &Defines) const {
702 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnera1321f12009-03-20 15:55:34 +0000703 getDragonFlyDefines(Opts, Defines);
Chris Lattner5637ef52008-08-23 18:23:14 +0000704 }
705};
706} // end anonymous namespace
707
708namespace {
Eli Friedmanff594f22008-08-21 00:24:02 +0000709// x86-32 Linux target
710class LinuxX86_32TargetInfo : public X86_32TargetInfo {
711public:
712 LinuxX86_32TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
Chris Lattner4ecd7532008-10-05 19:44:25 +0000713 UserLabelPrefix = "";
Eli Friedmanff594f22008-08-21 00:24:02 +0000714 }
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000715 virtual void getTargetDefines(const LangOptions &Opts,
716 std::vector<char> &Defines) const {
717 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnera1321f12009-03-20 15:55:34 +0000718 getLinuxDefines(Opts, Defines);
Eli Friedmanff594f22008-08-21 00:24:02 +0000719 }
720};
721} // end anonymous namespace
722
723namespace {
Eli Friedmanc968a6a2008-08-21 01:40:19 +0000724// x86-32 Windows target
725class WindowsX86_32TargetInfo : public X86_32TargetInfo {
726public:
727 WindowsX86_32TargetInfo(const std::string& triple)
728 : X86_32TargetInfo(triple) {
729 // FIXME: Fix wchar_t.
730 // FIXME: We should probably enable -fms-extensions by default for
731 // this target.
732 }
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000733 virtual void getTargetDefines(const LangOptions &Opts,
734 std::vector<char> &Defines) const {
735 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Eli Friedmanc968a6a2008-08-21 01:40:19 +0000736 // This list is based off of the the list of things MingW defines
Eli Friedmanc968a6a2008-08-21 01:40:19 +0000737 Define(Defines, "_WIN32");
Chris Lattner1e1c0b92009-03-20 16:06:38 +0000738 DefineStd(Defines, "WIN32", Opts);
739 DefineStd(Defines, "WINNT", Opts);
Eli Friedmanc968a6a2008-08-21 01:40:19 +0000740 Define(Defines, "_X86_");
741 Define(Defines, "__MSVCRT__");
742 }
743};
744} // end anonymous namespace
745
746namespace {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000747// x86-64 generic target
748class X86_64TargetInfo : public X86TargetInfo {
749public:
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000750 X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) {
Chris Lattnerba7a6c12008-05-09 06:17:04 +0000751 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Chris Lattner22ebe7b2009-01-28 06:58:19 +0000752 DoubleAlign = LongLongAlign = 64;
Eli Friedmanb5366062008-05-20 14:21:01 +0000753 LongDoubleWidth = 128;
754 LongDoubleAlign = 128;
Chris Lattnerd0a79b22009-02-05 07:32:46 +0000755 IntMaxType = SignedLong;
756 UIntMaxType = UnsignedLong;
757
Eli Friedman873f65a2008-08-21 00:13:15 +0000758 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
759 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
760 "a0:0:64-f80:128:128";
Chris Lattner10a5b382007-01-29 05:24:35 +0000761 }
Anders Carlssona7408e72007-10-13 00:45:48 +0000762 virtual const char *getVAListDeclaration() const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +0000763 return "typedef struct __va_list_tag {"
764 " unsigned gp_offset;"
765 " unsigned fp_offset;"
766 " void* overflow_arg_area;"
767 " void* reg_save_area;"
768 "} __builtin_va_list[1];";
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000769 }
Eli Friedman3fd920a2008-08-20 02:34:37 +0000770};
771} // end anonymous namespace
772
773namespace {
Chris Lattner3c3e2cc2008-10-16 17:04:31 +0000774// x86-64 FreeBSD target
775class FreeBSDX86_64TargetInfo : public X86_64TargetInfo {
776public:
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000777 FreeBSDX86_64TargetInfo(const std::string &triple)
778 : X86_64TargetInfo(triple) {}
779 virtual void getTargetDefines(const LangOptions &Opts,
780 std::vector<char> &Defines) const {
781 X86_64TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnera1321f12009-03-20 15:55:34 +0000782 getFreeBSDDefines(Opts, 1, getTargetTriple(), Defines);
Chris Lattner3c3e2cc2008-10-16 17:04:31 +0000783 }
784};
785} // end anonymous namespace
786
787namespace {
Daniel Dunbard0921de2008-09-23 17:37:57 +0000788// x86-64 Linux target
789class LinuxX86_64TargetInfo : public X86_64TargetInfo {
790public:
791 LinuxX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) {
Chris Lattner4ecd7532008-10-05 19:44:25 +0000792 UserLabelPrefix = "";
Daniel Dunbard0921de2008-09-23 17:37:57 +0000793 }
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000794 virtual void getTargetDefines(const LangOptions &Opts,
795 std::vector<char> &Defines) const {
796 X86_64TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnera1321f12009-03-20 15:55:34 +0000797 getLinuxDefines(Opts, Defines);
Daniel Dunbard0921de2008-09-23 17:37:57 +0000798 }
799};
800} // end anonymous namespace
801
802namespace {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000803// x86-64 Darwin (OS X) target
804class DarwinX86_64TargetInfo : public X86_64TargetInfo {
805public:
806 DarwinX86_64TargetInfo(const std::string& triple) :
807 X86_64TargetInfo(triple) {}
808
Daniel Dunbar08b216a2009-03-31 23:42:16 +0000809 virtual const char *getStringSymbolPrefix(bool IsConstant) const {
810 return IsConstant ? "\01LC" : "\01lC";
811 }
812
813 virtual const char *getCFStringSymbolPrefix() const {
814 return "\01L_unnamed_cfstring_";
815 }
816
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000817 virtual void getTargetDefines(const LangOptions &Opts,
818 std::vector<char> &Defines) const {
819 X86_64TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerb3793bb2008-09-30 01:00:25 +0000820 getDarwinDefines(Defines, getTargetTriple());
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000821 }
Daniel Dunbarb8767ac2008-08-23 08:43:39 +0000822
Chris Lattnerc7c6dd42008-12-04 22:54:33 +0000823 /// getDefaultLangOptions - Allow the target to specify default settings for
824 /// various language options. These may be overridden by command line
825 /// options.
826 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattner2ca529c2008-12-04 23:20:07 +0000827 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattnerc7c6dd42008-12-04 22:54:33 +0000828 }
Chris Lattner5ba61f02006-10-14 07:39:34 +0000829};
830} // end anonymous namespace.
831
Chris Lattner17df24e2008-04-21 18:56:49 +0000832namespace {
Eli Friedmanf05b7722008-08-20 07:44:10 +0000833class ARMTargetInfo : public TargetInfo {
Chris Lattner17df24e2008-04-21 18:56:49 +0000834public:
Eli Friedmanf05b7722008-08-20 07:44:10 +0000835 ARMTargetInfo(const std::string& triple) : TargetInfo(triple) {
836 // FIXME: Are the defaults correct for ARM?
Eli Friedman873f65a2008-08-21 00:13:15 +0000837 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
838 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:64";
Eli Friedmanb5366062008-05-20 14:21:01 +0000839 }
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000840 virtual void getTargetDefines(const LangOptions &Opts,
841 std::vector<char> &Defs) const {
Chris Lattnerecd49032009-03-02 22:27:17 +0000842 // Target identification.
843 Define(Defs, "__arm");
844 Define(Defs, "__arm__");
845
846 // Target properties.
847 Define(Defs, "__LITTLE_ENDIAN__");
848
849 // Subtarget options. [hard coded to v6 for now]
850 Define(Defs, "__ARM_ARCH_6K__");
851 Define(Defs, "__ARMEL__");
852 Define(Defs, "__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", "20000");
Chris Lattner17df24e2008-04-21 18:56:49 +0000853 }
854 virtual void getTargetBuiltins(const Builtin::Info *&Records,
855 unsigned &NumRecords) const {
Eli Friedmanf05b7722008-08-20 07:44:10 +0000856 // FIXME: Implement.
857 Records = 0;
Chris Lattner17df24e2008-04-21 18:56:49 +0000858 NumRecords = 0;
859 }
860 virtual const char *getVAListDeclaration() const {
Eli Friedmanf05b7722008-08-20 07:44:10 +0000861 return "typedef char* __builtin_va_list;";
Chris Lattner17df24e2008-04-21 18:56:49 +0000862 }
863 virtual const char *getTargetPrefix() const {
Eli Friedmanf05b7722008-08-20 07:44:10 +0000864 return "arm";
Chris Lattner17df24e2008-04-21 18:56:49 +0000865 }
Chris Lattner17df24e2008-04-21 18:56:49 +0000866 virtual void getGCCRegNames(const char * const *&Names,
867 unsigned &NumNames) const {
Eli Friedmanf05b7722008-08-20 07:44:10 +0000868 // FIXME: Implement.
869 Names = 0;
Chris Lattner17df24e2008-04-21 18:56:49 +0000870 NumNames = 0;
871 }
872 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
873 unsigned &NumAliases) const {
Eli Friedmanf05b7722008-08-20 07:44:10 +0000874 // FIXME: Implement.
875 Aliases = 0;
Chris Lattner17df24e2008-04-21 18:56:49 +0000876 NumAliases = 0;
877 }
Anders Carlsson58436352009-02-28 17:11:49 +0000878 virtual bool validateAsmConstraint(const char *&Name,
Nate Begeman2908fa02008-04-22 05:03:19 +0000879 TargetInfo::ConstraintInfo &info) const {
Eli Friedmanf05b7722008-08-20 07:44:10 +0000880 // FIXME: Check if this is complete
Anders Carlsson58436352009-02-28 17:11:49 +0000881 switch (*Name) {
Eli Friedmanf05b7722008-08-20 07:44:10 +0000882 default:
Nate Begeman2908fa02008-04-22 05:03:19 +0000883 case 'l': // r0-r7
884 case 'h': // r8-r15
885 case 'w': // VFP Floating point register single precision
886 case 'P': // VFP Floating point register double precision
887 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
888 return true;
889 }
Chris Lattner17df24e2008-04-21 18:56:49 +0000890 return false;
891 }
892 virtual const char *getClobbers() const {
Eli Friedmanf05b7722008-08-20 07:44:10 +0000893 // FIXME: Is this really right?
Chris Lattner17df24e2008-04-21 18:56:49 +0000894 return "";
895 }
896};
897} // end anonymous namespace.
898
Eli Friedmanf05b7722008-08-20 07:44:10 +0000899
900namespace {
901class DarwinARMTargetInfo : public ARMTargetInfo {
902public:
903 DarwinARMTargetInfo(const std::string& triple) : ARMTargetInfo(triple) {}
904
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000905 virtual void getTargetDefines(const LangOptions &Opts,
906 std::vector<char> &Defines) const {
907 ARMTargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerb3793bb2008-09-30 01:00:25 +0000908 getDarwinDefines(Defines, getTargetTriple());
Eli Friedmanf05b7722008-08-20 07:44:10 +0000909 }
910};
911} // end anonymous namespace.
912
Chris Lattner5ba61f02006-10-14 07:39:34 +0000913namespace {
Daniel Dunbarc53305f2009-03-23 16:09:04 +0000914// arm FreeBSD target
915class FreeBSDARMTargetInfo : public ARMTargetInfo {
916public:
917 FreeBSDARMTargetInfo(const std::string& triple) : ARMTargetInfo(triple) {}
918 virtual void getTargetDefines(const LangOptions &Opts,
919 std::vector<char> &Defines) const {
920 ARMTargetInfo::getTargetDefines(Opts, Defines);
921 getFreeBSDDefines(Opts, 0, getTargetTriple(), Defines);
922 }
923};
924} // end anonymous namespace
925
926namespace {
Eli Friedmanda8f5a92008-08-20 07:28:14 +0000927class SparcV8TargetInfo : public TargetInfo {
Chris Lattner9b415d62009-01-27 01:58:38 +0000928 static const TargetInfo::GCCRegAlias GCCRegAliases[];
929 static const char * const GCCRegNames[];
Gabor Greif49991682008-02-21 16:29:08 +0000930public:
Eli Friedmanda8f5a92008-08-20 07:28:14 +0000931 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
932 // FIXME: Support Sparc quad-precision long double?
Eli Friedman873f65a2008-08-21 00:13:15 +0000933 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
934 "i64:64:64-f32:32:32-f64:64:64-v64:64:64";
Eli Friedmanda8f5a92008-08-20 07:28:14 +0000935 }
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000936 virtual void getTargetDefines(const LangOptions &Opts,
937 std::vector<char> &Defines) const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +0000938 // FIXME: This is missing a lot of important defines; some of the
939 // missing stuff is likely to break system headers.
Gabor Greif49991682008-02-21 16:29:08 +0000940 Define(Defines, "__sparc");
Eli Friedmanb2bef7c2008-05-25 05:26:09 +0000941 Define(Defines, "__sparc__");
Gabor Greif49991682008-02-21 16:29:08 +0000942 Define(Defines, "__sparcv8");
943 }
944 virtual void getTargetBuiltins(const Builtin::Info *&Records,
945 unsigned &NumRecords) const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +0000946 // FIXME: Implement!
Gabor Greif49991682008-02-21 16:29:08 +0000947 }
948 virtual const char *getVAListDeclaration() const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +0000949 return "typedef void* __builtin_va_list;";
Gabor Greif49991682008-02-21 16:29:08 +0000950 }
951 virtual const char *getTargetPrefix() const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +0000952 return "sparc";
Gabor Greif49991682008-02-21 16:29:08 +0000953 }
954 virtual void getGCCRegNames(const char * const *&Names,
Chris Lattner9b415d62009-01-27 01:58:38 +0000955 unsigned &NumNames) const;
Gabor Greif49991682008-02-21 16:29:08 +0000956 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattner9b415d62009-01-27 01:58:38 +0000957 unsigned &NumAliases) const;
Anders Carlsson58436352009-02-28 17:11:49 +0000958 virtual bool validateAsmConstraint(const char *&Name,
Gabor Greif49991682008-02-21 16:29:08 +0000959 TargetInfo::ConstraintInfo &info) const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +0000960 // FIXME: Implement!
961 return false;
Gabor Greif49991682008-02-21 16:29:08 +0000962 }
963 virtual const char *getClobbers() const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +0000964 // FIXME: Implement!
965 return "";
Gabor Greif49991682008-02-21 16:29:08 +0000966 }
967};
968
Chris Lattner9b415d62009-01-27 01:58:38 +0000969const char * const SparcV8TargetInfo::GCCRegNames[] = {
970 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
971 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
972 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
973 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
974};
975
976void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names,
977 unsigned &NumNames) const {
978 Names = GCCRegNames;
979 NumNames = llvm::array_lengthof(GCCRegNames);
980}
981
982const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = {
983 { { "g0" }, "r0" },
984 { { "g1" }, "r1" },
985 { { "g2" }, "r2" },
986 { { "g3" }, "r3" },
987 { { "g4" }, "r4" },
988 { { "g5" }, "r5" },
989 { { "g6" }, "r6" },
990 { { "g7" }, "r7" },
991 { { "o0" }, "r8" },
992 { { "o1" }, "r9" },
993 { { "o2" }, "r10" },
994 { { "o3" }, "r11" },
995 { { "o4" }, "r12" },
996 { { "o5" }, "r13" },
997 { { "o6", "sp" }, "r14" },
998 { { "o7" }, "r15" },
999 { { "l0" }, "r16" },
1000 { { "l1" }, "r17" },
1001 { { "l2" }, "r18" },
1002 { { "l3" }, "r19" },
1003 { { "l4" }, "r20" },
1004 { { "l5" }, "r21" },
1005 { { "l6" }, "r22" },
1006 { { "l7" }, "r23" },
1007 { { "i0" }, "r24" },
1008 { { "i1" }, "r25" },
1009 { { "i2" }, "r26" },
1010 { { "i3" }, "r27" },
1011 { { "i4" }, "r28" },
1012 { { "i5" }, "r29" },
1013 { { "i6", "fp" }, "r30" },
1014 { { "i7" }, "r31" },
1015};
1016
1017void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
1018 unsigned &NumAliases) const {
1019 Aliases = GCCRegAliases;
1020 NumAliases = llvm::array_lengthof(GCCRegAliases);
1021}
Gabor Greif49991682008-02-21 16:29:08 +00001022} // end anonymous namespace.
1023
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001024namespace {
1025class SolarisSparcV8TargetInfo : public SparcV8TargetInfo {
1026public:
1027 SolarisSparcV8TargetInfo(const std::string& triple) :
Eli Friedmand50881c2008-11-02 02:43:55 +00001028 SparcV8TargetInfo(triple) {
1029 SizeType = UnsignedInt;
1030 PtrDiffType = SignedInt;
1031 }
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001032
Chris Lattner4ba73aa02009-03-20 15:52:06 +00001033 virtual void getTargetDefines(const LangOptions &Opts,
1034 std::vector<char> &Defines) const {
1035 SparcV8TargetInfo::getTargetDefines(Opts, Defines);
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001036 getSolarisDefines(Defines);
1037 }
1038};
1039} // end anonymous namespace.
Chris Lattner5ba61f02006-10-14 07:39:34 +00001040
Chris Lattnerb781dc792008-05-08 05:58:21 +00001041namespace {
1042 class PIC16TargetInfo : public TargetInfo{
1043 public:
1044 PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) {
Sanjiv Guptad7959242008-10-31 09:52:39 +00001045 IntWidth = 16;
1046 LongWidth = LongLongWidth = 32;
1047 PointerWidth = 16;
1048 IntAlign = 8;
1049 LongAlign = LongLongAlign = 8;
Eli Friedmanb5366062008-05-20 14:21:01 +00001050 PointerAlign = 8;
Sanjiv Guptad7959242008-10-31 09:52:39 +00001051 SizeType = UnsignedInt;
1052 IntMaxType = SignedLong;
1053 UIntMaxType = UnsignedLong;
Chris Lattner7e4c81c2009-02-13 22:28:55 +00001054 IntPtrType = SignedShort;
Eli Friedmand50881c2008-11-02 02:43:55 +00001055 PtrDiffType = SignedInt;
Sanjiv Gupta14f18f32008-08-18 10:05:22 +00001056 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8";
Chris Lattnerb781dc792008-05-08 05:58:21 +00001057 }
Chris Lattner5e2ef0c2008-05-09 06:08:39 +00001058 virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; }
1059 virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; }
Chris Lattner4ba73aa02009-03-20 15:52:06 +00001060 virtual void getTargetDefines(const LangOptions &Opts,
1061 std::vector<char> &Defines) const {
Chris Lattnerb781dc792008-05-08 05:58:21 +00001062 Define(Defines, "__pic16");
1063 }
1064 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1065 unsigned &NumRecords) const {}
1066 virtual const char *getVAListDeclaration() const { return "";}
1067 virtual const char *getClobbers() const {return "";}
1068 virtual const char *getTargetPrefix() const {return "";}
1069 virtual void getGCCRegNames(const char * const *&Names,
1070 unsigned &NumNames) const {}
Anders Carlsson58436352009-02-28 17:11:49 +00001071 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattnerb781dc792008-05-08 05:58:21 +00001072 TargetInfo::ConstraintInfo &info) const {
1073 return true;
1074 }
1075 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1076 unsigned &NumAliases) const {}
1077 virtual bool useGlobalsForAutomaticVariables() const {return true;}
1078 };
1079}
1080
Chris Lattner5ba61f02006-10-14 07:39:34 +00001081//===----------------------------------------------------------------------===//
1082// Driver code
1083//===----------------------------------------------------------------------===//
1084
Ted Kremenek0c2bea22007-12-04 17:07:35 +00001085static inline bool IsX86(const std::string& TT) {
Ted Kremenekb0615542007-12-03 22:06:55 +00001086 return (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' &&
1087 TT[4] == '-' && TT[1] - '3' < 6);
1088}
1089
Chris Lattner855d0242008-03-05 01:18:20 +00001090/// CreateTargetInfo - Return the target info object for the specified target
1091/// triple.
1092TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
Eli Friedman873f65a2008-08-21 00:13:15 +00001093 // OS detection; this isn't really anywhere near complete.
1094 // Additions and corrections are welcome.
1095 bool isDarwin = T.find("-darwin") != std::string::npos;
Chris Lattner5637ef52008-08-23 18:23:14 +00001096 bool isDragonFly = T.find("-dragonfly") != std::string::npos;
Chris Lattner3c3e2cc2008-10-16 17:04:31 +00001097 bool isFreeBSD = T.find("-freebsd") != std::string::npos;
Eli Friedman873f65a2008-08-21 00:13:15 +00001098 bool isSolaris = T.find("-solaris") != std::string::npos;
1099 bool isLinux = T.find("-linux") != std::string::npos;
1100 bool isWindows = T.find("-windows") != std::string::npos ||
1101 T.find("-win32") != std::string::npos ||
1102 T.find("-mingw") != std::string::npos;
Eli Friedmanb5366062008-05-20 14:21:01 +00001103
Eli Friedman873f65a2008-08-21 00:13:15 +00001104 if (T.find("ppc-") == 0 || T.find("powerpc-") == 0) {
1105 if (isDarwin)
1106 return new DarwinPPCTargetInfo(T);
1107 return new PPC32TargetInfo(T);
1108 }
Eli Friedmanb5366062008-05-20 14:21:01 +00001109
Eli Friedman873f65a2008-08-21 00:13:15 +00001110 if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0) {
1111 if (isDarwin)
1112 return new DarwinPPC64TargetInfo(T);
1113 return new PPC64TargetInfo(T);
1114 }
Chris Lattner17df24e2008-04-21 18:56:49 +00001115
Eli Friedman873f65a2008-08-21 00:13:15 +00001116 if (T.find("armv6-") == 0 || T.find("arm-") == 0) {
1117 if (isDarwin)
1118 return new DarwinARMTargetInfo(T);
Daniel Dunbarc53305f2009-03-23 16:09:04 +00001119 if (isFreeBSD)
1120 return new FreeBSDARMTargetInfo(T);
Eli Friedman873f65a2008-08-21 00:13:15 +00001121 return new ARMTargetInfo(T);
1122 }
Eli Friedmanb5366062008-05-20 14:21:01 +00001123
Eli Friedman873f65a2008-08-21 00:13:15 +00001124 if (T.find("sparc-") == 0) {
1125 if (isSolaris)
1126 return new SolarisSparcV8TargetInfo(T);
1127 return new SparcV8TargetInfo(T);
1128 }
1129
Chris Lattnerd0b80c82009-02-20 17:04:14 +00001130 if (T.find("x86_64-") == 0 || T.find("amd64-") == 0) {
Eli Friedman873f65a2008-08-21 00:13:15 +00001131 if (isDarwin)
1132 return new DarwinX86_64TargetInfo(T);
Daniel Dunbard0921de2008-09-23 17:37:57 +00001133 if (isLinux)
1134 return new LinuxX86_64TargetInfo(T);
Chris Lattner3c3e2cc2008-10-16 17:04:31 +00001135 if (isFreeBSD)
1136 return new FreeBSDX86_64TargetInfo(T);
Eli Friedman873f65a2008-08-21 00:13:15 +00001137 return new X86_64TargetInfo(T);
1138 }
Eli Friedmanb5366062008-05-20 14:21:01 +00001139
Chris Lattnerb781dc792008-05-08 05:58:21 +00001140 if (T.find("pic16-") == 0)
1141 return new PIC16TargetInfo(T);
1142
Eli Friedman873f65a2008-08-21 00:13:15 +00001143 if (IsX86(T)) {
1144 if (isDarwin)
1145 return new DarwinI386TargetInfo(T);
Eli Friedmanff594f22008-08-21 00:24:02 +00001146 if (isLinux)
1147 return new LinuxX86_32TargetInfo(T);
Chris Lattner5637ef52008-08-23 18:23:14 +00001148 if (isDragonFly)
1149 return new DragonFlyX86_32TargetInfo(T);
Chris Lattner3c3e2cc2008-10-16 17:04:31 +00001150 if (isFreeBSD)
1151 return new FreeBSDX86_32TargetInfo(T);
Eli Friedmanc968a6a2008-08-21 01:40:19 +00001152 if (isWindows)
1153 return new WindowsX86_32TargetInfo(T);
Eli Friedman873f65a2008-08-21 00:13:15 +00001154 return new X86_32TargetInfo(T);
1155 }
Eli Friedmanb5366062008-05-20 14:21:01 +00001156
Chris Lattner855d0242008-03-05 01:18:20 +00001157 return NULL;
Chris Lattner5ba61f02006-10-14 07:39:34 +00001158}
Ted Kremenekc490bdb2008-03-04 17:47:18 +00001159