blob: 5f5ba60e85853f0b510ceac5a6264262e8caa8a9 [file] [log] [blame]
Chris Lattner4b009652007-07-25 00:24:17 +00001//===--- Targets.cpp - Implement -arch option and targets -----------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner959e5be2007-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 Lattner4b009652007-07-25 00:24:17 +00007//
8//===----------------------------------------------------------------------===//
9//
Ted Kremenek38591a22007-12-12 18:05:32 +000010// This file implements construction of a TargetInfo object from a
11// target triple.
Chris Lattner4b009652007-07-25 00:24:17 +000012//
13//===----------------------------------------------------------------------===//
14
Douglas Gregor2e8a7aa2009-02-16 21:58:21 +000015// FIXME: Layering violation
Chris Lattner4b009652007-07-25 00:24:17 +000016#include "clang/AST/Builtins.h"
Anders Carlssone1449c12007-12-09 23:17:02 +000017#include "clang/AST/TargetBuiltins.h"
Chris Lattner4b009652007-07-25 00:24:17 +000018#include "clang/Basic/TargetInfo.h"
Chris Lattnerddae7102008-12-04 22:54:33 +000019#include "clang/Basic/LangOptions.h"
Anders Carlsson7dd1c952007-11-24 23:38:12 +000020#include "llvm/ADT/STLExtras.h"
Eli Friedmand4011892008-05-20 14:27:34 +000021#include "llvm/ADT/APFloat.h"
Chris Lattnerc345a802009-03-20 16:06:38 +000022#include "llvm/ADT/SmallString.h"
Chris Lattner4b009652007-07-25 00:24:17 +000023using namespace clang;
24
Chris Lattner4b009652007-07-25 00:24:17 +000025//===----------------------------------------------------------------------===//
26// Common code shared among targets.
27//===----------------------------------------------------------------------===//
28
Chris Lattner0db667a2007-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 Lattnerc345a802009-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 Lattnerbd00eb82008-10-05 21:50:58 +000062//===----------------------------------------------------------------------===//
63// Defines specific to certain operating systems.
64//===----------------------------------------------------------------------===//
65
Eli Friedmanff158dd2008-08-20 07:28:14 +000066static void getSolarisDefines(std::vector<char> &Defs) {
67 Define(Defs, "__SUN__");
68 Define(Defs, "__SOLARIS__");
69}
Chris Lattner4b009652007-07-25 00:24:17 +000070
Chris Lattnerab81f162009-03-20 15:55:34 +000071static void getFreeBSDDefines(const LangOptions &Opts, bool is64Bit,
72 const char *Triple, std::vector<char> &Defs) {
Chris Lattner98cb2a22008-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 Lattnerc345a802009-03-20 16:06:38 +000085 DefineStd(Defs, "unix", Opts);
Anton Korobeynikovfb820852009-02-14 16:42:50 +000086 Define(Defs, "__ELF__", "1");
Chris Lattner98cb2a22008-10-16 17:04:31 +000087 if (is64Bit) {
88 Define(Defs, "__LP64__");
89 }
90}
91
Chris Lattnerab81f162009-03-20 15:55:34 +000092static void getDragonFlyDefines(const LangOptions &Opts,
93 std::vector<char> &Defs) {
Chris Lattnerbd00eb82008-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 Lattnerc345a802009-03-20 16:06:38 +0000100 DefineStd(Defs, "unix", Opts);
Chris Lattnerbd00eb82008-10-05 21:50:58 +0000101}
102
Chris Lattnerab81f162009-03-20 15:55:34 +0000103static void getLinuxDefines(const LangOptions &Opts, std::vector<char> &Defs) {
Chris Lattnerbd00eb82008-10-05 21:50:58 +0000104 // Linux defines; list based off of gcc output
Chris Lattnerc345a802009-03-20 16:06:38 +0000105 DefineStd(Defs, "unix", Opts);
106 DefineStd(Defs, "linux", Opts);
Chris Lattnerbd00eb82008-10-05 21:50:58 +0000107 Define(Defs, "__gnu_linux__");
Argiris Kirtzidis99de9532009-02-14 15:02:45 +0000108 Define(Defs, "__ELF__", "1");
Chris Lattnerbd00eb82008-10-05 21:50:58 +0000109}
110
Chris Lattnerd7bc88b2008-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 Lattnerc5dc8eb2008-09-30 01:00:25 +0000141static void getDarwinDefines(std::vector<char> &Defs, const char *Triple) {
Eli Friedman872996c2008-08-20 02:34:37 +0000142 Define(Defs, "__APPLE__");
143 Define(Defs, "__MACH__");
Chris Lattner8405e092009-02-05 07:19:24 +0000144 Define(Defs, "OBJC_NEW_PROPERTIES");
145
146 // FIXME: OBJC_ZEROCOST_EXCEPTIONS when using zero cost eh.
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000147
148 // Figure out which "darwin number" the target triple is. "darwin9" -> 10.5.
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000149 unsigned Maj, Min;
150 if (getDarwinNumber(Triple, Maj, Min)) {
Chris Lattnerd376f6d2008-09-30 20:30:12 +0000151 char DarwinStr[] = "1000";
Chris Lattnerd7bc88b2008-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 Lattnerc5dc8eb2008-09-30 01:00:25 +0000155 }
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000156
157 // Handle minor version: 10.4.9 -> darwin8.9 -> "1049"
158 DarwinStr[3] = Min+'0';
Chris Lattnerd376f6d2008-09-30 20:30:12 +0000159 Define(Defs, "__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", DarwinStr);
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000160 }
Eli Friedman872996c2008-08-20 02:34:37 +0000161}
Chris Lattner4b009652007-07-25 00:24:17 +0000162
Chris Lattnerd7bc88b2008-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 Jahaniand09b9f72009-02-12 17:54:33 +0000173 // As does nonfragile-abi for 64bit mode
Fariborz Jahanian27f58962009-02-24 23:34:44 +0000174 if (Maj > 9)
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000175 Opts.Blocks = 1;
Fariborz Jahanian27f58962009-02-24 23:34:44 +0000176
Fariborz Jahanian72efecb2009-02-24 23:38:42 +0000177 if (Maj >= 9 && Opts.ObjC1 && !strncmp(Triple, "x86_64", 6))
178 Opts.ObjCNonFragileABI = 1;
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000179}
180
181
Chris Lattnerbd00eb82008-10-05 21:50:58 +0000182//===----------------------------------------------------------------------===//
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000183// Specific target implementations.
184//===----------------------------------------------------------------------===//
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000185
Eli Friedmanfd5a4122008-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 Lattner4b009652007-07-25 00:24:17 +0000199 Records = BuiltinInfo;
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000200 NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner4b009652007-07-25 00:24:17 +0000201 }
Chris Lattnerbef1d722009-03-02 22:27:17 +0000202
Chris Lattner79682402009-03-20 15:52:06 +0000203 virtual void getTargetDefines(const LangOptions &Opts,
204 std::vector<char> &Defines) const;
Chris Lattnerbef1d722009-03-02 22:27:17 +0000205
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000206 virtual const char *getVAListDeclaration() const {
Chris Lattnera07708f2008-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 Friedmanfd5a4122008-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 Lattnera07708f2008-10-27 01:11:29 +0000215 "} __builtin_va_list[1];";*/
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000216 }
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000217 virtual const char *getTargetPrefix() const {
218 return "ppc";
Anders Carlsson4ce42302007-11-27 04:11:28 +0000219 }
Eli Friedmanfd5a4122008-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 Carlsson36834a72009-02-28 17:11:49 +0000224 virtual bool validateAsmConstraint(const char *&Name,
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000225 TargetInfo::ConstraintInfo &info) const {
Anders Carlsson36834a72009-02-28 17:11:49 +0000226 switch (*Name) {
Anders Carlsson4ce42302007-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 Friedmanfd5a4122008-08-20 23:11:40 +0000236 virtual const char *getClobbers() const {
237 return "";
Anders Carlsson4ce42302007-11-27 04:11:28 +0000238 }
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000239};
Anders Carlsson4ce42302007-11-27 04:11:28 +0000240
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000241const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
Douglas Gregor2e8a7aa2009-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 Friedmanfd5a4122008-08-20 23:11:40 +0000244#include "clang/AST/PPCBuiltins.def"
245};
Chris Lattnerbef1d722009-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 Lattner79682402009-03-20 15:52:06 +0000250void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
251 std::vector<char> &Defs) const {
Chris Lattnerbef1d722009-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 Lattner9fd73612008-04-21 18:56:49 +0000277
Eli Friedmanfd5a4122008-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 Lattner4b009652007-07-25 00:24:17 +0000298
Eli Friedmanfd5a4122008-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 Lattner4b009652007-07-25 00:24:17 +0000304
Eli Friedmanfd5a4122008-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 Lattner4b009652007-07-25 00:24:17 +0000348
349namespace {
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000350class PPC32TargetInfo : public PPCTargetInfo {
Chris Lattner4b009652007-07-25 00:24:17 +0000351public:
Eli Friedman2b161652008-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 Lattner4b009652007-07-25 00:24:17 +0000356};
357} // end anonymous namespace.
358
359namespace {
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000360class PPC64TargetInfo : public PPCTargetInfo {
Chris Lattner4b009652007-07-25 00:24:17 +0000361public:
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000362 PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
Chris Lattnere5fde952008-05-09 06:17:04 +0000363 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedman2b161652008-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 Lattnere5fde952008-05-09 06:17:04 +0000366 }
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000367};
368} // end anonymous namespace.
369
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000370
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000371namespace {
372class DarwinPPCTargetInfo : public PPC32TargetInfo {
373public:
374 DarwinPPCTargetInfo(const std::string& triple) : PPC32TargetInfo(triple) {}
Chris Lattner79682402009-03-20 15:52:06 +0000375 virtual void getTargetDefines(const LangOptions &Opts,
376 std::vector<char> &Defines) const {
377 PPC32TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000378 getDarwinDefines(Defines, getTargetTriple());
Chris Lattner4b009652007-07-25 00:24:17 +0000379 }
Daniel Dunbar34542952008-08-23 08:43:39 +0000380
Chris Lattnerddae7102008-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 Lattnerd7bc88b2008-12-04 23:20:07 +0000385 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattnerddae7102008-12-04 22:54:33 +0000386 }
Eli Friedmanfd5a4122008-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 Lattner79682402009-03-20 15:52:06 +0000394 virtual void getTargetDefines(const LangOptions &Opts,
395 std::vector<char> &Defines) const {
396 PPC64TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000397 getDarwinDefines(Defines, getTargetTriple());
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000398 }
Daniel Dunbar34542952008-08-23 08:43:39 +0000399
Chris Lattnerddae7102008-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 Lattnerd7bc88b2008-12-04 23:20:07 +0000404 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattnerddae7102008-12-04 22:54:33 +0000405 }
Chris Lattner4b009652007-07-25 00:24:17 +0000406};
407} // end anonymous namespace.
408
409namespace {
Eli Friedman872996c2008-08-20 02:34:37 +0000410// Namespace for x86 abstract base class
411const Builtin::Info BuiltinInfo[] = {
Douglas Gregor2e8a7aa2009-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 Friedman872996c2008-08-20 02:34:37 +0000414#include "clang/AST/X86Builtins.def"
415};
Eli Friedman0b7b1cb2008-05-20 14:21:01 +0000416
Eli Friedman872996c2008-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 Lattner715fe4c2009-03-02 22:40:39 +0000441 enum X86SSEEnum {
442 NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42
443 } SSELevel;
Eli Friedman872996c2008-08-20 02:34:37 +0000444public:
Chris Lattner715fe4c2009-03-02 22:40:39 +0000445 X86TargetInfo(const std::string& triple)
Chris Lattnerf6790a82009-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 Friedman872996c2008-08-20 02:34:37 +0000450 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
Chris Lattner4b009652007-07-25 00:24:17 +0000451 }
452 virtual void getTargetBuiltins(const Builtin::Info *&Records,
453 unsigned &NumRecords) const {
Eli Friedman872996c2008-08-20 02:34:37 +0000454 Records = BuiltinInfo;
455 NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner4b009652007-07-25 00:24:17 +0000456 }
Anders Carlsson333052c2007-12-08 19:32:57 +0000457 virtual const char *getTargetPrefix() const {
Eli Friedman872996c2008-08-20 02:34:37 +0000458 return "x86";
Anders Carlsson333052c2007-12-08 19:32:57 +0000459 }
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000460 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedman872996c2008-08-20 02:34:37 +0000461 unsigned &NumNames) const {
462 Names = GCCRegNames;
463 NumNames = llvm::array_lengthof(GCCRegNames);
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000464 }
465 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
466 unsigned &NumAliases) const {
Eli Friedman872996c2008-08-20 02:34:37 +0000467 Aliases = GCCRegAliases;
468 NumAliases = llvm::array_lengthof(GCCRegAliases);
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000469 }
Anders Carlsson36834a72009-02-28 17:11:49 +0000470 virtual bool validateAsmConstraint(const char *&Name,
Eli Friedman872996c2008-08-20 02:34:37 +0000471 TargetInfo::ConstraintInfo &info) const;
472 virtual std::string convertConstraint(const char Constraint) const;
Anders Carlsson4ce42302007-11-27 04:11:28 +0000473 virtual const char *getClobbers() const {
Eli Friedman872996c2008-08-20 02:34:37 +0000474 return "~{dirflag},~{fpsr},~{flags}";
475 }
Chris Lattner79682402009-03-20 15:52:06 +0000476 virtual void getTargetDefines(const LangOptions &Opts,
477 std::vector<char> &Defines) const;
Chris Lattner7d6220c2009-03-02 22:20:04 +0000478
Chris Lattnerf6790a82009-03-03 19:56:18 +0000479 virtual int HandleTargetFeatures(std::string *StrArray, unsigned NumStrs,
480 std::string &ErrorReason);
Chris Lattner4b009652007-07-25 00:24:17 +0000481};
Chris Lattner7d6220c2009-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 Lattnerf6790a82009-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 Lattner7d6220c2009-03-02 22:20:04 +0000522}
Chris Lattnerbef1d722009-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 Lattner79682402009-03-20 15:52:06 +0000526void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
527 std::vector<char> &Defs) const {
Chris Lattnerbef1d722009-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 Lattnerc345a802009-03-20 16:06:38 +0000538 DefineStd(Defs, "i386", Opts);
Chris Lattnerbef1d722009-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 Lattnerbef1d722009-03-02 22:27:17 +0000548 Define(Defs, "__REGISTER_PREFIX__", "");
Chris Lattner715fe4c2009-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 Lattnerbef1d722009-03-02 22:27:17 +0000571}
572
Eli Friedman872996c2008-08-20 02:34:37 +0000573
574bool
Anders Carlsson36834a72009-02-28 17:11:49 +0000575X86TargetInfo::validateAsmConstraint(const char *&Name,
Eli Friedman872996c2008-08-20 02:34:37 +0000576 TargetInfo::ConstraintInfo &info) const {
Anders Carlsson36834a72009-02-28 17:11:49 +0000577 switch (*Name) {
Eli Friedman872996c2008-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 Carlsson2285e622008-10-06 00:41:45 +0000589 case 'y': // Any MMX register.
Anders Carlssond2459f92008-10-06 19:17:39 +0000590 case 'x': // Any SSE register.
Eli Friedman872996c2008-08-20 02:34:37 +0000591 case 'Q': // Any register accessible as [r]h: a, b, c, and d.
Anders Carlssonff235da2009-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 Friedman872996c2008-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 Friedman872996c2008-08-20 02:34:37 +0000620} // end anonymous namespace
Chris Lattner4b009652007-07-25 00:24:17 +0000621
622namespace {
Eli Friedman872996c2008-08-20 02:34:37 +0000623// X86-32 generic target
624class X86_32TargetInfo : public X86TargetInfo {
Chris Lattner4b009652007-07-25 00:24:17 +0000625public:
Eli Friedman872996c2008-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 Friedman2b161652008-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 Friedman04ede302009-03-29 20:31:09 +0000633 SizeType = UnsignedInt;
634 PtrDiffType = SignedInt;
635 IntPtrType = SignedInt;
Eli Friedman872996c2008-08-20 02:34:37 +0000636 }
637 virtual const char *getVAListDeclaration() const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000638 return "typedef char* __builtin_va_list;";
Eli Friedman872996c2008-08-20 02:34:37 +0000639 }
Eli Friedman872996c2008-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 Friedman04ede302009-03-29 20:31:09 +0000650 SizeType = UnsignedLong;
651 IntPtrType = SignedLong;
Eli Friedman2b161652008-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 Friedman872996c2008-08-20 02:34:37 +0000655 }
Daniel Dunbarc3a48932009-03-31 23:42:16 +0000656
657 virtual const char *getStringSymbolPrefix(bool IsConstant) const {
658 return IsConstant ? "\01LC" : "\01lC";
659 }
660
Daniel Dunbar6a916482009-04-03 00:57:44 +0000661 virtual const char *getUnicodeStringSymbolPrefix() const {
662 return "__utf16_string_";
663 }
664
665 virtual const char *getUnicodeStringSection() const {
666 return "__TEXT,__ustring";
667 }
668
Daniel Dunbarc3a48932009-03-31 23:42:16 +0000669 virtual const char *getCFStringSymbolPrefix() const {
670 return "\01LC";
671 }
672
Chris Lattner79682402009-03-20 15:52:06 +0000673 virtual void getTargetDefines(const LangOptions &Opts,
674 std::vector<char> &Defines) const {
675 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000676 getDarwinDefines(Defines, getTargetTriple());
Eli Friedman872996c2008-08-20 02:34:37 +0000677 }
Daniel Dunbarc3a48932009-03-31 23:42:16 +0000678
Chris Lattnerddae7102008-12-04 22:54:33 +0000679 /// getDefaultLangOptions - Allow the target to specify default settings for
680 /// various language options. These may be overridden by command line
681 /// options.
682 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000683 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattnerddae7102008-12-04 22:54:33 +0000684 }
Eli Friedman872996c2008-08-20 02:34:37 +0000685};
686} // end anonymous namespace
687
688namespace {
Chris Lattner98cb2a22008-10-16 17:04:31 +0000689// x86-32 FreeBSD target
690class FreeBSDX86_32TargetInfo : public X86_32TargetInfo {
691public:
Eli Friedman7cca0982008-11-02 02:43:55 +0000692 FreeBSDX86_32TargetInfo(const std::string& triple) :
Eli Friedman04ede302009-03-29 20:31:09 +0000693 X86_32TargetInfo(triple) { }
Chris Lattner79682402009-03-20 15:52:06 +0000694 virtual void getTargetDefines(const LangOptions &Opts,
695 std::vector<char> &Defines) const {
696 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerab81f162009-03-20 15:55:34 +0000697 getFreeBSDDefines(Opts, 0, getTargetTriple(), Defines);
Chris Lattner98cb2a22008-10-16 17:04:31 +0000698 }
699};
700} // end anonymous namespace
701
702namespace {
Chris Lattnerd4faca42008-08-23 18:23:14 +0000703// x86-32 DragonFly target
704class DragonFlyX86_32TargetInfo : public X86_32TargetInfo {
705public:
Eli Friedman7cca0982008-11-02 02:43:55 +0000706 DragonFlyX86_32TargetInfo(const std::string& triple) :
Eli Friedman04ede302009-03-29 20:31:09 +0000707 X86_32TargetInfo(triple) { }
Chris Lattner79682402009-03-20 15:52:06 +0000708 virtual void getTargetDefines(const LangOptions &Opts,
709 std::vector<char> &Defines) const {
710 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerab81f162009-03-20 15:55:34 +0000711 getDragonFlyDefines(Opts, Defines);
Chris Lattnerd4faca42008-08-23 18:23:14 +0000712 }
713};
714} // end anonymous namespace
715
716namespace {
Eli Friedman5fb0a022008-08-21 00:24:02 +0000717// x86-32 Linux target
718class LinuxX86_32TargetInfo : public X86_32TargetInfo {
719public:
720 LinuxX86_32TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
Chris Lattner5edfe012008-10-05 19:44:25 +0000721 UserLabelPrefix = "";
Eli Friedman5fb0a022008-08-21 00:24:02 +0000722 }
Chris Lattner79682402009-03-20 15:52:06 +0000723 virtual void getTargetDefines(const LangOptions &Opts,
724 std::vector<char> &Defines) const {
725 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerab81f162009-03-20 15:55:34 +0000726 getLinuxDefines(Opts, Defines);
Eli Friedman5fb0a022008-08-21 00:24:02 +0000727 }
728};
729} // end anonymous namespace
730
731namespace {
Eli Friedman23cb7912008-08-21 01:40:19 +0000732// x86-32 Windows target
733class WindowsX86_32TargetInfo : public X86_32TargetInfo {
734public:
735 WindowsX86_32TargetInfo(const std::string& triple)
736 : X86_32TargetInfo(triple) {
737 // FIXME: Fix wchar_t.
738 // FIXME: We should probably enable -fms-extensions by default for
739 // this target.
740 }
Chris Lattner79682402009-03-20 15:52:06 +0000741 virtual void getTargetDefines(const LangOptions &Opts,
742 std::vector<char> &Defines) const {
743 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Eli Friedman23cb7912008-08-21 01:40:19 +0000744 // This list is based off of the the list of things MingW defines
Eli Friedman23cb7912008-08-21 01:40:19 +0000745 Define(Defines, "_WIN32");
Chris Lattnerc345a802009-03-20 16:06:38 +0000746 DefineStd(Defines, "WIN32", Opts);
747 DefineStd(Defines, "WINNT", Opts);
Eli Friedman23cb7912008-08-21 01:40:19 +0000748 Define(Defines, "_X86_");
749 Define(Defines, "__MSVCRT__");
750 }
751};
752} // end anonymous namespace
753
754namespace {
Eli Friedman872996c2008-08-20 02:34:37 +0000755// x86-64 generic target
756class X86_64TargetInfo : public X86TargetInfo {
757public:
Chris Lattner79682402009-03-20 15:52:06 +0000758 X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) {
Chris Lattnere5fde952008-05-09 06:17:04 +0000759 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Chris Lattner4dfc45a2009-01-28 06:58:19 +0000760 DoubleAlign = LongLongAlign = 64;
Eli Friedman0b7b1cb2008-05-20 14:21:01 +0000761 LongDoubleWidth = 128;
762 LongDoubleAlign = 128;
Chris Lattnerbfbfbaf2009-02-05 07:32:46 +0000763 IntMaxType = SignedLong;
764 UIntMaxType = UnsignedLong;
765
Eli Friedman2b161652008-08-21 00:13:15 +0000766 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
767 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
768 "a0:0:64-f80:128:128";
Chris Lattner4b009652007-07-25 00:24:17 +0000769 }
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000770 virtual const char *getVAListDeclaration() const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000771 return "typedef struct __va_list_tag {"
772 " unsigned gp_offset;"
773 " unsigned fp_offset;"
774 " void* overflow_arg_area;"
775 " void* reg_save_area;"
776 "} __builtin_va_list[1];";
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000777 }
Eli Friedman872996c2008-08-20 02:34:37 +0000778};
779} // end anonymous namespace
780
781namespace {
Chris Lattner98cb2a22008-10-16 17:04:31 +0000782// x86-64 FreeBSD target
783class FreeBSDX86_64TargetInfo : public X86_64TargetInfo {
784public:
Chris Lattner79682402009-03-20 15:52:06 +0000785 FreeBSDX86_64TargetInfo(const std::string &triple)
786 : X86_64TargetInfo(triple) {}
787 virtual void getTargetDefines(const LangOptions &Opts,
788 std::vector<char> &Defines) const {
789 X86_64TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerab81f162009-03-20 15:55:34 +0000790 getFreeBSDDefines(Opts, 1, getTargetTriple(), Defines);
Chris Lattner98cb2a22008-10-16 17:04:31 +0000791 }
792};
793} // end anonymous namespace
794
795namespace {
Daniel Dunbare5a80f22008-09-23 17:37:57 +0000796// x86-64 Linux target
797class LinuxX86_64TargetInfo : public X86_64TargetInfo {
798public:
799 LinuxX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) {
Chris Lattner5edfe012008-10-05 19:44:25 +0000800 UserLabelPrefix = "";
Daniel Dunbare5a80f22008-09-23 17:37:57 +0000801 }
Chris Lattner79682402009-03-20 15:52:06 +0000802 virtual void getTargetDefines(const LangOptions &Opts,
803 std::vector<char> &Defines) const {
804 X86_64TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerab81f162009-03-20 15:55:34 +0000805 getLinuxDefines(Opts, Defines);
Daniel Dunbare5a80f22008-09-23 17:37:57 +0000806 }
807};
808} // end anonymous namespace
809
810namespace {
Eli Friedman872996c2008-08-20 02:34:37 +0000811// x86-64 Darwin (OS X) target
812class DarwinX86_64TargetInfo : public X86_64TargetInfo {
813public:
814 DarwinX86_64TargetInfo(const std::string& triple) :
815 X86_64TargetInfo(triple) {}
816
Daniel Dunbarc3a48932009-03-31 23:42:16 +0000817 virtual const char *getStringSymbolPrefix(bool IsConstant) const {
818 return IsConstant ? "\01LC" : "\01lC";
819 }
820
Daniel Dunbar6a916482009-04-03 00:57:44 +0000821 virtual const char *getUnicodeStringSymbolPrefix() const {
822 return "__utf16_string_";
823 }
824
825 virtual const char *getUnicodeStringSection() const {
826 return "__TEXT,__ustring";
827 }
828
Daniel Dunbarc3a48932009-03-31 23:42:16 +0000829 virtual const char *getCFStringSymbolPrefix() const {
830 return "\01L_unnamed_cfstring_";
831 }
832
Chris Lattner79682402009-03-20 15:52:06 +0000833 virtual void getTargetDefines(const LangOptions &Opts,
834 std::vector<char> &Defines) const {
835 X86_64TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000836 getDarwinDefines(Defines, getTargetTriple());
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000837 }
Daniel Dunbar34542952008-08-23 08:43:39 +0000838
Chris Lattnerddae7102008-12-04 22:54:33 +0000839 /// getDefaultLangOptions - Allow the target to specify default settings for
840 /// various language options. These may be overridden by command line
841 /// options.
842 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000843 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattnerddae7102008-12-04 22:54:33 +0000844 }
Chris Lattner4b009652007-07-25 00:24:17 +0000845};
846} // end anonymous namespace.
847
Chris Lattner9fd73612008-04-21 18:56:49 +0000848namespace {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000849class ARMTargetInfo : public TargetInfo {
Chris Lattner9fd73612008-04-21 18:56:49 +0000850public:
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000851 ARMTargetInfo(const std::string& triple) : TargetInfo(triple) {
852 // FIXME: Are the defaults correct for ARM?
Eli Friedman2b161652008-08-21 00:13:15 +0000853 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
854 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:64";
Eli Friedman0b7b1cb2008-05-20 14:21:01 +0000855 }
Chris Lattner79682402009-03-20 15:52:06 +0000856 virtual void getTargetDefines(const LangOptions &Opts,
857 std::vector<char> &Defs) const {
Chris Lattnerbef1d722009-03-02 22:27:17 +0000858 // Target identification.
859 Define(Defs, "__arm");
860 Define(Defs, "__arm__");
861
862 // Target properties.
863 Define(Defs, "__LITTLE_ENDIAN__");
864
865 // Subtarget options. [hard coded to v6 for now]
866 Define(Defs, "__ARM_ARCH_6K__");
867 Define(Defs, "__ARMEL__");
868 Define(Defs, "__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", "20000");
Chris Lattner9fd73612008-04-21 18:56:49 +0000869 }
870 virtual void getTargetBuiltins(const Builtin::Info *&Records,
871 unsigned &NumRecords) const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000872 // FIXME: Implement.
873 Records = 0;
Chris Lattner9fd73612008-04-21 18:56:49 +0000874 NumRecords = 0;
875 }
876 virtual const char *getVAListDeclaration() const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000877 return "typedef char* __builtin_va_list;";
Chris Lattner9fd73612008-04-21 18:56:49 +0000878 }
879 virtual const char *getTargetPrefix() const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000880 return "arm";
Chris Lattner9fd73612008-04-21 18:56:49 +0000881 }
Chris Lattner9fd73612008-04-21 18:56:49 +0000882 virtual void getGCCRegNames(const char * const *&Names,
883 unsigned &NumNames) const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000884 // FIXME: Implement.
885 Names = 0;
Chris Lattner9fd73612008-04-21 18:56:49 +0000886 NumNames = 0;
887 }
888 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
889 unsigned &NumAliases) const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000890 // FIXME: Implement.
891 Aliases = 0;
Chris Lattner9fd73612008-04-21 18:56:49 +0000892 NumAliases = 0;
893 }
Anders Carlsson36834a72009-02-28 17:11:49 +0000894 virtual bool validateAsmConstraint(const char *&Name,
Nate Begeman222823a2008-04-22 05:03:19 +0000895 TargetInfo::ConstraintInfo &info) const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000896 // FIXME: Check if this is complete
Anders Carlsson36834a72009-02-28 17:11:49 +0000897 switch (*Name) {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000898 default:
Nate Begeman222823a2008-04-22 05:03:19 +0000899 case 'l': // r0-r7
900 case 'h': // r8-r15
901 case 'w': // VFP Floating point register single precision
902 case 'P': // VFP Floating point register double precision
903 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
904 return true;
905 }
Chris Lattner9fd73612008-04-21 18:56:49 +0000906 return false;
907 }
908 virtual const char *getClobbers() const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000909 // FIXME: Is this really right?
Chris Lattner9fd73612008-04-21 18:56:49 +0000910 return "";
911 }
912};
913} // end anonymous namespace.
914
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000915
916namespace {
917class DarwinARMTargetInfo : public ARMTargetInfo {
918public:
919 DarwinARMTargetInfo(const std::string& triple) : ARMTargetInfo(triple) {}
920
Chris Lattner79682402009-03-20 15:52:06 +0000921 virtual void getTargetDefines(const LangOptions &Opts,
922 std::vector<char> &Defines) const {
923 ARMTargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000924 getDarwinDefines(Defines, getTargetTriple());
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000925 }
926};
927} // end anonymous namespace.
928
Chris Lattner4b009652007-07-25 00:24:17 +0000929namespace {
Daniel Dunbar88fd9942009-03-23 16:09:04 +0000930// arm FreeBSD target
931class FreeBSDARMTargetInfo : public ARMTargetInfo {
932public:
933 FreeBSDARMTargetInfo(const std::string& triple) : ARMTargetInfo(triple) {}
934 virtual void getTargetDefines(const LangOptions &Opts,
935 std::vector<char> &Defines) const {
936 ARMTargetInfo::getTargetDefines(Opts, Defines);
937 getFreeBSDDefines(Opts, 0, getTargetTriple(), Defines);
938 }
939};
940} // end anonymous namespace
941
942namespace {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000943class SparcV8TargetInfo : public TargetInfo {
Chris Lattnerff7c53d2009-01-27 01:58:38 +0000944 static const TargetInfo::GCCRegAlias GCCRegAliases[];
945 static const char * const GCCRegNames[];
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000946public:
Eli Friedmanff158dd2008-08-20 07:28:14 +0000947 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
948 // FIXME: Support Sparc quad-precision long double?
Eli Friedman2b161652008-08-21 00:13:15 +0000949 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
950 "i64:64:64-f32:32:32-f64:64:64-v64:64:64";
Eli Friedmanff158dd2008-08-20 07:28:14 +0000951 }
Chris Lattner79682402009-03-20 15:52:06 +0000952 virtual void getTargetDefines(const LangOptions &Opts,
953 std::vector<char> &Defines) const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000954 // FIXME: This is missing a lot of important defines; some of the
955 // missing stuff is likely to break system headers.
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000956 Define(Defines, "__sparc");
Eli Friedman1dee5c52008-05-25 05:26:09 +0000957 Define(Defines, "__sparc__");
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000958 Define(Defines, "__sparcv8");
959 }
960 virtual void getTargetBuiltins(const Builtin::Info *&Records,
961 unsigned &NumRecords) const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000962 // FIXME: Implement!
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000963 }
964 virtual const char *getVAListDeclaration() const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000965 return "typedef void* __builtin_va_list;";
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000966 }
967 virtual const char *getTargetPrefix() const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000968 return "sparc";
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000969 }
970 virtual void getGCCRegNames(const char * const *&Names,
Chris Lattnerff7c53d2009-01-27 01:58:38 +0000971 unsigned &NumNames) const;
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000972 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattnerff7c53d2009-01-27 01:58:38 +0000973 unsigned &NumAliases) const;
Anders Carlsson36834a72009-02-28 17:11:49 +0000974 virtual bool validateAsmConstraint(const char *&Name,
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000975 TargetInfo::ConstraintInfo &info) const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000976 // FIXME: Implement!
977 return false;
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000978 }
979 virtual const char *getClobbers() const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000980 // FIXME: Implement!
981 return "";
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000982 }
983};
984
Chris Lattnerff7c53d2009-01-27 01:58:38 +0000985const char * const SparcV8TargetInfo::GCCRegNames[] = {
986 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
987 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
988 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
989 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
990};
991
992void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names,
993 unsigned &NumNames) const {
994 Names = GCCRegNames;
995 NumNames = llvm::array_lengthof(GCCRegNames);
996}
997
998const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = {
999 { { "g0" }, "r0" },
1000 { { "g1" }, "r1" },
1001 { { "g2" }, "r2" },
1002 { { "g3" }, "r3" },
1003 { { "g4" }, "r4" },
1004 { { "g5" }, "r5" },
1005 { { "g6" }, "r6" },
1006 { { "g7" }, "r7" },
1007 { { "o0" }, "r8" },
1008 { { "o1" }, "r9" },
1009 { { "o2" }, "r10" },
1010 { { "o3" }, "r11" },
1011 { { "o4" }, "r12" },
1012 { { "o5" }, "r13" },
1013 { { "o6", "sp" }, "r14" },
1014 { { "o7" }, "r15" },
1015 { { "l0" }, "r16" },
1016 { { "l1" }, "r17" },
1017 { { "l2" }, "r18" },
1018 { { "l3" }, "r19" },
1019 { { "l4" }, "r20" },
1020 { { "l5" }, "r21" },
1021 { { "l6" }, "r22" },
1022 { { "l7" }, "r23" },
1023 { { "i0" }, "r24" },
1024 { { "i1" }, "r25" },
1025 { { "i2" }, "r26" },
1026 { { "i3" }, "r27" },
1027 { { "i4" }, "r28" },
1028 { { "i5" }, "r29" },
1029 { { "i6", "fp" }, "r30" },
1030 { { "i7" }, "r31" },
1031};
1032
1033void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
1034 unsigned &NumAliases) const {
1035 Aliases = GCCRegAliases;
1036 NumAliases = llvm::array_lengthof(GCCRegAliases);
1037}
Gabor Greif8a3ff0d2008-02-21 16:29:08 +00001038} // end anonymous namespace.
1039
Eli Friedmanff158dd2008-08-20 07:28:14 +00001040namespace {
1041class SolarisSparcV8TargetInfo : public SparcV8TargetInfo {
1042public:
1043 SolarisSparcV8TargetInfo(const std::string& triple) :
Eli Friedman7cca0982008-11-02 02:43:55 +00001044 SparcV8TargetInfo(triple) {
1045 SizeType = UnsignedInt;
1046 PtrDiffType = SignedInt;
1047 }
Eli Friedmanff158dd2008-08-20 07:28:14 +00001048
Chris Lattner79682402009-03-20 15:52:06 +00001049 virtual void getTargetDefines(const LangOptions &Opts,
1050 std::vector<char> &Defines) const {
1051 SparcV8TargetInfo::getTargetDefines(Opts, Defines);
Eli Friedmanff158dd2008-08-20 07:28:14 +00001052 getSolarisDefines(Defines);
1053 }
1054};
1055} // end anonymous namespace.
Chris Lattner4b009652007-07-25 00:24:17 +00001056
Chris Lattner85970f32008-05-08 05:58:21 +00001057namespace {
1058 class PIC16TargetInfo : public TargetInfo{
1059 public:
1060 PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) {
Sanjiv Guptafa451432008-10-31 09:52:39 +00001061 IntWidth = 16;
1062 LongWidth = LongLongWidth = 32;
1063 PointerWidth = 16;
1064 IntAlign = 8;
1065 LongAlign = LongLongAlign = 8;
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001066 PointerAlign = 8;
Sanjiv Guptafa451432008-10-31 09:52:39 +00001067 SizeType = UnsignedInt;
1068 IntMaxType = SignedLong;
1069 UIntMaxType = UnsignedLong;
Chris Lattnerd9ef7242009-02-13 22:28:55 +00001070 IntPtrType = SignedShort;
Eli Friedman7cca0982008-11-02 02:43:55 +00001071 PtrDiffType = SignedInt;
Sanjiv Guptaebd8f0f2008-08-18 10:05:22 +00001072 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8";
Chris Lattner85970f32008-05-08 05:58:21 +00001073 }
Chris Lattner727b3c42008-05-09 06:08:39 +00001074 virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; }
1075 virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; }
Chris Lattner79682402009-03-20 15:52:06 +00001076 virtual void getTargetDefines(const LangOptions &Opts,
1077 std::vector<char> &Defines) const {
Chris Lattner85970f32008-05-08 05:58:21 +00001078 Define(Defines, "__pic16");
1079 }
1080 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1081 unsigned &NumRecords) const {}
1082 virtual const char *getVAListDeclaration() const { return "";}
1083 virtual const char *getClobbers() const {return "";}
1084 virtual const char *getTargetPrefix() const {return "";}
1085 virtual void getGCCRegNames(const char * const *&Names,
1086 unsigned &NumNames) const {}
Anders Carlsson36834a72009-02-28 17:11:49 +00001087 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattner85970f32008-05-08 05:58:21 +00001088 TargetInfo::ConstraintInfo &info) const {
1089 return true;
1090 }
1091 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1092 unsigned &NumAliases) const {}
1093 virtual bool useGlobalsForAutomaticVariables() const {return true;}
1094 };
1095}
1096
Chris Lattner4b009652007-07-25 00:24:17 +00001097//===----------------------------------------------------------------------===//
1098// Driver code
1099//===----------------------------------------------------------------------===//
1100
Ted Kremenekb97d7672007-12-04 17:07:35 +00001101static inline bool IsX86(const std::string& TT) {
Ted Kremenek40499482007-12-03 22:06:55 +00001102 return (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' &&
1103 TT[4] == '-' && TT[1] - '3' < 6);
1104}
1105
Chris Lattnerfc457002008-03-05 01:18:20 +00001106/// CreateTargetInfo - Return the target info object for the specified target
1107/// triple.
1108TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
Eli Friedman2b161652008-08-21 00:13:15 +00001109 // OS detection; this isn't really anywhere near complete.
1110 // Additions and corrections are welcome.
1111 bool isDarwin = T.find("-darwin") != std::string::npos;
Chris Lattnerd4faca42008-08-23 18:23:14 +00001112 bool isDragonFly = T.find("-dragonfly") != std::string::npos;
Chris Lattner98cb2a22008-10-16 17:04:31 +00001113 bool isFreeBSD = T.find("-freebsd") != std::string::npos;
Eli Friedman2b161652008-08-21 00:13:15 +00001114 bool isSolaris = T.find("-solaris") != std::string::npos;
1115 bool isLinux = T.find("-linux") != std::string::npos;
1116 bool isWindows = T.find("-windows") != std::string::npos ||
1117 T.find("-win32") != std::string::npos ||
1118 T.find("-mingw") != std::string::npos;
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001119
Eli Friedman2b161652008-08-21 00:13:15 +00001120 if (T.find("ppc-") == 0 || T.find("powerpc-") == 0) {
1121 if (isDarwin)
1122 return new DarwinPPCTargetInfo(T);
1123 return new PPC32TargetInfo(T);
1124 }
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001125
Eli Friedman2b161652008-08-21 00:13:15 +00001126 if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0) {
1127 if (isDarwin)
1128 return new DarwinPPC64TargetInfo(T);
1129 return new PPC64TargetInfo(T);
1130 }
Chris Lattner9fd73612008-04-21 18:56:49 +00001131
Eli Friedman2b161652008-08-21 00:13:15 +00001132 if (T.find("armv6-") == 0 || T.find("arm-") == 0) {
1133 if (isDarwin)
1134 return new DarwinARMTargetInfo(T);
Daniel Dunbar88fd9942009-03-23 16:09:04 +00001135 if (isFreeBSD)
1136 return new FreeBSDARMTargetInfo(T);
Eli Friedman2b161652008-08-21 00:13:15 +00001137 return new ARMTargetInfo(T);
1138 }
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001139
Eli Friedman2b161652008-08-21 00:13:15 +00001140 if (T.find("sparc-") == 0) {
1141 if (isSolaris)
1142 return new SolarisSparcV8TargetInfo(T);
1143 return new SparcV8TargetInfo(T);
1144 }
1145
Chris Lattner273dce42009-02-20 17:04:14 +00001146 if (T.find("x86_64-") == 0 || T.find("amd64-") == 0) {
Eli Friedman2b161652008-08-21 00:13:15 +00001147 if (isDarwin)
1148 return new DarwinX86_64TargetInfo(T);
Daniel Dunbare5a80f22008-09-23 17:37:57 +00001149 if (isLinux)
1150 return new LinuxX86_64TargetInfo(T);
Chris Lattner98cb2a22008-10-16 17:04:31 +00001151 if (isFreeBSD)
1152 return new FreeBSDX86_64TargetInfo(T);
Eli Friedman2b161652008-08-21 00:13:15 +00001153 return new X86_64TargetInfo(T);
1154 }
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001155
Chris Lattner85970f32008-05-08 05:58:21 +00001156 if (T.find("pic16-") == 0)
1157 return new PIC16TargetInfo(T);
1158
Eli Friedman2b161652008-08-21 00:13:15 +00001159 if (IsX86(T)) {
1160 if (isDarwin)
1161 return new DarwinI386TargetInfo(T);
Eli Friedman5fb0a022008-08-21 00:24:02 +00001162 if (isLinux)
1163 return new LinuxX86_32TargetInfo(T);
Chris Lattnerd4faca42008-08-23 18:23:14 +00001164 if (isDragonFly)
1165 return new DragonFlyX86_32TargetInfo(T);
Chris Lattner98cb2a22008-10-16 17:04:31 +00001166 if (isFreeBSD)
1167 return new FreeBSDX86_32TargetInfo(T);
Eli Friedman23cb7912008-08-21 01:40:19 +00001168 if (isWindows)
1169 return new WindowsX86_32TargetInfo(T);
Eli Friedman2b161652008-08-21 00:13:15 +00001170 return new X86_32TargetInfo(T);
1171 }
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001172
Chris Lattnerfc457002008-03-05 01:18:20 +00001173 return NULL;
Chris Lattner4b009652007-07-25 00:24:17 +00001174}
Ted Kremenekd507bab2008-03-04 17:47:18 +00001175