blob: 40bc31381d1e186c9010d94bf5e4bf128b342689 [file] [log] [blame]
Reid Spencer5f016e22007-07-11 17:01:13 +00001//===--- Targets.cpp - Implement -arch option and targets -----------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner0bc735f2007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Reid Spencer5f016e22007-07-11 17:01:13 +00007//
8//===----------------------------------------------------------------------===//
9//
Ted Kremenekbbced582007-12-12 18:05:32 +000010// This file implements construction of a TargetInfo object from a
11// target triple.
Reid Spencer5f016e22007-07-11 17:01:13 +000012//
13//===----------------------------------------------------------------------===//
14
Douglas Gregorb1152d82009-02-16 21:58:21 +000015// FIXME: Layering violation
Reid Spencer5f016e22007-07-11 17:01:13 +000016#include "clang/AST/Builtins.h"
Anders Carlsson564f1de2007-12-09 23:17:02 +000017#include "clang/AST/TargetBuiltins.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000018#include "clang/Basic/TargetInfo.h"
Chris Lattner8fc4dfb2008-12-04 22:54:33 +000019#include "clang/Basic/LangOptions.h"
Anders Carlsson3346ae62007-11-24 23:38:12 +000020#include "llvm/ADT/STLExtras.h"
Eli Friedman25531262008-05-20 14:27:34 +000021#include "llvm/ADT/APFloat.h"
Chris Lattnerca45cff2009-03-20 16:06:38 +000022#include "llvm/ADT/SmallString.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000023using namespace clang;
24
Reid Spencer5f016e22007-07-11 17:01:13 +000025//===----------------------------------------------------------------------===//
26// Common code shared among targets.
27//===----------------------------------------------------------------------===//
28
Chris Lattnerd15fa822007-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 Lattnerca45cff2009-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 Lattnerd29b6302008-10-05 21:50:58 +000062//===----------------------------------------------------------------------===//
63// Defines specific to certain operating systems.
64//===----------------------------------------------------------------------===//
65
Eli Friedman01b86682008-08-20 07:28:14 +000066static void getSolarisDefines(std::vector<char> &Defs) {
67 Define(Defs, "__SUN__");
68 Define(Defs, "__SOLARIS__");
69}
Reid Spencer5f016e22007-07-11 17:01:13 +000070
Chris Lattner318ca712009-03-20 15:55:34 +000071static void getFreeBSDDefines(const LangOptions &Opts, bool is64Bit,
72 const char *Triple, std::vector<char> &Defs) {
Chris Lattnerfd0269d2008-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 Lattnerca45cff2009-03-20 16:06:38 +000085 DefineStd(Defs, "unix", Opts);
Anton Korobeynikov2793bda2009-02-14 16:42:50 +000086 Define(Defs, "__ELF__", "1");
Chris Lattnerfd0269d2008-10-16 17:04:31 +000087 if (is64Bit) {
88 Define(Defs, "__LP64__");
89 }
90}
91
Chris Lattner318ca712009-03-20 15:55:34 +000092static void getDragonFlyDefines(const LangOptions &Opts,
93 std::vector<char> &Defs) {
Chris Lattnerd29b6302008-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 Lattnerca45cff2009-03-20 16:06:38 +0000100 DefineStd(Defs, "unix", Opts);
Chris Lattnerd29b6302008-10-05 21:50:58 +0000101}
102
Chris Lattner318ca712009-03-20 15:55:34 +0000103static void getLinuxDefines(const LangOptions &Opts, std::vector<char> &Defs) {
Chris Lattnerd29b6302008-10-05 21:50:58 +0000104 // Linux defines; list based off of gcc output
Chris Lattnerca45cff2009-03-20 16:06:38 +0000105 DefineStd(Defs, "unix", Opts);
106 DefineStd(Defs, "linux", Opts);
Chris Lattnerd29b6302008-10-05 21:50:58 +0000107 Define(Defs, "__gnu_linux__");
Argyrios Kyrtzidis487cdee2009-02-14 15:02:45 +0000108 Define(Defs, "__ELF__", "1");
Chris Lattnerd29b6302008-10-05 21:50:58 +0000109}
110
Chris Lattnerae0ee032008-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 Lattner8b30c412008-09-30 01:00:25 +0000141static void getDarwinDefines(std::vector<char> &Defs, const char *Triple) {
Eli Friedman618234a2008-08-20 02:34:37 +0000142 Define(Defs, "__APPLE__");
143 Define(Defs, "__MACH__");
Chris Lattnerd427ad42009-02-05 07:19:24 +0000144 Define(Defs, "OBJC_NEW_PROPERTIES");
145
146 // FIXME: OBJC_ZEROCOST_EXCEPTIONS when using zero cost eh.
Chris Lattner8b30c412008-09-30 01:00:25 +0000147
148 // Figure out which "darwin number" the target triple is. "darwin9" -> 10.5.
Chris Lattnerae0ee032008-12-04 23:20:07 +0000149 unsigned Maj, Min;
150 if (getDarwinNumber(Triple, Maj, Min)) {
Chris Lattner079f2c462008-09-30 20:30:12 +0000151 char DarwinStr[] = "1000";
Chris Lattnerae0ee032008-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 Lattner8b30c412008-09-30 01:00:25 +0000155 }
Chris Lattnerae0ee032008-12-04 23:20:07 +0000156
157 // Handle minor version: 10.4.9 -> darwin8.9 -> "1049"
158 DarwinStr[3] = Min+'0';
Chris Lattner079f2c462008-09-30 20:30:12 +0000159 Define(Defs, "__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", DarwinStr);
Chris Lattner8b30c412008-09-30 01:00:25 +0000160 }
Eli Friedman618234a2008-08-20 02:34:37 +0000161}
Reid Spencer5f016e22007-07-11 17:01:13 +0000162
Chris Lattnerae0ee032008-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 Jahaniana30b17b2009-02-12 17:54:33 +0000173 // As does nonfragile-abi for 64bit mode
Fariborz Jahanian66a5c2c2009-02-24 23:34:44 +0000174 if (Maj > 9)
Chris Lattnerae0ee032008-12-04 23:20:07 +0000175 Opts.Blocks = 1;
Fariborz Jahanian66a5c2c2009-02-24 23:34:44 +0000176
Fariborz Jahanian84d01332009-02-24 23:38:42 +0000177 if (Maj >= 9 && Opts.ObjC1 && !strncmp(Triple, "x86_64", 6))
178 Opts.ObjCNonFragileABI = 1;
Chris Lattnerae0ee032008-12-04 23:20:07 +0000179}
180
181
Chris Lattnerd29b6302008-10-05 21:50:58 +0000182//===----------------------------------------------------------------------===//
Eli Friedmane4277982008-08-20 23:11:40 +0000183// Specific target implementations.
184//===----------------------------------------------------------------------===//
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000185
Eli Friedmane4277982008-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 {
Reid Spencer5f016e22007-07-11 17:01:13 +0000199 Records = BuiltinInfo;
Eli Friedmane4277982008-08-20 23:11:40 +0000200 NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
Reid Spencer5f016e22007-07-11 17:01:13 +0000201 }
Chris Lattnerc0f59212009-03-02 22:27:17 +0000202
Chris Lattner33328642009-03-20 15:52:06 +0000203 virtual void getTargetDefines(const LangOptions &Opts,
204 std::vector<char> &Defines) const;
Chris Lattnerc0f59212009-03-02 22:27:17 +0000205
Eli Friedmane4277982008-08-20 23:11:40 +0000206 virtual const char *getVAListDeclaration() const {
Chris Lattnerd5998502008-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 Friedmane4277982008-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 Lattnerd5998502008-10-27 01:11:29 +0000215 "} __builtin_va_list[1];";*/
Anders Carlsson3346ae62007-11-24 23:38:12 +0000216 }
Eli Friedmane4277982008-08-20 23:11:40 +0000217 virtual const char *getTargetPrefix() const {
218 return "ppc";
Anders Carlssond04c6e22007-11-27 04:11:28 +0000219 }
Eli Friedmane4277982008-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 Carlsson066d2ea2009-02-28 17:11:49 +0000224 virtual bool validateAsmConstraint(const char *&Name,
Eli Friedmane4277982008-08-20 23:11:40 +0000225 TargetInfo::ConstraintInfo &info) const {
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000226 switch (*Name) {
Anders Carlssond04c6e22007-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 Friedmane4277982008-08-20 23:11:40 +0000236 virtual const char *getClobbers() const {
237 return "";
Anders Carlssond04c6e22007-11-27 04:11:28 +0000238 }
Eli Friedmane4277982008-08-20 23:11:40 +0000239};
Anders Carlssond04c6e22007-11-27 04:11:28 +0000240
Eli Friedmane4277982008-08-20 23:11:40 +0000241const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
Douglas Gregorb1152d82009-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 Friedmane4277982008-08-20 23:11:40 +0000244#include "clang/AST/PPCBuiltins.def"
245};
Chris Lattnerc0f59212009-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 Lattner33328642009-03-20 15:52:06 +0000250void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
251 std::vector<char> &Defs) const {
Chris Lattnerc0f59212009-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 Lattner393ff042008-04-21 18:56:49 +0000277
Eli Friedmane4277982008-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};
Reid Spencer5f016e22007-07-11 17:01:13 +0000298
Eli Friedmane4277982008-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}
Reid Spencer5f016e22007-07-11 17:01:13 +0000304
Eli Friedmane4277982008-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.
Reid Spencer5f016e22007-07-11 17:01:13 +0000348
349namespace {
Eli Friedmane4277982008-08-20 23:11:40 +0000350class PPC32TargetInfo : public PPCTargetInfo {
Reid Spencer5f016e22007-07-11 17:01:13 +0000351public:
Eli Friedmaned855cb2008-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 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000356};
357} // end anonymous namespace.
358
359namespace {
Eli Friedmane4277982008-08-20 23:11:40 +0000360class PPC64TargetInfo : public PPCTargetInfo {
Reid Spencer5f016e22007-07-11 17:01:13 +0000361public:
Eli Friedmane4277982008-08-20 23:11:40 +0000362 PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
Chris Lattnerf291b102008-05-09 06:17:04 +0000363 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedmaned855cb2008-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 Lattnerf291b102008-05-09 06:17:04 +0000366 }
Eli Friedmane4277982008-08-20 23:11:40 +0000367};
368} // end anonymous namespace.
369
Chris Lattnerae0ee032008-12-04 23:20:07 +0000370
Eli Friedmane4277982008-08-20 23:11:40 +0000371namespace {
372class DarwinPPCTargetInfo : public PPC32TargetInfo {
373public:
374 DarwinPPCTargetInfo(const std::string& triple) : PPC32TargetInfo(triple) {}
Chris Lattner33328642009-03-20 15:52:06 +0000375 virtual void getTargetDefines(const LangOptions &Opts,
376 std::vector<char> &Defines) const {
377 PPC32TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattner8b30c412008-09-30 01:00:25 +0000378 getDarwinDefines(Defines, getTargetTriple());
Reid Spencer5f016e22007-07-11 17:01:13 +0000379 }
Daniel Dunbardcb4a1a2008-08-23 08:43:39 +0000380
Chris Lattner8fc4dfb2008-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 Lattnerae0ee032008-12-04 23:20:07 +0000385 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000386 }
Eli Friedmane4277982008-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 Lattner33328642009-03-20 15:52:06 +0000394 virtual void getTargetDefines(const LangOptions &Opts,
395 std::vector<char> &Defines) const {
396 PPC64TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattner8b30c412008-09-30 01:00:25 +0000397 getDarwinDefines(Defines, getTargetTriple());
Anders Carlsson3346ae62007-11-24 23:38:12 +0000398 }
Daniel Dunbardcb4a1a2008-08-23 08:43:39 +0000399
Chris Lattner8fc4dfb2008-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 Lattnerae0ee032008-12-04 23:20:07 +0000404 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000405 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000406};
407} // end anonymous namespace.
408
409namespace {
Eli Friedman618234a2008-08-20 02:34:37 +0000410// Namespace for x86 abstract base class
411const Builtin::Info BuiltinInfo[] = {
Douglas Gregorb1152d82009-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 Friedman618234a2008-08-20 02:34:37 +0000414#include "clang/AST/X86Builtins.def"
415};
Eli Friedman61538a72008-05-20 14:21:01 +0000416
Eli Friedman618234a2008-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 Lattner84f0ea82009-03-02 22:40:39 +0000441 enum X86SSEEnum {
442 NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42
443 } SSELevel;
Eli Friedman618234a2008-08-20 02:34:37 +0000444public:
Chris Lattner84f0ea82009-03-02 22:40:39 +0000445 X86TargetInfo(const std::string& triple)
Chris Lattner6328cc32009-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 Friedman618234a2008-08-20 02:34:37 +0000450 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
Reid Spencer5f016e22007-07-11 17:01:13 +0000451 }
452 virtual void getTargetBuiltins(const Builtin::Info *&Records,
453 unsigned &NumRecords) const {
Eli Friedman618234a2008-08-20 02:34:37 +0000454 Records = BuiltinInfo;
455 NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
Reid Spencer5f016e22007-07-11 17:01:13 +0000456 }
Anders Carlsson44fe49c2007-12-08 19:32:57 +0000457 virtual const char *getTargetPrefix() const {
Eli Friedman618234a2008-08-20 02:34:37 +0000458 return "x86";
Anders Carlsson44fe49c2007-12-08 19:32:57 +0000459 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000460 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedman618234a2008-08-20 02:34:37 +0000461 unsigned &NumNames) const {
462 Names = GCCRegNames;
463 NumNames = llvm::array_lengthof(GCCRegNames);
Anders Carlsson3346ae62007-11-24 23:38:12 +0000464 }
465 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
466 unsigned &NumAliases) const {
Eli Friedman618234a2008-08-20 02:34:37 +0000467 Aliases = GCCRegAliases;
468 NumAliases = llvm::array_lengthof(GCCRegAliases);
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000469 }
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000470 virtual bool validateAsmConstraint(const char *&Name,
Eli Friedman618234a2008-08-20 02:34:37 +0000471 TargetInfo::ConstraintInfo &info) const;
472 virtual std::string convertConstraint(const char Constraint) const;
Anders Carlssond04c6e22007-11-27 04:11:28 +0000473 virtual const char *getClobbers() const {
Eli Friedman618234a2008-08-20 02:34:37 +0000474 return "~{dirflag},~{fpsr},~{flags}";
475 }
Chris Lattner33328642009-03-20 15:52:06 +0000476 virtual void getTargetDefines(const LangOptions &Opts,
477 std::vector<char> &Defines) const;
Chris Lattner3daed522009-03-02 22:20:04 +0000478
Chris Lattner6328cc32009-03-03 19:56:18 +0000479 virtual int HandleTargetFeatures(std::string *StrArray, unsigned NumStrs,
480 std::string &ErrorReason);
Reid Spencer5f016e22007-07-11 17:01:13 +0000481};
Chris Lattner3daed522009-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 Lattner6328cc32009-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 Lattner3daed522009-03-02 22:20:04 +0000522}
Chris Lattnerc0f59212009-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 Lattner33328642009-03-20 15:52:06 +0000526void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
527 std::vector<char> &Defs) const {
Chris Lattnerc0f59212009-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 Lattnerca45cff2009-03-20 16:06:38 +0000538 DefineStd(Defs, "i386", Opts);
Chris Lattnerc0f59212009-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 Lattnerc0f59212009-03-02 22:27:17 +0000548 Define(Defs, "__REGISTER_PREFIX__", "");
Chris Lattner84f0ea82009-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 Lattnerc0f59212009-03-02 22:27:17 +0000571}
572
Eli Friedman618234a2008-08-20 02:34:37 +0000573
574bool
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000575X86TargetInfo::validateAsmConstraint(const char *&Name,
Eli Friedman618234a2008-08-20 02:34:37 +0000576 TargetInfo::ConstraintInfo &info) const {
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000577 switch (*Name) {
Eli Friedman618234a2008-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 Carlssonfce09342008-10-06 00:41:45 +0000589 case 'y': // Any MMX register.
Anders Carlssona7406d42008-10-06 19:17:39 +0000590 case 'x': // Any SSE register.
Eli Friedman618234a2008-08-20 02:34:37 +0000591 case 'Q': // Any register accessible as [r]h: a, b, c, and d.
Anders Carlsson79bc64c2009-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 Friedman618234a2008-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 Friedman618234a2008-08-20 02:34:37 +0000620} // end anonymous namespace
Reid Spencer5f016e22007-07-11 17:01:13 +0000621
622namespace {
Eli Friedman618234a2008-08-20 02:34:37 +0000623// X86-32 generic target
624class X86_32TargetInfo : public X86TargetInfo {
Reid Spencer5f016e22007-07-11 17:01:13 +0000625public:
Eli Friedman618234a2008-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 Friedmaned855cb2008-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 Friedman1afabd92009-03-29 20:31:09 +0000633 SizeType = UnsignedInt;
634 PtrDiffType = SignedInt;
635 IntPtrType = SignedInt;
Anton Korobeynikov264a76c2009-04-03 23:38:25 +0000636 RegParmMax = 3;
Eli Friedman618234a2008-08-20 02:34:37 +0000637 }
638 virtual const char *getVAListDeclaration() const {
Eli Friedman01b86682008-08-20 07:28:14 +0000639 return "typedef char* __builtin_va_list;";
Eli Friedman618234a2008-08-20 02:34:37 +0000640 }
Eli Friedman618234a2008-08-20 02:34:37 +0000641};
642} // end anonymous namespace
643
644namespace {
645// x86-32 Darwin (OS X) target
646class DarwinI386TargetInfo : public X86_32TargetInfo {
647public:
648 DarwinI386TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
649 LongDoubleWidth = 128;
650 LongDoubleAlign = 128;
Eli Friedman1afabd92009-03-29 20:31:09 +0000651 SizeType = UnsignedLong;
652 IntPtrType = SignedLong;
Eli Friedmaned855cb2008-08-21 00:13:15 +0000653 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
654 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
655 "a0:0:64-f80:128:128";
Eli Friedman618234a2008-08-20 02:34:37 +0000656 }
Daniel Dunbar8e5c2b82009-03-31 23:42:16 +0000657
658 virtual const char *getStringSymbolPrefix(bool IsConstant) const {
659 return IsConstant ? "\01LC" : "\01lC";
660 }
661
Daniel Dunbara9668e02009-04-03 00:57:44 +0000662 virtual const char *getUnicodeStringSymbolPrefix() const {
663 return "__utf16_string_";
664 }
665
666 virtual const char *getUnicodeStringSection() const {
667 return "__TEXT,__ustring";
668 }
669
Daniel Dunbar8e5c2b82009-03-31 23:42:16 +0000670 virtual const char *getCFStringSymbolPrefix() const {
671 return "\01LC";
672 }
673
Chris Lattner33328642009-03-20 15:52:06 +0000674 virtual void getTargetDefines(const LangOptions &Opts,
675 std::vector<char> &Defines) const {
676 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattner8b30c412008-09-30 01:00:25 +0000677 getDarwinDefines(Defines, getTargetTriple());
Eli Friedman618234a2008-08-20 02:34:37 +0000678 }
Daniel Dunbar8e5c2b82009-03-31 23:42:16 +0000679
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000680 /// getDefaultLangOptions - Allow the target to specify default settings for
681 /// various language options. These may be overridden by command line
682 /// options.
683 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattnerae0ee032008-12-04 23:20:07 +0000684 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000685 }
Eli Friedman618234a2008-08-20 02:34:37 +0000686};
687} // end anonymous namespace
688
689namespace {
Chris Lattnerfd0269d2008-10-16 17:04:31 +0000690// x86-32 FreeBSD target
691class FreeBSDX86_32TargetInfo : public X86_32TargetInfo {
692public:
Eli Friedmanf509d732008-11-02 02:43:55 +0000693 FreeBSDX86_32TargetInfo(const std::string& triple) :
Eli Friedman1afabd92009-03-29 20:31:09 +0000694 X86_32TargetInfo(triple) { }
Chris Lattner33328642009-03-20 15:52:06 +0000695 virtual void getTargetDefines(const LangOptions &Opts,
696 std::vector<char> &Defines) const {
697 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattner318ca712009-03-20 15:55:34 +0000698 getFreeBSDDefines(Opts, 0, getTargetTriple(), Defines);
Chris Lattnerfd0269d2008-10-16 17:04:31 +0000699 }
700};
701} // end anonymous namespace
702
703namespace {
Chris Lattnereac7aee2008-08-23 18:23:14 +0000704// x86-32 DragonFly target
705class DragonFlyX86_32TargetInfo : public X86_32TargetInfo {
706public:
Eli Friedmanf509d732008-11-02 02:43:55 +0000707 DragonFlyX86_32TargetInfo(const std::string& triple) :
Eli Friedman1afabd92009-03-29 20:31:09 +0000708 X86_32TargetInfo(triple) { }
Chris Lattner33328642009-03-20 15:52:06 +0000709 virtual void getTargetDefines(const LangOptions &Opts,
710 std::vector<char> &Defines) const {
711 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattner318ca712009-03-20 15:55:34 +0000712 getDragonFlyDefines(Opts, Defines);
Chris Lattnereac7aee2008-08-23 18:23:14 +0000713 }
714};
715} // end anonymous namespace
716
717namespace {
Eli Friedman0d4047b2008-08-21 00:24:02 +0000718// x86-32 Linux target
719class LinuxX86_32TargetInfo : public X86_32TargetInfo {
720public:
721 LinuxX86_32TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
Chris Lattner9b533162008-10-05 19:44:25 +0000722 UserLabelPrefix = "";
Eli Friedman0d4047b2008-08-21 00:24:02 +0000723 }
Chris Lattner33328642009-03-20 15:52:06 +0000724 virtual void getTargetDefines(const LangOptions &Opts,
725 std::vector<char> &Defines) const {
726 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattner318ca712009-03-20 15:55:34 +0000727 getLinuxDefines(Opts, Defines);
Eli Friedman0d4047b2008-08-21 00:24:02 +0000728 }
729};
730} // end anonymous namespace
731
732namespace {
Eli Friedman29a30502008-08-21 01:40:19 +0000733// x86-32 Windows target
734class WindowsX86_32TargetInfo : public X86_32TargetInfo {
735public:
736 WindowsX86_32TargetInfo(const std::string& triple)
737 : X86_32TargetInfo(triple) {
738 // FIXME: Fix wchar_t.
739 // FIXME: We should probably enable -fms-extensions by default for
740 // this target.
741 }
Chris Lattner33328642009-03-20 15:52:06 +0000742 virtual void getTargetDefines(const LangOptions &Opts,
743 std::vector<char> &Defines) const {
744 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Eli Friedman29a30502008-08-21 01:40:19 +0000745 // This list is based off of the the list of things MingW defines
Eli Friedman29a30502008-08-21 01:40:19 +0000746 Define(Defines, "_WIN32");
Chris Lattnerca45cff2009-03-20 16:06:38 +0000747 DefineStd(Defines, "WIN32", Opts);
748 DefineStd(Defines, "WINNT", Opts);
Eli Friedman29a30502008-08-21 01:40:19 +0000749 Define(Defines, "_X86_");
750 Define(Defines, "__MSVCRT__");
751 }
752};
753} // end anonymous namespace
754
755namespace {
Eli Friedman618234a2008-08-20 02:34:37 +0000756// x86-64 generic target
757class X86_64TargetInfo : public X86TargetInfo {
758public:
Chris Lattner33328642009-03-20 15:52:06 +0000759 X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) {
Chris Lattnerf291b102008-05-09 06:17:04 +0000760 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Chris Lattner778601f2009-01-28 06:58:19 +0000761 DoubleAlign = LongLongAlign = 64;
Eli Friedman61538a72008-05-20 14:21:01 +0000762 LongDoubleWidth = 128;
763 LongDoubleAlign = 128;
Chris Lattner06ebe862009-02-05 07:32:46 +0000764 IntMaxType = SignedLong;
765 UIntMaxType = UnsignedLong;
Anton Korobeynikov264a76c2009-04-03 23:38:25 +0000766 RegParmMax = 6;
Chris Lattner06ebe862009-02-05 07:32:46 +0000767
Eli Friedmaned855cb2008-08-21 00:13:15 +0000768 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
769 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
770 "a0:0:64-f80:128:128";
Reid Spencer5f016e22007-07-11 17:01:13 +0000771 }
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000772 virtual const char *getVAListDeclaration() const {
Eli Friedman01b86682008-08-20 07:28:14 +0000773 return "typedef struct __va_list_tag {"
774 " unsigned gp_offset;"
775 " unsigned fp_offset;"
776 " void* overflow_arg_area;"
777 " void* reg_save_area;"
778 "} __builtin_va_list[1];";
Anders Carlsson3346ae62007-11-24 23:38:12 +0000779 }
Eli Friedman618234a2008-08-20 02:34:37 +0000780};
781} // end anonymous namespace
782
783namespace {
Chris Lattnerfd0269d2008-10-16 17:04:31 +0000784// x86-64 FreeBSD target
785class FreeBSDX86_64TargetInfo : public X86_64TargetInfo {
786public:
Chris Lattner33328642009-03-20 15:52:06 +0000787 FreeBSDX86_64TargetInfo(const std::string &triple)
788 : X86_64TargetInfo(triple) {}
789 virtual void getTargetDefines(const LangOptions &Opts,
790 std::vector<char> &Defines) const {
791 X86_64TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattner318ca712009-03-20 15:55:34 +0000792 getFreeBSDDefines(Opts, 1, getTargetTriple(), Defines);
Chris Lattnerfd0269d2008-10-16 17:04:31 +0000793 }
794};
795} // end anonymous namespace
796
797namespace {
Daniel Dunbarb55a42b2008-09-23 17:37:57 +0000798// x86-64 Linux target
799class LinuxX86_64TargetInfo : public X86_64TargetInfo {
800public:
801 LinuxX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) {
Chris Lattner9b533162008-10-05 19:44:25 +0000802 UserLabelPrefix = "";
Daniel Dunbarb55a42b2008-09-23 17:37:57 +0000803 }
Chris Lattner33328642009-03-20 15:52:06 +0000804 virtual void getTargetDefines(const LangOptions &Opts,
805 std::vector<char> &Defines) const {
806 X86_64TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattner318ca712009-03-20 15:55:34 +0000807 getLinuxDefines(Opts, Defines);
Daniel Dunbarb55a42b2008-09-23 17:37:57 +0000808 }
809};
810} // end anonymous namespace
811
812namespace {
Eli Friedman618234a2008-08-20 02:34:37 +0000813// x86-64 Darwin (OS X) target
814class DarwinX86_64TargetInfo : public X86_64TargetInfo {
815public:
816 DarwinX86_64TargetInfo(const std::string& triple) :
817 X86_64TargetInfo(triple) {}
818
Daniel Dunbar8e5c2b82009-03-31 23:42:16 +0000819 virtual const char *getStringSymbolPrefix(bool IsConstant) const {
820 return IsConstant ? "\01LC" : "\01lC";
821 }
822
Daniel Dunbara9668e02009-04-03 00:57:44 +0000823 virtual const char *getUnicodeStringSymbolPrefix() const {
824 return "__utf16_string_";
825 }
826
827 virtual const char *getUnicodeStringSection() const {
828 return "__TEXT,__ustring";
829 }
830
Daniel Dunbar8e5c2b82009-03-31 23:42:16 +0000831 virtual const char *getCFStringSymbolPrefix() const {
832 return "\01L_unnamed_cfstring_";
833 }
834
Chris Lattner33328642009-03-20 15:52:06 +0000835 virtual void getTargetDefines(const LangOptions &Opts,
836 std::vector<char> &Defines) const {
837 X86_64TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattner8b30c412008-09-30 01:00:25 +0000838 getDarwinDefines(Defines, getTargetTriple());
Anders Carlsson3346ae62007-11-24 23:38:12 +0000839 }
Daniel Dunbardcb4a1a2008-08-23 08:43:39 +0000840
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000841 /// getDefaultLangOptions - Allow the target to specify default settings for
842 /// various language options. These may be overridden by command line
843 /// options.
844 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattnerae0ee032008-12-04 23:20:07 +0000845 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000846 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000847};
848} // end anonymous namespace.
849
Chris Lattner393ff042008-04-21 18:56:49 +0000850namespace {
Eli Friedmana9f54962008-08-20 07:44:10 +0000851class ARMTargetInfo : public TargetInfo {
Chris Lattner393ff042008-04-21 18:56:49 +0000852public:
Eli Friedmana9f54962008-08-20 07:44:10 +0000853 ARMTargetInfo(const std::string& triple) : TargetInfo(triple) {
854 // FIXME: Are the defaults correct for ARM?
Eli Friedmaned855cb2008-08-21 00:13:15 +0000855 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
856 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:64";
Eli Friedman61538a72008-05-20 14:21:01 +0000857 }
Chris Lattner33328642009-03-20 15:52:06 +0000858 virtual void getTargetDefines(const LangOptions &Opts,
859 std::vector<char> &Defs) const {
Chris Lattnerc0f59212009-03-02 22:27:17 +0000860 // Target identification.
861 Define(Defs, "__arm");
862 Define(Defs, "__arm__");
863
864 // Target properties.
865 Define(Defs, "__LITTLE_ENDIAN__");
866
867 // Subtarget options. [hard coded to v6 for now]
868 Define(Defs, "__ARM_ARCH_6K__");
869 Define(Defs, "__ARMEL__");
870 Define(Defs, "__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", "20000");
Chris Lattner393ff042008-04-21 18:56:49 +0000871 }
872 virtual void getTargetBuiltins(const Builtin::Info *&Records,
873 unsigned &NumRecords) const {
Eli Friedmana9f54962008-08-20 07:44:10 +0000874 // FIXME: Implement.
875 Records = 0;
Chris Lattner393ff042008-04-21 18:56:49 +0000876 NumRecords = 0;
877 }
878 virtual const char *getVAListDeclaration() const {
Eli Friedmana9f54962008-08-20 07:44:10 +0000879 return "typedef char* __builtin_va_list;";
Chris Lattner393ff042008-04-21 18:56:49 +0000880 }
881 virtual const char *getTargetPrefix() const {
Eli Friedmana9f54962008-08-20 07:44:10 +0000882 return "arm";
Chris Lattner393ff042008-04-21 18:56:49 +0000883 }
Chris Lattner393ff042008-04-21 18:56:49 +0000884 virtual void getGCCRegNames(const char * const *&Names,
885 unsigned &NumNames) const {
Eli Friedmana9f54962008-08-20 07:44:10 +0000886 // FIXME: Implement.
887 Names = 0;
Chris Lattner393ff042008-04-21 18:56:49 +0000888 NumNames = 0;
889 }
890 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
891 unsigned &NumAliases) const {
Eli Friedmana9f54962008-08-20 07:44:10 +0000892 // FIXME: Implement.
893 Aliases = 0;
Chris Lattner393ff042008-04-21 18:56:49 +0000894 NumAliases = 0;
895 }
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000896 virtual bool validateAsmConstraint(const char *&Name,
Nate Begemanad487f42008-04-22 05:03:19 +0000897 TargetInfo::ConstraintInfo &info) const {
Eli Friedmana9f54962008-08-20 07:44:10 +0000898 // FIXME: Check if this is complete
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000899 switch (*Name) {
Eli Friedmana9f54962008-08-20 07:44:10 +0000900 default:
Nate Begemanad487f42008-04-22 05:03:19 +0000901 case 'l': // r0-r7
902 case 'h': // r8-r15
903 case 'w': // VFP Floating point register single precision
904 case 'P': // VFP Floating point register double precision
905 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
906 return true;
907 }
Chris Lattner393ff042008-04-21 18:56:49 +0000908 return false;
909 }
910 virtual const char *getClobbers() const {
Eli Friedmana9f54962008-08-20 07:44:10 +0000911 // FIXME: Is this really right?
Chris Lattner393ff042008-04-21 18:56:49 +0000912 return "";
913 }
914};
915} // end anonymous namespace.
916
Eli Friedmana9f54962008-08-20 07:44:10 +0000917
918namespace {
919class DarwinARMTargetInfo : public ARMTargetInfo {
920public:
921 DarwinARMTargetInfo(const std::string& triple) : ARMTargetInfo(triple) {}
922
Chris Lattner33328642009-03-20 15:52:06 +0000923 virtual void getTargetDefines(const LangOptions &Opts,
924 std::vector<char> &Defines) const {
925 ARMTargetInfo::getTargetDefines(Opts, Defines);
Chris Lattner8b30c412008-09-30 01:00:25 +0000926 getDarwinDefines(Defines, getTargetTriple());
Eli Friedmana9f54962008-08-20 07:44:10 +0000927 }
928};
929} // end anonymous namespace.
930
Reid Spencer5f016e22007-07-11 17:01:13 +0000931namespace {
Daniel Dunbar1e0107a2009-03-23 16:09:04 +0000932// arm FreeBSD target
933class FreeBSDARMTargetInfo : public ARMTargetInfo {
934public:
935 FreeBSDARMTargetInfo(const std::string& triple) : ARMTargetInfo(triple) {}
936 virtual void getTargetDefines(const LangOptions &Opts,
937 std::vector<char> &Defines) const {
938 ARMTargetInfo::getTargetDefines(Opts, Defines);
939 getFreeBSDDefines(Opts, 0, getTargetTriple(), Defines);
940 }
941};
942} // end anonymous namespace
943
944namespace {
Eli Friedman01b86682008-08-20 07:28:14 +0000945class SparcV8TargetInfo : public TargetInfo {
Chris Lattnere957f532009-01-27 01:58:38 +0000946 static const TargetInfo::GCCRegAlias GCCRegAliases[];
947 static const char * const GCCRegNames[];
Gabor Greif26658672008-02-21 16:29:08 +0000948public:
Eli Friedman01b86682008-08-20 07:28:14 +0000949 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
950 // FIXME: Support Sparc quad-precision long double?
Eli Friedmaned855cb2008-08-21 00:13:15 +0000951 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
952 "i64:64:64-f32:32:32-f64:64:64-v64:64:64";
Eli Friedman01b86682008-08-20 07:28:14 +0000953 }
Chris Lattner33328642009-03-20 15:52:06 +0000954 virtual void getTargetDefines(const LangOptions &Opts,
955 std::vector<char> &Defines) const {
Eli Friedman01b86682008-08-20 07:28:14 +0000956 // FIXME: This is missing a lot of important defines; some of the
957 // missing stuff is likely to break system headers.
Gabor Greif26658672008-02-21 16:29:08 +0000958 Define(Defines, "__sparc");
Eli Friedmanbf0c9bd2008-05-25 05:26:09 +0000959 Define(Defines, "__sparc__");
Gabor Greif26658672008-02-21 16:29:08 +0000960 Define(Defines, "__sparcv8");
961 }
962 virtual void getTargetBuiltins(const Builtin::Info *&Records,
963 unsigned &NumRecords) const {
Eli Friedman01b86682008-08-20 07:28:14 +0000964 // FIXME: Implement!
Gabor Greif26658672008-02-21 16:29:08 +0000965 }
966 virtual const char *getVAListDeclaration() const {
Eli Friedman01b86682008-08-20 07:28:14 +0000967 return "typedef void* __builtin_va_list;";
Gabor Greif26658672008-02-21 16:29:08 +0000968 }
969 virtual const char *getTargetPrefix() const {
Eli Friedman01b86682008-08-20 07:28:14 +0000970 return "sparc";
Gabor Greif26658672008-02-21 16:29:08 +0000971 }
972 virtual void getGCCRegNames(const char * const *&Names,
Chris Lattnere957f532009-01-27 01:58:38 +0000973 unsigned &NumNames) const;
Gabor Greif26658672008-02-21 16:29:08 +0000974 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattnere957f532009-01-27 01:58:38 +0000975 unsigned &NumAliases) const;
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000976 virtual bool validateAsmConstraint(const char *&Name,
Gabor Greif26658672008-02-21 16:29:08 +0000977 TargetInfo::ConstraintInfo &info) const {
Eli Friedman01b86682008-08-20 07:28:14 +0000978 // FIXME: Implement!
979 return false;
Gabor Greif26658672008-02-21 16:29:08 +0000980 }
981 virtual const char *getClobbers() const {
Eli Friedman01b86682008-08-20 07:28:14 +0000982 // FIXME: Implement!
983 return "";
Gabor Greif26658672008-02-21 16:29:08 +0000984 }
985};
986
Chris Lattnere957f532009-01-27 01:58:38 +0000987const char * const SparcV8TargetInfo::GCCRegNames[] = {
988 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
989 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
990 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
991 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
992};
993
994void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names,
995 unsigned &NumNames) const {
996 Names = GCCRegNames;
997 NumNames = llvm::array_lengthof(GCCRegNames);
998}
999
1000const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = {
1001 { { "g0" }, "r0" },
1002 { { "g1" }, "r1" },
1003 { { "g2" }, "r2" },
1004 { { "g3" }, "r3" },
1005 { { "g4" }, "r4" },
1006 { { "g5" }, "r5" },
1007 { { "g6" }, "r6" },
1008 { { "g7" }, "r7" },
1009 { { "o0" }, "r8" },
1010 { { "o1" }, "r9" },
1011 { { "o2" }, "r10" },
1012 { { "o3" }, "r11" },
1013 { { "o4" }, "r12" },
1014 { { "o5" }, "r13" },
1015 { { "o6", "sp" }, "r14" },
1016 { { "o7" }, "r15" },
1017 { { "l0" }, "r16" },
1018 { { "l1" }, "r17" },
1019 { { "l2" }, "r18" },
1020 { { "l3" }, "r19" },
1021 { { "l4" }, "r20" },
1022 { { "l5" }, "r21" },
1023 { { "l6" }, "r22" },
1024 { { "l7" }, "r23" },
1025 { { "i0" }, "r24" },
1026 { { "i1" }, "r25" },
1027 { { "i2" }, "r26" },
1028 { { "i3" }, "r27" },
1029 { { "i4" }, "r28" },
1030 { { "i5" }, "r29" },
1031 { { "i6", "fp" }, "r30" },
1032 { { "i7" }, "r31" },
1033};
1034
1035void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
1036 unsigned &NumAliases) const {
1037 Aliases = GCCRegAliases;
1038 NumAliases = llvm::array_lengthof(GCCRegAliases);
1039}
Gabor Greif26658672008-02-21 16:29:08 +00001040} // end anonymous namespace.
1041
Eli Friedman01b86682008-08-20 07:28:14 +00001042namespace {
1043class SolarisSparcV8TargetInfo : public SparcV8TargetInfo {
1044public:
1045 SolarisSparcV8TargetInfo(const std::string& triple) :
Eli Friedmanf509d732008-11-02 02:43:55 +00001046 SparcV8TargetInfo(triple) {
1047 SizeType = UnsignedInt;
1048 PtrDiffType = SignedInt;
1049 }
Eli Friedman01b86682008-08-20 07:28:14 +00001050
Chris Lattner33328642009-03-20 15:52:06 +00001051 virtual void getTargetDefines(const LangOptions &Opts,
1052 std::vector<char> &Defines) const {
1053 SparcV8TargetInfo::getTargetDefines(Opts, Defines);
Eli Friedman01b86682008-08-20 07:28:14 +00001054 getSolarisDefines(Defines);
1055 }
1056};
1057} // end anonymous namespace.
Reid Spencer5f016e22007-07-11 17:01:13 +00001058
Chris Lattner2621fd12008-05-08 05:58:21 +00001059namespace {
1060 class PIC16TargetInfo : public TargetInfo{
1061 public:
1062 PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) {
Sanjiv Gupta31fc07d2008-10-31 09:52:39 +00001063 IntWidth = 16;
1064 LongWidth = LongLongWidth = 32;
1065 PointerWidth = 16;
1066 IntAlign = 8;
1067 LongAlign = LongLongAlign = 8;
Eli Friedman61538a72008-05-20 14:21:01 +00001068 PointerAlign = 8;
Sanjiv Gupta31fc07d2008-10-31 09:52:39 +00001069 SizeType = UnsignedInt;
1070 IntMaxType = SignedLong;
1071 UIntMaxType = UnsignedLong;
Chris Lattner6ad474f2009-02-13 22:28:55 +00001072 IntPtrType = SignedShort;
Eli Friedmanf509d732008-11-02 02:43:55 +00001073 PtrDiffType = SignedInt;
Sanjiv Gupta364af812008-08-18 10:05:22 +00001074 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8";
Chris Lattner2621fd12008-05-08 05:58:21 +00001075 }
Chris Lattner927686f2008-05-09 06:08:39 +00001076 virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; }
1077 virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; }
Chris Lattner33328642009-03-20 15:52:06 +00001078 virtual void getTargetDefines(const LangOptions &Opts,
1079 std::vector<char> &Defines) const {
Chris Lattner2621fd12008-05-08 05:58:21 +00001080 Define(Defines, "__pic16");
1081 }
1082 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1083 unsigned &NumRecords) const {}
1084 virtual const char *getVAListDeclaration() const { return "";}
1085 virtual const char *getClobbers() const {return "";}
1086 virtual const char *getTargetPrefix() const {return "";}
1087 virtual void getGCCRegNames(const char * const *&Names,
1088 unsigned &NumNames) const {}
Anders Carlsson066d2ea2009-02-28 17:11:49 +00001089 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattner2621fd12008-05-08 05:58:21 +00001090 TargetInfo::ConstraintInfo &info) const {
1091 return true;
1092 }
1093 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1094 unsigned &NumAliases) const {}
1095 virtual bool useGlobalsForAutomaticVariables() const {return true;}
1096 };
1097}
1098
Reid Spencer5f016e22007-07-11 17:01:13 +00001099//===----------------------------------------------------------------------===//
1100// Driver code
1101//===----------------------------------------------------------------------===//
1102
Ted Kremenek8448d382007-12-04 17:07:35 +00001103static inline bool IsX86(const std::string& TT) {
Ted Kremenekae360762007-12-03 22:06:55 +00001104 return (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' &&
1105 TT[4] == '-' && TT[1] - '3' < 6);
1106}
1107
Chris Lattner42e67372008-03-05 01:18:20 +00001108/// CreateTargetInfo - Return the target info object for the specified target
1109/// triple.
1110TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
Eli Friedmaned855cb2008-08-21 00:13:15 +00001111 // OS detection; this isn't really anywhere near complete.
1112 // Additions and corrections are welcome.
1113 bool isDarwin = T.find("-darwin") != std::string::npos;
Chris Lattnereac7aee2008-08-23 18:23:14 +00001114 bool isDragonFly = T.find("-dragonfly") != std::string::npos;
Chris Lattnerfd0269d2008-10-16 17:04:31 +00001115 bool isFreeBSD = T.find("-freebsd") != std::string::npos;
Eli Friedmaned855cb2008-08-21 00:13:15 +00001116 bool isSolaris = T.find("-solaris") != std::string::npos;
1117 bool isLinux = T.find("-linux") != std::string::npos;
1118 bool isWindows = T.find("-windows") != std::string::npos ||
1119 T.find("-win32") != std::string::npos ||
1120 T.find("-mingw") != std::string::npos;
Eli Friedman61538a72008-05-20 14:21:01 +00001121
Eli Friedmaned855cb2008-08-21 00:13:15 +00001122 if (T.find("ppc-") == 0 || T.find("powerpc-") == 0) {
1123 if (isDarwin)
1124 return new DarwinPPCTargetInfo(T);
1125 return new PPC32TargetInfo(T);
1126 }
Eli Friedman61538a72008-05-20 14:21:01 +00001127
Eli Friedmaned855cb2008-08-21 00:13:15 +00001128 if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0) {
1129 if (isDarwin)
1130 return new DarwinPPC64TargetInfo(T);
1131 return new PPC64TargetInfo(T);
1132 }
Chris Lattner393ff042008-04-21 18:56:49 +00001133
Eli Friedmaned855cb2008-08-21 00:13:15 +00001134 if (T.find("armv6-") == 0 || T.find("arm-") == 0) {
1135 if (isDarwin)
1136 return new DarwinARMTargetInfo(T);
Daniel Dunbar1e0107a2009-03-23 16:09:04 +00001137 if (isFreeBSD)
1138 return new FreeBSDARMTargetInfo(T);
Eli Friedmaned855cb2008-08-21 00:13:15 +00001139 return new ARMTargetInfo(T);
1140 }
Eli Friedman61538a72008-05-20 14:21:01 +00001141
Eli Friedmaned855cb2008-08-21 00:13:15 +00001142 if (T.find("sparc-") == 0) {
1143 if (isSolaris)
1144 return new SolarisSparcV8TargetInfo(T);
1145 return new SparcV8TargetInfo(T);
1146 }
1147
Chris Lattner54fefbe2009-02-20 17:04:14 +00001148 if (T.find("x86_64-") == 0 || T.find("amd64-") == 0) {
Eli Friedmaned855cb2008-08-21 00:13:15 +00001149 if (isDarwin)
1150 return new DarwinX86_64TargetInfo(T);
Daniel Dunbarb55a42b2008-09-23 17:37:57 +00001151 if (isLinux)
1152 return new LinuxX86_64TargetInfo(T);
Chris Lattnerfd0269d2008-10-16 17:04:31 +00001153 if (isFreeBSD)
1154 return new FreeBSDX86_64TargetInfo(T);
Eli Friedmaned855cb2008-08-21 00:13:15 +00001155 return new X86_64TargetInfo(T);
1156 }
Eli Friedman61538a72008-05-20 14:21:01 +00001157
Chris Lattner2621fd12008-05-08 05:58:21 +00001158 if (T.find("pic16-") == 0)
1159 return new PIC16TargetInfo(T);
1160
Eli Friedmaned855cb2008-08-21 00:13:15 +00001161 if (IsX86(T)) {
1162 if (isDarwin)
1163 return new DarwinI386TargetInfo(T);
Eli Friedman0d4047b2008-08-21 00:24:02 +00001164 if (isLinux)
1165 return new LinuxX86_32TargetInfo(T);
Chris Lattnereac7aee2008-08-23 18:23:14 +00001166 if (isDragonFly)
1167 return new DragonFlyX86_32TargetInfo(T);
Chris Lattnerfd0269d2008-10-16 17:04:31 +00001168 if (isFreeBSD)
1169 return new FreeBSDX86_32TargetInfo(T);
Eli Friedman29a30502008-08-21 01:40:19 +00001170 if (isWindows)
1171 return new WindowsX86_32TargetInfo(T);
Eli Friedmaned855cb2008-08-21 00:13:15 +00001172 return new X86_32TargetInfo(T);
1173 }
Eli Friedman61538a72008-05-20 14:21:01 +00001174
Chris Lattner42e67372008-03-05 01:18:20 +00001175 return NULL;
Reid Spencer5f016e22007-07-11 17:01:13 +00001176}
Ted Kremenekfb79f7c2008-03-04 17:47:18 +00001177