blob: 979b5fe21b32e39164776b7f2fb88a07b0535fcf [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 Lattner4b009652007-07-25 00:24:17 +000022using namespace clang;
23
Chris Lattner4b009652007-07-25 00:24:17 +000024//===----------------------------------------------------------------------===//
25// Common code shared among targets.
26//===----------------------------------------------------------------------===//
27
Chris Lattner0db667a2007-10-06 06:57:34 +000028static void Define(std::vector<char> &Buf, const char *Macro,
29 const char *Val = "1") {
30 const char *Def = "#define ";
31 Buf.insert(Buf.end(), Def, Def+strlen(Def));
32 Buf.insert(Buf.end(), Macro, Macro+strlen(Macro));
33 Buf.push_back(' ');
34 Buf.insert(Buf.end(), Val, Val+strlen(Val));
35 Buf.push_back('\n');
36}
37
Chris Lattnerbd00eb82008-10-05 21:50:58 +000038//===----------------------------------------------------------------------===//
39// Defines specific to certain operating systems.
40//===----------------------------------------------------------------------===//
41
Eli Friedmanff158dd2008-08-20 07:28:14 +000042static void getSolarisDefines(std::vector<char> &Defs) {
43 Define(Defs, "__SUN__");
44 Define(Defs, "__SOLARIS__");
45}
Chris Lattner4b009652007-07-25 00:24:17 +000046
Chris Lattnerab81f162009-03-20 15:55:34 +000047static void getFreeBSDDefines(const LangOptions &Opts, bool is64Bit,
48 const char *Triple, std::vector<char> &Defs) {
Chris Lattner98cb2a22008-10-16 17:04:31 +000049 // FreeBSD defines; list based off of gcc output
50
51 const char *FreeBSD = strstr(Triple, "-freebsd");
52 FreeBSD += strlen("-freebsd");
53 char release[] = "X";
54 release[0] = FreeBSD[0];
55 char version[] = "X00001";
56 version[0] = FreeBSD[0];
57
58 Define(Defs, "__FreeBSD__", release);
59 Define(Defs, "__FreeBSD_cc_version", version);
60 Define(Defs, "__KPRINTF_ATTRIBUTE__");
61 Define(Defs, "unix");
Anton Korobeynikovfb820852009-02-14 16:42:50 +000062 Define(Defs, "__ELF__", "1");
Chris Lattner98cb2a22008-10-16 17:04:31 +000063 if (is64Bit) {
64 Define(Defs, "__LP64__");
65 }
66}
67
Chris Lattnerab81f162009-03-20 15:55:34 +000068static void getDragonFlyDefines(const LangOptions &Opts,
69 std::vector<char> &Defs) {
Chris Lattnerbd00eb82008-10-05 21:50:58 +000070 // DragonFly defines; list based off of gcc output
71 Define(Defs, "__DragonFly__");
72 Define(Defs, "__DragonFly_cc_version", "100001");
73 Define(Defs, "__ELF__");
74 Define(Defs, "__KPRINTF_ATTRIBUTE__");
75 Define(Defs, "__tune_i386__");
76 Define(Defs, "unix");
77 Define(Defs, "__unix");
78 Define(Defs, "__unix__");
79}
80
Chris Lattnerab81f162009-03-20 15:55:34 +000081static void getLinuxDefines(const LangOptions &Opts, std::vector<char> &Defs) {
Chris Lattnerbd00eb82008-10-05 21:50:58 +000082 // Linux defines; list based off of gcc output
83 Define(Defs, "__unix__");
84 Define(Defs, "__unix");
85 Define(Defs, "unix");
86 Define(Defs, "__linux__");
87 Define(Defs, "__linux");
88 Define(Defs, "linux");
89 Define(Defs, "__gnu_linux__");
Argiris Kirtzidis99de9532009-02-14 15:02:45 +000090 Define(Defs, "__ELF__", "1");
Chris Lattnerbd00eb82008-10-05 21:50:58 +000091}
92
Chris Lattnerd7bc88b2008-12-04 23:20:07 +000093/// getDarwinNumber - Parse the 'darwin number' out of the specific targe
94/// triple. For example, if we have darwin8.5 return 8,5,4. If any entry is
95/// not defined, return 0's. Return true if we have -darwin in the string or
96/// false otherwise.
97static bool getDarwinNumber(const char *Triple, unsigned &Maj, unsigned &Min) {
98 Maj = Min = 0;
99 const char *Darwin = strstr(Triple, "-darwin");
100 if (Darwin == 0) return false;
101
102 Darwin += strlen("-darwin");
103 if (Darwin[0] < '0' || Darwin[0] > '9')
104 return true;
105
106 Maj = Darwin[0]-'0';
107 ++Darwin;
108
109 // Handle "darwin11".
110 if (Maj == 1 && Darwin[0] >= '0' && Darwin[0] <= '9') {
111 Maj = 10+Darwin[0]-'0';
112 ++Darwin;
113 }
114
115 // Handle minor version: 10.4.9 -> darwin8.9 -> "1049"
116 if (Darwin[0] == '.' && Darwin[1] >= '0' && Darwin[1] <= '9' &&
117 Darwin[2] == '\0')
118 Min = Darwin[1]-'0';
119
120 return true;
121}
122
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000123static void getDarwinDefines(std::vector<char> &Defs, const char *Triple) {
Eli Friedman872996c2008-08-20 02:34:37 +0000124 Define(Defs, "__APPLE__");
125 Define(Defs, "__MACH__");
Chris Lattner8405e092009-02-05 07:19:24 +0000126 Define(Defs, "OBJC_NEW_PROPERTIES");
127
128 // FIXME: OBJC_ZEROCOST_EXCEPTIONS when using zero cost eh.
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000129
130 // Figure out which "darwin number" the target triple is. "darwin9" -> 10.5.
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000131 unsigned Maj, Min;
132 if (getDarwinNumber(Triple, Maj, Min)) {
Chris Lattnerd376f6d2008-09-30 20:30:12 +0000133 char DarwinStr[] = "1000";
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000134 if (Maj >= 4 && Maj <= 13) { // 10.0-10.9
135 // darwin7 -> 1030, darwin8 -> 1040, darwin9 -> 1050, etc.
136 DarwinStr[2] = '0' + Maj-4;
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000137 }
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000138
139 // Handle minor version: 10.4.9 -> darwin8.9 -> "1049"
140 DarwinStr[3] = Min+'0';
Chris Lattnerd376f6d2008-09-30 20:30:12 +0000141 Define(Defs, "__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", DarwinStr);
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000142 }
Eli Friedman872996c2008-08-20 02:34:37 +0000143}
Chris Lattner4b009652007-07-25 00:24:17 +0000144
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000145/// GetDarwinLanguageOptions - Set the default language options for darwin.
146static void GetDarwinLanguageOptions(LangOptions &Opts,
147 const char *Triple) {
148 Opts.NeXTRuntime = true;
149
150 unsigned Maj, Min;
151 if (!getDarwinNumber(Triple, Maj, Min))
152 return;
153
154 // Blocks default to on for 10.6 (darwin10) and beyond.
Fariborz Jahaniand09b9f72009-02-12 17:54:33 +0000155 // As does nonfragile-abi for 64bit mode
Fariborz Jahanian27f58962009-02-24 23:34:44 +0000156 if (Maj > 9)
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000157 Opts.Blocks = 1;
Fariborz Jahanian27f58962009-02-24 23:34:44 +0000158
Fariborz Jahanian72efecb2009-02-24 23:38:42 +0000159 if (Maj >= 9 && Opts.ObjC1 && !strncmp(Triple, "x86_64", 6))
160 Opts.ObjCNonFragileABI = 1;
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000161}
162
163
Chris Lattnerbd00eb82008-10-05 21:50:58 +0000164//===----------------------------------------------------------------------===//
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000165// Specific target implementations.
166//===----------------------------------------------------------------------===//
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000167
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000168namespace {
169// PPC abstract base class
170class PPCTargetInfo : public TargetInfo {
171 static const Builtin::Info BuiltinInfo[];
172 static const char * const GCCRegNames[];
173 static const TargetInfo::GCCRegAlias GCCRegAliases[];
174
175public:
176 PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {
177 CharIsSigned = false;
178 }
179 virtual void getTargetBuiltins(const Builtin::Info *&Records,
180 unsigned &NumRecords) const {
Chris Lattner4b009652007-07-25 00:24:17 +0000181 Records = BuiltinInfo;
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000182 NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner4b009652007-07-25 00:24:17 +0000183 }
Chris Lattnerbef1d722009-03-02 22:27:17 +0000184
Chris Lattner79682402009-03-20 15:52:06 +0000185 virtual void getTargetDefines(const LangOptions &Opts,
186 std::vector<char> &Defines) const;
Chris Lattnerbef1d722009-03-02 22:27:17 +0000187
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000188 virtual const char *getVAListDeclaration() const {
Chris Lattnera07708f2008-10-27 01:11:29 +0000189 return "typedef char* __builtin_va_list;";
190 // This is the right definition for ABI/V4: System V.4/eabi.
191 /*return "typedef struct __va_list_tag {"
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000192 " unsigned char gpr;"
193 " unsigned char fpr;"
194 " unsigned short reserved;"
195 " void* overflow_arg_area;"
196 " void* reg_save_area;"
Chris Lattnera07708f2008-10-27 01:11:29 +0000197 "} __builtin_va_list[1];";*/
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000198 }
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000199 virtual const char *getTargetPrefix() const {
200 return "ppc";
Anders Carlsson4ce42302007-11-27 04:11:28 +0000201 }
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000202 virtual void getGCCRegNames(const char * const *&Names,
203 unsigned &NumNames) const;
204 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
205 unsigned &NumAliases) const;
Anders Carlsson36834a72009-02-28 17:11:49 +0000206 virtual bool validateAsmConstraint(const char *&Name,
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000207 TargetInfo::ConstraintInfo &info) const {
Anders Carlsson36834a72009-02-28 17:11:49 +0000208 switch (*Name) {
Anders Carlsson4ce42302007-11-27 04:11:28 +0000209 default: return false;
210 case 'O': // Zero
211 return true;
212 case 'b': // Base register
213 case 'f': // Floating point register
214 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
215 return true;
216 }
217 }
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000218 virtual const char *getClobbers() const {
219 return "";
Anders Carlsson4ce42302007-11-27 04:11:28 +0000220 }
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000221};
Anders Carlsson4ce42302007-11-27 04:11:28 +0000222
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000223const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
Douglas Gregor2e8a7aa2009-02-16 21:58:21 +0000224#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
225#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000226#include "clang/AST/PPCBuiltins.def"
227};
Chris Lattnerbef1d722009-03-02 22:27:17 +0000228
229
230/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
231/// #defines that are not tied to a specific subtarget.
Chris Lattner79682402009-03-20 15:52:06 +0000232void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
233 std::vector<char> &Defs) const {
Chris Lattnerbef1d722009-03-02 22:27:17 +0000234 // Target identification.
235 Define(Defs, "__ppc__");
236 Define(Defs, "_ARCH_PPC");
237 Define(Defs, "__POWERPC__");
238 if (PointerWidth == 64) {
239 Define(Defs, "_ARCH_PPC64");
240 Define(Defs, "_LP64");
241 Define(Defs, "__LP64__");
242 Define(Defs, "__ppc64__");
243 } else {
244 Define(Defs, "__ppc__");
245 }
246
247 // Target properties.
248 Define(Defs, "_BIG_ENDIAN");
249 Define(Defs, "__BIG_ENDIAN__");
250
251 // Subtarget options.
252 Define(Defs, "__NATURAL_ALIGNMENT__");
253 Define(Defs, "__REGISTER_PREFIX__", "");
254
255 // FIXME: Should be controlled by command line option.
256 Define(Defs, "__LONG_DOUBLE_128__");
257}
258
Chris Lattner9fd73612008-04-21 18:56:49 +0000259
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000260const char * const PPCTargetInfo::GCCRegNames[] = {
261 "0", "1", "2", "3", "4", "5", "6", "7",
262 "8", "9", "10", "11", "12", "13", "14", "15",
263 "16", "17", "18", "19", "20", "21", "22", "23",
264 "24", "25", "26", "27", "28", "29", "30", "31",
265 "0", "1", "2", "3", "4", "5", "6", "7",
266 "8", "9", "10", "11", "12", "13", "14", "15",
267 "16", "17", "18", "19", "20", "21", "22", "23",
268 "24", "25", "26", "27", "28", "29", "30", "31",
269 "mq", "lr", "ctr", "ap",
270 "0", "1", "2", "3", "4", "5", "6", "7",
271 "xer",
272 "0", "1", "2", "3", "4", "5", "6", "7",
273 "8", "9", "10", "11", "12", "13", "14", "15",
274 "16", "17", "18", "19", "20", "21", "22", "23",
275 "24", "25", "26", "27", "28", "29", "30", "31",
276 "vrsave", "vscr",
277 "spe_acc", "spefscr",
278 "sfp"
279};
Chris Lattner4b009652007-07-25 00:24:17 +0000280
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000281void PPCTargetInfo::getGCCRegNames(const char * const *&Names,
282 unsigned &NumNames) const {
283 Names = GCCRegNames;
284 NumNames = llvm::array_lengthof(GCCRegNames);
285}
Chris Lattner4b009652007-07-25 00:24:17 +0000286
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000287const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
288 // While some of these aliases do map to different registers
289 // they still share the same register name.
290 { { "cc", "cr0", "fr0", "r0", "v0"}, "0" },
291 { { "cr1", "fr1", "r1", "sp", "v1"}, "1" },
292 { { "cr2", "fr2", "r2", "toc", "v2"}, "2" },
293 { { "cr3", "fr3", "r3", "v3"}, "3" },
294 { { "cr4", "fr4", "r4", "v4"}, "4" },
295 { { "cr5", "fr5", "r5", "v5"}, "5" },
296 { { "cr6", "fr6", "r6", "v6"}, "6" },
297 { { "cr7", "fr7", "r7", "v7"}, "7" },
298 { { "fr8", "r8", "v8"}, "8" },
299 { { "fr9", "r9", "v9"}, "9" },
300 { { "fr10", "r10", "v10"}, "10" },
301 { { "fr11", "r11", "v11"}, "11" },
302 { { "fr12", "r12", "v12"}, "12" },
303 { { "fr13", "r13", "v13"}, "13" },
304 { { "fr14", "r14", "v14"}, "14" },
305 { { "fr15", "r15", "v15"}, "15" },
306 { { "fr16", "r16", "v16"}, "16" },
307 { { "fr17", "r17", "v17"}, "17" },
308 { { "fr18", "r18", "v18"}, "18" },
309 { { "fr19", "r19", "v19"}, "19" },
310 { { "fr20", "r20", "v20"}, "20" },
311 { { "fr21", "r21", "v21"}, "21" },
312 { { "fr22", "r22", "v22"}, "22" },
313 { { "fr23", "r23", "v23"}, "23" },
314 { { "fr24", "r24", "v24"}, "24" },
315 { { "fr25", "r25", "v25"}, "25" },
316 { { "fr26", "r26", "v26"}, "26" },
317 { { "fr27", "r27", "v27"}, "27" },
318 { { "fr28", "r28", "v28"}, "28" },
319 { { "fr29", "r29", "v29"}, "29" },
320 { { "fr30", "r30", "v30"}, "30" },
321 { { "fr31", "r31", "v31"}, "31" },
322};
323
324void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
325 unsigned &NumAliases) const {
326 Aliases = GCCRegAliases;
327 NumAliases = llvm::array_lengthof(GCCRegAliases);
328}
329} // end anonymous namespace.
Chris Lattner4b009652007-07-25 00:24:17 +0000330
331namespace {
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000332class PPC32TargetInfo : public PPCTargetInfo {
Chris Lattner4b009652007-07-25 00:24:17 +0000333public:
Eli Friedman2b161652008-08-21 00:13:15 +0000334 PPC32TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
335 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
336 "i64:64:64-f32:32:32-f64:64:64-v128:128:128";
337 }
Chris Lattner4b009652007-07-25 00:24:17 +0000338};
339} // end anonymous namespace.
340
341namespace {
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000342class PPC64TargetInfo : public PPCTargetInfo {
Chris Lattner4b009652007-07-25 00:24:17 +0000343public:
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000344 PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
Chris Lattnere5fde952008-05-09 06:17:04 +0000345 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedman2b161652008-08-21 00:13:15 +0000346 DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
347 "i64:64:64-f32:32:32-f64:64:64-v128:128:128";
Chris Lattnere5fde952008-05-09 06:17:04 +0000348 }
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000349};
350} // end anonymous namespace.
351
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000352
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000353namespace {
354class DarwinPPCTargetInfo : public PPC32TargetInfo {
355public:
356 DarwinPPCTargetInfo(const std::string& triple) : PPC32TargetInfo(triple) {}
Chris Lattner79682402009-03-20 15:52:06 +0000357 virtual void getTargetDefines(const LangOptions &Opts,
358 std::vector<char> &Defines) const {
359 PPC32TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000360 getDarwinDefines(Defines, getTargetTriple());
Chris Lattner4b009652007-07-25 00:24:17 +0000361 }
Daniel Dunbar34542952008-08-23 08:43:39 +0000362
Chris Lattnerddae7102008-12-04 22:54:33 +0000363 /// getDefaultLangOptions - Allow the target to specify default settings for
364 /// various language options. These may be overridden by command line
365 /// options.
366 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000367 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattnerddae7102008-12-04 22:54:33 +0000368 }
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000369};
370} // end anonymous namespace.
371
372namespace {
373class DarwinPPC64TargetInfo : public PPC64TargetInfo {
374public:
375 DarwinPPC64TargetInfo(const std::string& triple) : PPC64TargetInfo(triple) {}
Chris Lattner79682402009-03-20 15:52:06 +0000376 virtual void getTargetDefines(const LangOptions &Opts,
377 std::vector<char> &Defines) const {
378 PPC64TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000379 getDarwinDefines(Defines, getTargetTriple());
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000380 }
Daniel Dunbar34542952008-08-23 08:43:39 +0000381
Chris Lattnerddae7102008-12-04 22:54:33 +0000382 /// getDefaultLangOptions - Allow the target to specify default settings for
383 /// various language options. These may be overridden by command line
384 /// options.
385 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000386 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattnerddae7102008-12-04 22:54:33 +0000387 }
Chris Lattner4b009652007-07-25 00:24:17 +0000388};
389} // end anonymous namespace.
390
391namespace {
Eli Friedman872996c2008-08-20 02:34:37 +0000392// Namespace for x86 abstract base class
393const Builtin::Info BuiltinInfo[] = {
Douglas Gregor2e8a7aa2009-02-16 21:58:21 +0000394#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
395#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
Eli Friedman872996c2008-08-20 02:34:37 +0000396#include "clang/AST/X86Builtins.def"
397};
Eli Friedman0b7b1cb2008-05-20 14:21:01 +0000398
Eli Friedman872996c2008-08-20 02:34:37 +0000399const char *GCCRegNames[] = {
400 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
401 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
402 "argp", "flags", "fspr", "dirflag", "frame",
403 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
404 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
405 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
406 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
407};
408
409const TargetInfo::GCCRegAlias GCCRegAliases[] = {
410 { { "al", "ah", "eax", "rax" }, "ax" },
411 { { "bl", "bh", "ebx", "rbx" }, "bx" },
412 { { "cl", "ch", "ecx", "rcx" }, "cx" },
413 { { "dl", "dh", "edx", "rdx" }, "dx" },
414 { { "esi", "rsi" }, "si" },
415 { { "edi", "rdi" }, "di" },
416 { { "esp", "rsp" }, "sp" },
417 { { "ebp", "rbp" }, "bp" },
418};
419
420// X86 target abstract base class; x86-32 and x86-64 are very close, so
421// most of the implementation can be shared.
422class X86TargetInfo : public TargetInfo {
Chris Lattner715fe4c2009-03-02 22:40:39 +0000423 enum X86SSEEnum {
424 NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42
425 } SSELevel;
Eli Friedman872996c2008-08-20 02:34:37 +0000426public:
Chris Lattner715fe4c2009-03-02 22:40:39 +0000427 X86TargetInfo(const std::string& triple)
Chris Lattnerf6790a82009-03-03 19:56:18 +0000428 : TargetInfo(triple),
429 // FIXME: hard coding to SSE2 for now. This should change to NoMMXSSE so
430 // that the driver controls this.
431 SSELevel(SSE2) {
Eli Friedman872996c2008-08-20 02:34:37 +0000432 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
Chris Lattner4b009652007-07-25 00:24:17 +0000433 }
434 virtual void getTargetBuiltins(const Builtin::Info *&Records,
435 unsigned &NumRecords) const {
Eli Friedman872996c2008-08-20 02:34:37 +0000436 Records = BuiltinInfo;
437 NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner4b009652007-07-25 00:24:17 +0000438 }
Anders Carlsson333052c2007-12-08 19:32:57 +0000439 virtual const char *getTargetPrefix() const {
Eli Friedman872996c2008-08-20 02:34:37 +0000440 return "x86";
Anders Carlsson333052c2007-12-08 19:32:57 +0000441 }
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000442 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedman872996c2008-08-20 02:34:37 +0000443 unsigned &NumNames) const {
444 Names = GCCRegNames;
445 NumNames = llvm::array_lengthof(GCCRegNames);
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000446 }
447 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
448 unsigned &NumAliases) const {
Eli Friedman872996c2008-08-20 02:34:37 +0000449 Aliases = GCCRegAliases;
450 NumAliases = llvm::array_lengthof(GCCRegAliases);
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000451 }
Anders Carlsson36834a72009-02-28 17:11:49 +0000452 virtual bool validateAsmConstraint(const char *&Name,
Eli Friedman872996c2008-08-20 02:34:37 +0000453 TargetInfo::ConstraintInfo &info) const;
454 virtual std::string convertConstraint(const char Constraint) const;
Anders Carlsson4ce42302007-11-27 04:11:28 +0000455 virtual const char *getClobbers() const {
Eli Friedman872996c2008-08-20 02:34:37 +0000456 return "~{dirflag},~{fpsr},~{flags}";
457 }
Chris Lattner79682402009-03-20 15:52:06 +0000458 virtual void getTargetDefines(const LangOptions &Opts,
459 std::vector<char> &Defines) const;
Chris Lattner7d6220c2009-03-02 22:20:04 +0000460
Chris Lattnerf6790a82009-03-03 19:56:18 +0000461 virtual int HandleTargetFeatures(std::string *StrArray, unsigned NumStrs,
462 std::string &ErrorReason);
Chris Lattner4b009652007-07-25 00:24:17 +0000463};
Chris Lattner7d6220c2009-03-02 22:20:04 +0000464
465/// HandleTargetOptions - Handle target-specific options like -msse2 and
466/// friends. An array of arguments is passed in: if they are all valid, this
467/// should handle them and return -1. If there is an error, the index of the
468/// invalid argument should be returned along with an optional error string.
Chris Lattnerf6790a82009-03-03 19:56:18 +0000469int X86TargetInfo::HandleTargetFeatures(std::string *StrArray, unsigned NumStrs,
470 std::string &ErrorReason) {
471 for (unsigned i = 0; i != NumStrs; ++i) {
472 const std::string &Feature = StrArray[i];
473 if (Feature.size() < 2) return i;
474 // Ignore explicitly disabled features.
475 if (Feature[0] == '-') continue;
476
477 // Feature strings are of the form "+feature".
478 if (Feature[0] != '+') return i;
479
480 // The set of supported subtarget features is defined in
481 // lib/Target/X86/X86.td. Here we recognize and map onto our internal
482 // state.
483 if (Feature == "+mmx")
484 SSELevel = std::max(SSELevel, MMX);
485 else if (Feature == "+sse")
486 SSELevel = std::max(SSELevel, SSE1);
487 else if (Feature == "+sse2")
488 SSELevel = std::max(SSELevel, SSE2);
489 else if (Feature == "+sse3")
490 SSELevel = std::max(SSELevel, SSE3);
491 else if (Feature == "+ssse3")
492 SSELevel = std::max(SSELevel, SSSE3);
493 else if (Feature == "+sse41")
494 SSELevel = std::max(SSELevel, SSE41);
495 else if (Feature == "+sse42")
496 SSELevel = std::max(SSELevel, SSE42);
497 else if (Feature == "+64bit" || Feature == "+slow-bt-mem")
498 // Ignore these features.
499 continue;
500 else
501 return i;
502 }
503 return -1;
Chris Lattner7d6220c2009-03-02 22:20:04 +0000504}
Chris Lattnerbef1d722009-03-02 22:27:17 +0000505
506/// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines
507/// that are not tied to a specific subtarget.
Chris Lattner79682402009-03-20 15:52:06 +0000508void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
509 std::vector<char> &Defs) const {
Chris Lattnerbef1d722009-03-02 22:27:17 +0000510 // Target identification.
511 if (PointerWidth == 64) {
512 Define(Defs, "_LP64");
513 Define(Defs, "__LP64__");
514 Define(Defs, "__amd64__");
515 Define(Defs, "__amd64");
516 Define(Defs, "__x86_64");
517 Define(Defs, "__x86_64__");
518 Define(Defs, "__SSE3__");
519 } else {
520 Define(Defs, "__i386__");
521 Define(Defs, "__i386");
522 Define(Defs, "i386");
523 }
524
525 // Target properties.
526 Define(Defs, "__LITTLE_ENDIAN__");
527
528 // Subtarget options.
529 Define(Defs, "__nocona");
530 Define(Defs, "__nocona__");
531 Define(Defs, "__tune_nocona__");
Chris Lattnerbef1d722009-03-02 22:27:17 +0000532 Define(Defs, "__REGISTER_PREFIX__", "");
Chris Lattner715fe4c2009-03-02 22:40:39 +0000533
534 // Each case falls through to the previous one here.
535 switch (SSELevel) {
536 case SSE42:
537 Define(Defs, "__SSE4_2__");
538 case SSE41:
539 Define(Defs, "__SSE4_1__");
540 case SSSE3:
541 Define(Defs, "__SSSE3__");
542 case SSE3:
543 Define(Defs, "__SSE3__");
544 case SSE2:
545 Define(Defs, "__SSE2__");
546 Define(Defs, "__SSE2_MATH__"); // -mfp-math=sse always implied.
547 case SSE1:
548 Define(Defs, "__SSE__");
549 Define(Defs, "__SSE_MATH__"); // -mfp-math=sse always implied.
550 case MMX:
551 Define(Defs, "__MMX__");
552 case NoMMXSSE:
553 break;
554 }
Chris Lattnerbef1d722009-03-02 22:27:17 +0000555}
556
Eli Friedman872996c2008-08-20 02:34:37 +0000557
558bool
Anders Carlsson36834a72009-02-28 17:11:49 +0000559X86TargetInfo::validateAsmConstraint(const char *&Name,
Eli Friedman872996c2008-08-20 02:34:37 +0000560 TargetInfo::ConstraintInfo &info) const {
Anders Carlsson36834a72009-02-28 17:11:49 +0000561 switch (*Name) {
Eli Friedman872996c2008-08-20 02:34:37 +0000562 default: return false;
563 case 'a': // eax.
564 case 'b': // ebx.
565 case 'c': // ecx.
566 case 'd': // edx.
567 case 'S': // esi.
568 case 'D': // edi.
569 case 'A': // edx:eax.
570 case 't': // top of floating point stack.
571 case 'u': // second from top of floating point stack.
572 case 'q': // Any register accessible as [r]l: a, b, c, and d.
Anders Carlsson2285e622008-10-06 00:41:45 +0000573 case 'y': // Any MMX register.
Anders Carlssond2459f92008-10-06 19:17:39 +0000574 case 'x': // Any SSE register.
Eli Friedman872996c2008-08-20 02:34:37 +0000575 case 'Q': // Any register accessible as [r]h: a, b, c, and d.
Anders Carlssonff235da2009-01-24 18:03:09 +0000576 case 'e': // 32-bit signed integer constant for use with zero-extending
577 // x86_64 instructions.
578 case 'Z': // 32-bit unsigned integer constant for use with zero-extending
579 // x86_64 instructions.
Eli Friedman872996c2008-08-20 02:34:37 +0000580 case 'N': // unsigned 8-bit integer constant for use with in and out
581 // instructions.
582 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
583 return true;
584 }
585}
586
587std::string
588X86TargetInfo::convertConstraint(const char Constraint) const {
589 switch (Constraint) {
590 case 'a': return std::string("{ax}");
591 case 'b': return std::string("{bx}");
592 case 'c': return std::string("{cx}");
593 case 'd': return std::string("{dx}");
594 case 'S': return std::string("{si}");
595 case 'D': return std::string("{di}");
596 case 't': // top of floating point stack.
597 return std::string("{st}");
598 case 'u': // second from top of floating point stack.
599 return std::string("{st(1)}"); // second from top of floating point stack.
600 default:
601 return std::string(1, Constraint);
602 }
603}
Eli Friedman872996c2008-08-20 02:34:37 +0000604} // end anonymous namespace
Chris Lattner4b009652007-07-25 00:24:17 +0000605
606namespace {
Eli Friedman872996c2008-08-20 02:34:37 +0000607// X86-32 generic target
608class X86_32TargetInfo : public X86TargetInfo {
Chris Lattner4b009652007-07-25 00:24:17 +0000609public:
Eli Friedman872996c2008-08-20 02:34:37 +0000610 X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
611 DoubleAlign = LongLongAlign = 32;
612 LongDoubleWidth = 96;
613 LongDoubleAlign = 32;
Eli Friedman2b161652008-08-21 00:13:15 +0000614 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
615 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
616 "a0:0:64-f80:32:32";
Eli Friedman872996c2008-08-20 02:34:37 +0000617 }
618 virtual const char *getVAListDeclaration() const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000619 return "typedef char* __builtin_va_list;";
Eli Friedman872996c2008-08-20 02:34:37 +0000620 }
Eli Friedman872996c2008-08-20 02:34:37 +0000621};
622} // end anonymous namespace
623
624namespace {
625// x86-32 Darwin (OS X) target
626class DarwinI386TargetInfo : public X86_32TargetInfo {
627public:
628 DarwinI386TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
629 LongDoubleWidth = 128;
630 LongDoubleAlign = 128;
Chris Lattner8405e092009-02-05 07:19:24 +0000631 PtrDiffType = SignedInt;
Eli Friedman2b161652008-08-21 00:13:15 +0000632 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
633 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
634 "a0:0:64-f80:128:128";
Eli Friedman872996c2008-08-20 02:34:37 +0000635 }
Chris Lattner79682402009-03-20 15:52:06 +0000636 virtual void getTargetDefines(const LangOptions &Opts,
637 std::vector<char> &Defines) const {
638 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000639 getDarwinDefines(Defines, getTargetTriple());
Eli Friedman872996c2008-08-20 02:34:37 +0000640 }
Chris Lattnerddae7102008-12-04 22:54:33 +0000641 /// getDefaultLangOptions - Allow the target to specify default settings for
642 /// various language options. These may be overridden by command line
643 /// options.
644 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000645 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattnerddae7102008-12-04 22:54:33 +0000646 }
Eli Friedman872996c2008-08-20 02:34:37 +0000647};
648} // end anonymous namespace
649
650namespace {
Chris Lattner98cb2a22008-10-16 17:04:31 +0000651// x86-32 FreeBSD target
652class FreeBSDX86_32TargetInfo : public X86_32TargetInfo {
653public:
Eli Friedman7cca0982008-11-02 02:43:55 +0000654 FreeBSDX86_32TargetInfo(const std::string& triple) :
655 X86_32TargetInfo(triple) {
656 SizeType = UnsignedInt;
657 PtrDiffType = SignedInt;
Chris Lattner98cb2a22008-10-16 17:04:31 +0000658 }
Chris Lattner79682402009-03-20 15:52:06 +0000659 virtual void getTargetDefines(const LangOptions &Opts,
660 std::vector<char> &Defines) const {
661 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerab81f162009-03-20 15:55:34 +0000662 getFreeBSDDefines(Opts, 0, getTargetTriple(), Defines);
Chris Lattner98cb2a22008-10-16 17:04:31 +0000663 }
664};
665} // end anonymous namespace
666
667namespace {
Chris Lattnerd4faca42008-08-23 18:23:14 +0000668// x86-32 DragonFly target
669class DragonFlyX86_32TargetInfo : public X86_32TargetInfo {
670public:
Eli Friedman7cca0982008-11-02 02:43:55 +0000671 DragonFlyX86_32TargetInfo(const std::string& triple) :
672 X86_32TargetInfo(triple) {
673 SizeType = UnsignedInt;
674 PtrDiffType = SignedInt;
Chris Lattnerd4faca42008-08-23 18:23:14 +0000675 }
Chris Lattner79682402009-03-20 15:52:06 +0000676 virtual void getTargetDefines(const LangOptions &Opts,
677 std::vector<char> &Defines) const {
678 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerab81f162009-03-20 15:55:34 +0000679 getDragonFlyDefines(Opts, Defines);
Chris Lattnerd4faca42008-08-23 18:23:14 +0000680 }
681};
682} // end anonymous namespace
683
684namespace {
Eli Friedman5fb0a022008-08-21 00:24:02 +0000685// x86-32 Linux target
686class LinuxX86_32TargetInfo : public X86_32TargetInfo {
687public:
688 LinuxX86_32TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
Chris Lattner5edfe012008-10-05 19:44:25 +0000689 UserLabelPrefix = "";
Eli Friedman7cca0982008-11-02 02:43:55 +0000690 SizeType = UnsignedInt;
691 PtrDiffType = SignedInt;
Chris Lattnerd9ef7242009-02-13 22:28:55 +0000692 IntPtrType = SignedInt;
Eli Friedman5fb0a022008-08-21 00:24:02 +0000693 }
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 getLinuxDefines(Opts, Defines);
Eli Friedman5fb0a022008-08-21 00:24:02 +0000698 }
699};
700} // end anonymous namespace
701
702namespace {
Eli Friedman23cb7912008-08-21 01:40:19 +0000703// x86-32 Windows target
704class WindowsX86_32TargetInfo : public X86_32TargetInfo {
705public:
706 WindowsX86_32TargetInfo(const std::string& triple)
707 : X86_32TargetInfo(triple) {
708 // FIXME: Fix wchar_t.
709 // FIXME: We should probably enable -fms-extensions by default for
710 // this target.
Eli Friedman7cca0982008-11-02 02:43:55 +0000711 SizeType = UnsignedInt;
712 PtrDiffType = SignedInt;
Eli Friedman23cb7912008-08-21 01:40:19 +0000713 }
Chris Lattner79682402009-03-20 15:52:06 +0000714 virtual void getTargetDefines(const LangOptions &Opts,
715 std::vector<char> &Defines) const {
716 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Eli Friedman23cb7912008-08-21 01:40:19 +0000717 // This list is based off of the the list of things MingW defines
718 Define(Defines, "__WIN32__");
719 Define(Defines, "__WIN32");
720 Define(Defines, "_WIN32");
721 Define(Defines, "WIN32");
722 Define(Defines, "__WINNT__");
723 Define(Defines, "__WINNT");
724 Define(Defines, "WINNT");
Eli Friedman23cb7912008-08-21 01:40:19 +0000725 Define(Defines, "_X86_");
726 Define(Defines, "__MSVCRT__");
727 }
728};
729} // end anonymous namespace
730
731namespace {
Eli Friedman872996c2008-08-20 02:34:37 +0000732// x86-64 generic target
733class X86_64TargetInfo : public X86TargetInfo {
734public:
Chris Lattner79682402009-03-20 15:52:06 +0000735 X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) {
Chris Lattnere5fde952008-05-09 06:17:04 +0000736 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Chris Lattner4dfc45a2009-01-28 06:58:19 +0000737 DoubleAlign = LongLongAlign = 64;
Eli Friedman0b7b1cb2008-05-20 14:21:01 +0000738 LongDoubleWidth = 128;
739 LongDoubleAlign = 128;
Chris Lattnerbfbfbaf2009-02-05 07:32:46 +0000740 IntMaxType = SignedLong;
741 UIntMaxType = UnsignedLong;
742
Eli Friedman2b161652008-08-21 00:13:15 +0000743 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
744 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
745 "a0:0:64-f80:128:128";
Chris Lattner4b009652007-07-25 00:24:17 +0000746 }
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000747 virtual const char *getVAListDeclaration() const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000748 return "typedef struct __va_list_tag {"
749 " unsigned gp_offset;"
750 " unsigned fp_offset;"
751 " void* overflow_arg_area;"
752 " void* reg_save_area;"
753 "} __builtin_va_list[1];";
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000754 }
Eli Friedman872996c2008-08-20 02:34:37 +0000755};
756} // end anonymous namespace
757
758namespace {
Chris Lattner98cb2a22008-10-16 17:04:31 +0000759// x86-64 FreeBSD target
760class FreeBSDX86_64TargetInfo : public X86_64TargetInfo {
761public:
Chris Lattner79682402009-03-20 15:52:06 +0000762 FreeBSDX86_64TargetInfo(const std::string &triple)
763 : X86_64TargetInfo(triple) {}
764 virtual void getTargetDefines(const LangOptions &Opts,
765 std::vector<char> &Defines) const {
766 X86_64TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerab81f162009-03-20 15:55:34 +0000767 getFreeBSDDefines(Opts, 1, getTargetTriple(), Defines);
Chris Lattner98cb2a22008-10-16 17:04:31 +0000768 }
769};
770} // end anonymous namespace
771
772namespace {
Daniel Dunbare5a80f22008-09-23 17:37:57 +0000773// x86-64 Linux target
774class LinuxX86_64TargetInfo : public X86_64TargetInfo {
775public:
776 LinuxX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) {
Chris Lattner5edfe012008-10-05 19:44:25 +0000777 UserLabelPrefix = "";
Daniel Dunbare5a80f22008-09-23 17:37:57 +0000778 }
Chris Lattner79682402009-03-20 15:52:06 +0000779 virtual void getTargetDefines(const LangOptions &Opts,
780 std::vector<char> &Defines) const {
781 X86_64TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerab81f162009-03-20 15:55:34 +0000782 getLinuxDefines(Opts, Defines);
Daniel Dunbare5a80f22008-09-23 17:37:57 +0000783 }
784};
785} // end anonymous namespace
786
787namespace {
Eli Friedman872996c2008-08-20 02:34:37 +0000788// x86-64 Darwin (OS X) target
789class DarwinX86_64TargetInfo : public X86_64TargetInfo {
790public:
791 DarwinX86_64TargetInfo(const std::string& triple) :
792 X86_64TargetInfo(triple) {}
793
Chris Lattner79682402009-03-20 15:52:06 +0000794 virtual void getTargetDefines(const LangOptions &Opts,
795 std::vector<char> &Defines) const {
796 X86_64TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000797 getDarwinDefines(Defines, getTargetTriple());
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000798 }
Daniel Dunbar34542952008-08-23 08:43:39 +0000799
Chris Lattnerddae7102008-12-04 22:54:33 +0000800 /// getDefaultLangOptions - Allow the target to specify default settings for
801 /// various language options. These may be overridden by command line
802 /// options.
803 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000804 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattnerddae7102008-12-04 22:54:33 +0000805 }
Chris Lattner4b009652007-07-25 00:24:17 +0000806};
807} // end anonymous namespace.
808
Chris Lattner9fd73612008-04-21 18:56:49 +0000809namespace {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000810class ARMTargetInfo : public TargetInfo {
Chris Lattner9fd73612008-04-21 18:56:49 +0000811public:
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000812 ARMTargetInfo(const std::string& triple) : TargetInfo(triple) {
813 // FIXME: Are the defaults correct for ARM?
Eli Friedman2b161652008-08-21 00:13:15 +0000814 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
815 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:64";
Eli Friedman0b7b1cb2008-05-20 14:21:01 +0000816 }
Chris Lattner79682402009-03-20 15:52:06 +0000817 virtual void getTargetDefines(const LangOptions &Opts,
818 std::vector<char> &Defs) const {
Chris Lattnerbef1d722009-03-02 22:27:17 +0000819 // Target identification.
820 Define(Defs, "__arm");
821 Define(Defs, "__arm__");
822
823 // Target properties.
824 Define(Defs, "__LITTLE_ENDIAN__");
825
826 // Subtarget options. [hard coded to v6 for now]
827 Define(Defs, "__ARM_ARCH_6K__");
828 Define(Defs, "__ARMEL__");
829 Define(Defs, "__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", "20000");
Chris Lattner9fd73612008-04-21 18:56:49 +0000830 }
831 virtual void getTargetBuiltins(const Builtin::Info *&Records,
832 unsigned &NumRecords) const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000833 // FIXME: Implement.
834 Records = 0;
Chris Lattner9fd73612008-04-21 18:56:49 +0000835 NumRecords = 0;
836 }
837 virtual const char *getVAListDeclaration() const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000838 return "typedef char* __builtin_va_list;";
Chris Lattner9fd73612008-04-21 18:56:49 +0000839 }
840 virtual const char *getTargetPrefix() const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000841 return "arm";
Chris Lattner9fd73612008-04-21 18:56:49 +0000842 }
Chris Lattner9fd73612008-04-21 18:56:49 +0000843 virtual void getGCCRegNames(const char * const *&Names,
844 unsigned &NumNames) const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000845 // FIXME: Implement.
846 Names = 0;
Chris Lattner9fd73612008-04-21 18:56:49 +0000847 NumNames = 0;
848 }
849 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
850 unsigned &NumAliases) const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000851 // FIXME: Implement.
852 Aliases = 0;
Chris Lattner9fd73612008-04-21 18:56:49 +0000853 NumAliases = 0;
854 }
Anders Carlsson36834a72009-02-28 17:11:49 +0000855 virtual bool validateAsmConstraint(const char *&Name,
Nate Begeman222823a2008-04-22 05:03:19 +0000856 TargetInfo::ConstraintInfo &info) const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000857 // FIXME: Check if this is complete
Anders Carlsson36834a72009-02-28 17:11:49 +0000858 switch (*Name) {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000859 default:
Nate Begeman222823a2008-04-22 05:03:19 +0000860 case 'l': // r0-r7
861 case 'h': // r8-r15
862 case 'w': // VFP Floating point register single precision
863 case 'P': // VFP Floating point register double precision
864 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
865 return true;
866 }
Chris Lattner9fd73612008-04-21 18:56:49 +0000867 return false;
868 }
869 virtual const char *getClobbers() const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000870 // FIXME: Is this really right?
Chris Lattner9fd73612008-04-21 18:56:49 +0000871 return "";
872 }
873};
874} // end anonymous namespace.
875
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000876
877namespace {
878class DarwinARMTargetInfo : public ARMTargetInfo {
879public:
880 DarwinARMTargetInfo(const std::string& triple) : ARMTargetInfo(triple) {}
881
Chris Lattner79682402009-03-20 15:52:06 +0000882 virtual void getTargetDefines(const LangOptions &Opts,
883 std::vector<char> &Defines) const {
884 ARMTargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000885 getDarwinDefines(Defines, getTargetTriple());
Eli Friedmanbe727fe2008-08-20 07:44:10 +0000886 }
887};
888} // end anonymous namespace.
889
Chris Lattner4b009652007-07-25 00:24:17 +0000890namespace {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000891class SparcV8TargetInfo : public TargetInfo {
Chris Lattnerff7c53d2009-01-27 01:58:38 +0000892 static const TargetInfo::GCCRegAlias GCCRegAliases[];
893 static const char * const GCCRegNames[];
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000894public:
Eli Friedmanff158dd2008-08-20 07:28:14 +0000895 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
896 // FIXME: Support Sparc quad-precision long double?
Eli Friedman2b161652008-08-21 00:13:15 +0000897 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
898 "i64:64:64-f32:32:32-f64:64:64-v64:64:64";
Eli Friedmanff158dd2008-08-20 07:28:14 +0000899 }
Chris Lattner79682402009-03-20 15:52:06 +0000900 virtual void getTargetDefines(const LangOptions &Opts,
901 std::vector<char> &Defines) const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000902 // FIXME: This is missing a lot of important defines; some of the
903 // missing stuff is likely to break system headers.
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000904 Define(Defines, "__sparc");
Eli Friedman1dee5c52008-05-25 05:26:09 +0000905 Define(Defines, "__sparc__");
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000906 Define(Defines, "__sparcv8");
907 }
908 virtual void getTargetBuiltins(const Builtin::Info *&Records,
909 unsigned &NumRecords) const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000910 // FIXME: Implement!
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000911 }
912 virtual const char *getVAListDeclaration() const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000913 return "typedef void* __builtin_va_list;";
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000914 }
915 virtual const char *getTargetPrefix() const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000916 return "sparc";
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000917 }
918 virtual void getGCCRegNames(const char * const *&Names,
Chris Lattnerff7c53d2009-01-27 01:58:38 +0000919 unsigned &NumNames) const;
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000920 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattnerff7c53d2009-01-27 01:58:38 +0000921 unsigned &NumAliases) const;
Anders Carlsson36834a72009-02-28 17:11:49 +0000922 virtual bool validateAsmConstraint(const char *&Name,
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000923 TargetInfo::ConstraintInfo &info) const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000924 // FIXME: Implement!
925 return false;
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000926 }
927 virtual const char *getClobbers() const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000928 // FIXME: Implement!
929 return "";
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000930 }
931};
932
Chris Lattnerff7c53d2009-01-27 01:58:38 +0000933const char * const SparcV8TargetInfo::GCCRegNames[] = {
934 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
935 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
936 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
937 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
938};
939
940void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names,
941 unsigned &NumNames) const {
942 Names = GCCRegNames;
943 NumNames = llvm::array_lengthof(GCCRegNames);
944}
945
946const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = {
947 { { "g0" }, "r0" },
948 { { "g1" }, "r1" },
949 { { "g2" }, "r2" },
950 { { "g3" }, "r3" },
951 { { "g4" }, "r4" },
952 { { "g5" }, "r5" },
953 { { "g6" }, "r6" },
954 { { "g7" }, "r7" },
955 { { "o0" }, "r8" },
956 { { "o1" }, "r9" },
957 { { "o2" }, "r10" },
958 { { "o3" }, "r11" },
959 { { "o4" }, "r12" },
960 { { "o5" }, "r13" },
961 { { "o6", "sp" }, "r14" },
962 { { "o7" }, "r15" },
963 { { "l0" }, "r16" },
964 { { "l1" }, "r17" },
965 { { "l2" }, "r18" },
966 { { "l3" }, "r19" },
967 { { "l4" }, "r20" },
968 { { "l5" }, "r21" },
969 { { "l6" }, "r22" },
970 { { "l7" }, "r23" },
971 { { "i0" }, "r24" },
972 { { "i1" }, "r25" },
973 { { "i2" }, "r26" },
974 { { "i3" }, "r27" },
975 { { "i4" }, "r28" },
976 { { "i5" }, "r29" },
977 { { "i6", "fp" }, "r30" },
978 { { "i7" }, "r31" },
979};
980
981void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
982 unsigned &NumAliases) const {
983 Aliases = GCCRegAliases;
984 NumAliases = llvm::array_lengthof(GCCRegAliases);
985}
Gabor Greif8a3ff0d2008-02-21 16:29:08 +0000986} // end anonymous namespace.
987
Eli Friedmanff158dd2008-08-20 07:28:14 +0000988namespace {
989class SolarisSparcV8TargetInfo : public SparcV8TargetInfo {
990public:
991 SolarisSparcV8TargetInfo(const std::string& triple) :
Eli Friedman7cca0982008-11-02 02:43:55 +0000992 SparcV8TargetInfo(triple) {
993 SizeType = UnsignedInt;
994 PtrDiffType = SignedInt;
995 }
Eli Friedmanff158dd2008-08-20 07:28:14 +0000996
Chris Lattner79682402009-03-20 15:52:06 +0000997 virtual void getTargetDefines(const LangOptions &Opts,
998 std::vector<char> &Defines) const {
999 SparcV8TargetInfo::getTargetDefines(Opts, Defines);
Eli Friedmanff158dd2008-08-20 07:28:14 +00001000 getSolarisDefines(Defines);
1001 }
1002};
1003} // end anonymous namespace.
Chris Lattner4b009652007-07-25 00:24:17 +00001004
Chris Lattner85970f32008-05-08 05:58:21 +00001005namespace {
1006 class PIC16TargetInfo : public TargetInfo{
1007 public:
1008 PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) {
Sanjiv Guptafa451432008-10-31 09:52:39 +00001009 IntWidth = 16;
1010 LongWidth = LongLongWidth = 32;
1011 PointerWidth = 16;
1012 IntAlign = 8;
1013 LongAlign = LongLongAlign = 8;
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001014 PointerAlign = 8;
Sanjiv Guptafa451432008-10-31 09:52:39 +00001015 SizeType = UnsignedInt;
1016 IntMaxType = SignedLong;
1017 UIntMaxType = UnsignedLong;
Chris Lattnerd9ef7242009-02-13 22:28:55 +00001018 IntPtrType = SignedShort;
Eli Friedman7cca0982008-11-02 02:43:55 +00001019 PtrDiffType = SignedInt;
Sanjiv Guptaebd8f0f2008-08-18 10:05:22 +00001020 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8";
Chris Lattner85970f32008-05-08 05:58:21 +00001021 }
Chris Lattner727b3c42008-05-09 06:08:39 +00001022 virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; }
1023 virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; }
Chris Lattner79682402009-03-20 15:52:06 +00001024 virtual void getTargetDefines(const LangOptions &Opts,
1025 std::vector<char> &Defines) const {
Chris Lattner85970f32008-05-08 05:58:21 +00001026 Define(Defines, "__pic16");
1027 }
1028 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1029 unsigned &NumRecords) const {}
1030 virtual const char *getVAListDeclaration() const { return "";}
1031 virtual const char *getClobbers() const {return "";}
1032 virtual const char *getTargetPrefix() const {return "";}
1033 virtual void getGCCRegNames(const char * const *&Names,
1034 unsigned &NumNames) const {}
Anders Carlsson36834a72009-02-28 17:11:49 +00001035 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattner85970f32008-05-08 05:58:21 +00001036 TargetInfo::ConstraintInfo &info) const {
1037 return true;
1038 }
1039 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1040 unsigned &NumAliases) const {}
1041 virtual bool useGlobalsForAutomaticVariables() const {return true;}
1042 };
1043}
1044
Chris Lattner4b009652007-07-25 00:24:17 +00001045//===----------------------------------------------------------------------===//
1046// Driver code
1047//===----------------------------------------------------------------------===//
1048
Ted Kremenekb97d7672007-12-04 17:07:35 +00001049static inline bool IsX86(const std::string& TT) {
Ted Kremenek40499482007-12-03 22:06:55 +00001050 return (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' &&
1051 TT[4] == '-' && TT[1] - '3' < 6);
1052}
1053
Chris Lattnerfc457002008-03-05 01:18:20 +00001054/// CreateTargetInfo - Return the target info object for the specified target
1055/// triple.
1056TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
Eli Friedman2b161652008-08-21 00:13:15 +00001057 // OS detection; this isn't really anywhere near complete.
1058 // Additions and corrections are welcome.
1059 bool isDarwin = T.find("-darwin") != std::string::npos;
Chris Lattnerd4faca42008-08-23 18:23:14 +00001060 bool isDragonFly = T.find("-dragonfly") != std::string::npos;
Chris Lattner98cb2a22008-10-16 17:04:31 +00001061 bool isFreeBSD = T.find("-freebsd") != std::string::npos;
Eli Friedman2b161652008-08-21 00:13:15 +00001062 bool isSolaris = T.find("-solaris") != std::string::npos;
1063 bool isLinux = T.find("-linux") != std::string::npos;
1064 bool isWindows = T.find("-windows") != std::string::npos ||
1065 T.find("-win32") != std::string::npos ||
1066 T.find("-mingw") != std::string::npos;
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001067
Eli Friedman2b161652008-08-21 00:13:15 +00001068 if (T.find("ppc-") == 0 || T.find("powerpc-") == 0) {
1069 if (isDarwin)
1070 return new DarwinPPCTargetInfo(T);
1071 return new PPC32TargetInfo(T);
1072 }
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001073
Eli Friedman2b161652008-08-21 00:13:15 +00001074 if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0) {
1075 if (isDarwin)
1076 return new DarwinPPC64TargetInfo(T);
1077 return new PPC64TargetInfo(T);
1078 }
Chris Lattner9fd73612008-04-21 18:56:49 +00001079
Eli Friedman2b161652008-08-21 00:13:15 +00001080 if (T.find("armv6-") == 0 || T.find("arm-") == 0) {
1081 if (isDarwin)
1082 return new DarwinARMTargetInfo(T);
1083 return new ARMTargetInfo(T);
1084 }
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001085
Eli Friedman2b161652008-08-21 00:13:15 +00001086 if (T.find("sparc-") == 0) {
1087 if (isSolaris)
1088 return new SolarisSparcV8TargetInfo(T);
1089 return new SparcV8TargetInfo(T);
1090 }
1091
Chris Lattner273dce42009-02-20 17:04:14 +00001092 if (T.find("x86_64-") == 0 || T.find("amd64-") == 0) {
Eli Friedman2b161652008-08-21 00:13:15 +00001093 if (isDarwin)
1094 return new DarwinX86_64TargetInfo(T);
Daniel Dunbare5a80f22008-09-23 17:37:57 +00001095 if (isLinux)
1096 return new LinuxX86_64TargetInfo(T);
Chris Lattner98cb2a22008-10-16 17:04:31 +00001097 if (isFreeBSD)
1098 return new FreeBSDX86_64TargetInfo(T);
Eli Friedman2b161652008-08-21 00:13:15 +00001099 return new X86_64TargetInfo(T);
1100 }
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001101
Chris Lattner85970f32008-05-08 05:58:21 +00001102 if (T.find("pic16-") == 0)
1103 return new PIC16TargetInfo(T);
1104
Eli Friedman2b161652008-08-21 00:13:15 +00001105 if (IsX86(T)) {
1106 if (isDarwin)
1107 return new DarwinI386TargetInfo(T);
Eli Friedman5fb0a022008-08-21 00:24:02 +00001108 if (isLinux)
1109 return new LinuxX86_32TargetInfo(T);
Chris Lattnerd4faca42008-08-23 18:23:14 +00001110 if (isDragonFly)
1111 return new DragonFlyX86_32TargetInfo(T);
Chris Lattner98cb2a22008-10-16 17:04:31 +00001112 if (isFreeBSD)
1113 return new FreeBSDX86_32TargetInfo(T);
Eli Friedman23cb7912008-08-21 01:40:19 +00001114 if (isWindows)
1115 return new WindowsX86_32TargetInfo(T);
Eli Friedman2b161652008-08-21 00:13:15 +00001116 return new X86_32TargetInfo(T);
1117 }
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001118
Chris Lattnerfc457002008-03-05 01:18:20 +00001119 return NULL;
Chris Lattner4b009652007-07-25 00:24:17 +00001120}
Ted Kremenekd507bab2008-03-04 17:47:18 +00001121