blob: 04ab3afdb149928587c2dba5f71f8268ccbd071b [file] [log] [blame]
Reid Spencer5f016e22007-07-11 17:01:13 +00001//===--- Targets.cpp - Implement -arch option and targets -----------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner0bc735f2007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Reid Spencer5f016e22007-07-11 17:01:13 +00007//
8//===----------------------------------------------------------------------===//
9//
Ted Kremenekbbced582007-12-12 18:05:32 +000010// This file implements construction of a TargetInfo object from a
11// target triple.
Reid Spencer5f016e22007-07-11 17:01:13 +000012//
13//===----------------------------------------------------------------------===//
14
Douglas Gregorb1152d82009-02-16 21:58:21 +000015// FIXME: Layering violation
Reid Spencer5f016e22007-07-11 17:01:13 +000016#include "clang/AST/Builtins.h"
Anders Carlsson564f1de2007-12-09 23:17:02 +000017#include "clang/AST/TargetBuiltins.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000018#include "clang/Basic/TargetInfo.h"
Chris Lattner8fc4dfb2008-12-04 22:54:33 +000019#include "clang/Basic/LangOptions.h"
Anders Carlsson3346ae62007-11-24 23:38:12 +000020#include "llvm/ADT/STLExtras.h"
Eli Friedman25531262008-05-20 14:27:34 +000021#include "llvm/ADT/APFloat.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000022using namespace clang;
23
Reid Spencer5f016e22007-07-11 17:01:13 +000024//===----------------------------------------------------------------------===//
25// Common code shared among targets.
26//===----------------------------------------------------------------------===//
27
Chris Lattnerd15fa822007-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 Lattnerd29b6302008-10-05 21:50:58 +000038//===----------------------------------------------------------------------===//
39// Defines specific to certain operating systems.
40//===----------------------------------------------------------------------===//
41
Eli Friedman01b86682008-08-20 07:28:14 +000042static void getSolarisDefines(std::vector<char> &Defs) {
43 Define(Defs, "__SUN__");
44 Define(Defs, "__SOLARIS__");
45}
Reid Spencer5f016e22007-07-11 17:01:13 +000046
Nate Begemanca013422009-01-18 01:08:03 +000047static void getFreeBSDDefines(std::vector<char> &Defs, bool is64Bit,
48 const char *Triple) {
Chris Lattnerfd0269d2008-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 Korobeynikov2793bda2009-02-14 16:42:50 +000062 Define(Defs, "__ELF__", "1");
Chris Lattnerfd0269d2008-10-16 17:04:31 +000063 if (is64Bit) {
64 Define(Defs, "__LP64__");
65 }
66}
67
Chris Lattnerd29b6302008-10-05 21:50:58 +000068static void getDragonFlyDefines(std::vector<char> &Defs) {
69 // DragonFly defines; list based off of gcc output
70 Define(Defs, "__DragonFly__");
71 Define(Defs, "__DragonFly_cc_version", "100001");
72 Define(Defs, "__ELF__");
73 Define(Defs, "__KPRINTF_ATTRIBUTE__");
74 Define(Defs, "__tune_i386__");
75 Define(Defs, "unix");
76 Define(Defs, "__unix");
77 Define(Defs, "__unix__");
78}
79
80static void getLinuxDefines(std::vector<char> &Defs) {
81 // Linux defines; list based off of gcc output
82 Define(Defs, "__unix__");
83 Define(Defs, "__unix");
84 Define(Defs, "unix");
85 Define(Defs, "__linux__");
86 Define(Defs, "__linux");
87 Define(Defs, "linux");
88 Define(Defs, "__gnu_linux__");
Argyrios Kyrtzidis487cdee2009-02-14 15:02:45 +000089 Define(Defs, "__ELF__", "1");
Chris Lattnerd29b6302008-10-05 21:50:58 +000090}
91
Chris Lattnerae0ee032008-12-04 23:20:07 +000092/// getDarwinNumber - Parse the 'darwin number' out of the specific targe
93/// triple. For example, if we have darwin8.5 return 8,5,4. If any entry is
94/// not defined, return 0's. Return true if we have -darwin in the string or
95/// false otherwise.
96static bool getDarwinNumber(const char *Triple, unsigned &Maj, unsigned &Min) {
97 Maj = Min = 0;
98 const char *Darwin = strstr(Triple, "-darwin");
99 if (Darwin == 0) return false;
100
101 Darwin += strlen("-darwin");
102 if (Darwin[0] < '0' || Darwin[0] > '9')
103 return true;
104
105 Maj = Darwin[0]-'0';
106 ++Darwin;
107
108 // Handle "darwin11".
109 if (Maj == 1 && Darwin[0] >= '0' && Darwin[0] <= '9') {
110 Maj = 10+Darwin[0]-'0';
111 ++Darwin;
112 }
113
114 // Handle minor version: 10.4.9 -> darwin8.9 -> "1049"
115 if (Darwin[0] == '.' && Darwin[1] >= '0' && Darwin[1] <= '9' &&
116 Darwin[2] == '\0')
117 Min = Darwin[1]-'0';
118
119 return true;
120}
121
Chris Lattner8b30c412008-09-30 01:00:25 +0000122static void getDarwinDefines(std::vector<char> &Defs, const char *Triple) {
Eli Friedman618234a2008-08-20 02:34:37 +0000123 Define(Defs, "__APPLE__");
124 Define(Defs, "__MACH__");
Chris Lattnerd427ad42009-02-05 07:19:24 +0000125 Define(Defs, "OBJC_NEW_PROPERTIES");
126
127 // FIXME: OBJC_ZEROCOST_EXCEPTIONS when using zero cost eh.
Chris Lattner8b30c412008-09-30 01:00:25 +0000128
129 // Figure out which "darwin number" the target triple is. "darwin9" -> 10.5.
Chris Lattnerae0ee032008-12-04 23:20:07 +0000130 unsigned Maj, Min;
131 if (getDarwinNumber(Triple, Maj, Min)) {
Chris Lattner079f2c462008-09-30 20:30:12 +0000132 char DarwinStr[] = "1000";
Chris Lattnerae0ee032008-12-04 23:20:07 +0000133 if (Maj >= 4 && Maj <= 13) { // 10.0-10.9
134 // darwin7 -> 1030, darwin8 -> 1040, darwin9 -> 1050, etc.
135 DarwinStr[2] = '0' + Maj-4;
Chris Lattner8b30c412008-09-30 01:00:25 +0000136 }
Chris Lattnerae0ee032008-12-04 23:20:07 +0000137
138 // Handle minor version: 10.4.9 -> darwin8.9 -> "1049"
139 DarwinStr[3] = Min+'0';
Chris Lattner079f2c462008-09-30 20:30:12 +0000140 Define(Defs, "__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", DarwinStr);
Chris Lattner8b30c412008-09-30 01:00:25 +0000141 }
Eli Friedman618234a2008-08-20 02:34:37 +0000142}
Reid Spencer5f016e22007-07-11 17:01:13 +0000143
Chris Lattnerae0ee032008-12-04 23:20:07 +0000144/// GetDarwinLanguageOptions - Set the default language options for darwin.
145static void GetDarwinLanguageOptions(LangOptions &Opts,
146 const char *Triple) {
147 Opts.NeXTRuntime = true;
148
149 unsigned Maj, Min;
150 if (!getDarwinNumber(Triple, Maj, Min))
151 return;
152
153 // Blocks default to on for 10.6 (darwin10) and beyond.
Fariborz Jahaniana30b17b2009-02-12 17:54:33 +0000154 // As does nonfragile-abi for 64bit mode
Fariborz Jahanian66a5c2c2009-02-24 23:34:44 +0000155 if (Maj > 9)
Chris Lattnerae0ee032008-12-04 23:20:07 +0000156 Opts.Blocks = 1;
Fariborz Jahanian66a5c2c2009-02-24 23:34:44 +0000157
Fariborz Jahanian84d01332009-02-24 23:38:42 +0000158 if (Maj >= 9 && Opts.ObjC1 && !strncmp(Triple, "x86_64", 6))
159 Opts.ObjCNonFragileABI = 1;
Chris Lattnerae0ee032008-12-04 23:20:07 +0000160}
161
162
Chris Lattnerd29b6302008-10-05 21:50:58 +0000163//===----------------------------------------------------------------------===//
Eli Friedmane4277982008-08-20 23:11:40 +0000164// Specific target implementations.
165//===----------------------------------------------------------------------===//
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000166
Eli Friedmane4277982008-08-20 23:11:40 +0000167namespace {
168// PPC abstract base class
169class PPCTargetInfo : public TargetInfo {
170 static const Builtin::Info BuiltinInfo[];
171 static const char * const GCCRegNames[];
172 static const TargetInfo::GCCRegAlias GCCRegAliases[];
173
174public:
175 PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {
176 CharIsSigned = false;
177 }
178 virtual void getTargetBuiltins(const Builtin::Info *&Records,
179 unsigned &NumRecords) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000180 Records = BuiltinInfo;
Eli Friedmane4277982008-08-20 23:11:40 +0000181 NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
Reid Spencer5f016e22007-07-11 17:01:13 +0000182 }
Chris Lattnerc0f59212009-03-02 22:27:17 +0000183
184 virtual void getTargetDefines(std::vector<char> &Defines) const;
185
Eli Friedmane4277982008-08-20 23:11:40 +0000186 virtual const char *getVAListDeclaration() const {
Chris Lattnerd5998502008-10-27 01:11:29 +0000187 return "typedef char* __builtin_va_list;";
188 // This is the right definition for ABI/V4: System V.4/eabi.
189 /*return "typedef struct __va_list_tag {"
Eli Friedmane4277982008-08-20 23:11:40 +0000190 " unsigned char gpr;"
191 " unsigned char fpr;"
192 " unsigned short reserved;"
193 " void* overflow_arg_area;"
194 " void* reg_save_area;"
Chris Lattnerd5998502008-10-27 01:11:29 +0000195 "} __builtin_va_list[1];";*/
Anders Carlsson3346ae62007-11-24 23:38:12 +0000196 }
Eli Friedmane4277982008-08-20 23:11:40 +0000197 virtual const char *getTargetPrefix() const {
198 return "ppc";
Anders Carlssond04c6e22007-11-27 04:11:28 +0000199 }
Eli Friedmane4277982008-08-20 23:11:40 +0000200 virtual void getGCCRegNames(const char * const *&Names,
201 unsigned &NumNames) const;
202 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
203 unsigned &NumAliases) const;
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000204 virtual bool validateAsmConstraint(const char *&Name,
Eli Friedmane4277982008-08-20 23:11:40 +0000205 TargetInfo::ConstraintInfo &info) const {
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000206 switch (*Name) {
Anders Carlssond04c6e22007-11-27 04:11:28 +0000207 default: return false;
208 case 'O': // Zero
209 return true;
210 case 'b': // Base register
211 case 'f': // Floating point register
212 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
213 return true;
214 }
215 }
Eli Friedmane4277982008-08-20 23:11:40 +0000216 virtual const char *getClobbers() const {
217 return "";
Anders Carlssond04c6e22007-11-27 04:11:28 +0000218 }
Eli Friedmane4277982008-08-20 23:11:40 +0000219};
Anders Carlssond04c6e22007-11-27 04:11:28 +0000220
Eli Friedmane4277982008-08-20 23:11:40 +0000221const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
Douglas Gregorb1152d82009-02-16 21:58:21 +0000222#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
223#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
Eli Friedmane4277982008-08-20 23:11:40 +0000224#include "clang/AST/PPCBuiltins.def"
225};
Chris Lattnerc0f59212009-03-02 22:27:17 +0000226
227
228/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
229/// #defines that are not tied to a specific subtarget.
230void PPCTargetInfo::getTargetDefines(std::vector<char> &Defs) const {
231 // Target identification.
232 Define(Defs, "__ppc__");
233 Define(Defs, "_ARCH_PPC");
234 Define(Defs, "__POWERPC__");
235 if (PointerWidth == 64) {
236 Define(Defs, "_ARCH_PPC64");
237 Define(Defs, "_LP64");
238 Define(Defs, "__LP64__");
239 Define(Defs, "__ppc64__");
240 } else {
241 Define(Defs, "__ppc__");
242 }
243
244 // Target properties.
245 Define(Defs, "_BIG_ENDIAN");
246 Define(Defs, "__BIG_ENDIAN__");
247
248 // Subtarget options.
249 Define(Defs, "__NATURAL_ALIGNMENT__");
250 Define(Defs, "__REGISTER_PREFIX__", "");
251
252 // FIXME: Should be controlled by command line option.
253 Define(Defs, "__LONG_DOUBLE_128__");
254}
255
Chris Lattner393ff042008-04-21 18:56:49 +0000256
Eli Friedmane4277982008-08-20 23:11:40 +0000257const char * const PPCTargetInfo::GCCRegNames[] = {
258 "0", "1", "2", "3", "4", "5", "6", "7",
259 "8", "9", "10", "11", "12", "13", "14", "15",
260 "16", "17", "18", "19", "20", "21", "22", "23",
261 "24", "25", "26", "27", "28", "29", "30", "31",
262 "0", "1", "2", "3", "4", "5", "6", "7",
263 "8", "9", "10", "11", "12", "13", "14", "15",
264 "16", "17", "18", "19", "20", "21", "22", "23",
265 "24", "25", "26", "27", "28", "29", "30", "31",
266 "mq", "lr", "ctr", "ap",
267 "0", "1", "2", "3", "4", "5", "6", "7",
268 "xer",
269 "0", "1", "2", "3", "4", "5", "6", "7",
270 "8", "9", "10", "11", "12", "13", "14", "15",
271 "16", "17", "18", "19", "20", "21", "22", "23",
272 "24", "25", "26", "27", "28", "29", "30", "31",
273 "vrsave", "vscr",
274 "spe_acc", "spefscr",
275 "sfp"
276};
Reid Spencer5f016e22007-07-11 17:01:13 +0000277
Eli Friedmane4277982008-08-20 23:11:40 +0000278void PPCTargetInfo::getGCCRegNames(const char * const *&Names,
279 unsigned &NumNames) const {
280 Names = GCCRegNames;
281 NumNames = llvm::array_lengthof(GCCRegNames);
282}
Reid Spencer5f016e22007-07-11 17:01:13 +0000283
Eli Friedmane4277982008-08-20 23:11:40 +0000284const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
285 // While some of these aliases do map to different registers
286 // they still share the same register name.
287 { { "cc", "cr0", "fr0", "r0", "v0"}, "0" },
288 { { "cr1", "fr1", "r1", "sp", "v1"}, "1" },
289 { { "cr2", "fr2", "r2", "toc", "v2"}, "2" },
290 { { "cr3", "fr3", "r3", "v3"}, "3" },
291 { { "cr4", "fr4", "r4", "v4"}, "4" },
292 { { "cr5", "fr5", "r5", "v5"}, "5" },
293 { { "cr6", "fr6", "r6", "v6"}, "6" },
294 { { "cr7", "fr7", "r7", "v7"}, "7" },
295 { { "fr8", "r8", "v8"}, "8" },
296 { { "fr9", "r9", "v9"}, "9" },
297 { { "fr10", "r10", "v10"}, "10" },
298 { { "fr11", "r11", "v11"}, "11" },
299 { { "fr12", "r12", "v12"}, "12" },
300 { { "fr13", "r13", "v13"}, "13" },
301 { { "fr14", "r14", "v14"}, "14" },
302 { { "fr15", "r15", "v15"}, "15" },
303 { { "fr16", "r16", "v16"}, "16" },
304 { { "fr17", "r17", "v17"}, "17" },
305 { { "fr18", "r18", "v18"}, "18" },
306 { { "fr19", "r19", "v19"}, "19" },
307 { { "fr20", "r20", "v20"}, "20" },
308 { { "fr21", "r21", "v21"}, "21" },
309 { { "fr22", "r22", "v22"}, "22" },
310 { { "fr23", "r23", "v23"}, "23" },
311 { { "fr24", "r24", "v24"}, "24" },
312 { { "fr25", "r25", "v25"}, "25" },
313 { { "fr26", "r26", "v26"}, "26" },
314 { { "fr27", "r27", "v27"}, "27" },
315 { { "fr28", "r28", "v28"}, "28" },
316 { { "fr29", "r29", "v29"}, "29" },
317 { { "fr30", "r30", "v30"}, "30" },
318 { { "fr31", "r31", "v31"}, "31" },
319};
320
321void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
322 unsigned &NumAliases) const {
323 Aliases = GCCRegAliases;
324 NumAliases = llvm::array_lengthof(GCCRegAliases);
325}
326} // end anonymous namespace.
Reid Spencer5f016e22007-07-11 17:01:13 +0000327
328namespace {
Eli Friedmane4277982008-08-20 23:11:40 +0000329class PPC32TargetInfo : public PPCTargetInfo {
Reid Spencer5f016e22007-07-11 17:01:13 +0000330public:
Eli Friedmaned855cb2008-08-21 00:13:15 +0000331 PPC32TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
332 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
333 "i64:64:64-f32:32:32-f64:64:64-v128:128:128";
334 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000335};
336} // end anonymous namespace.
337
338namespace {
Eli Friedmane4277982008-08-20 23:11:40 +0000339class PPC64TargetInfo : public PPCTargetInfo {
Reid Spencer5f016e22007-07-11 17:01:13 +0000340public:
Eli Friedmane4277982008-08-20 23:11:40 +0000341 PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
Chris Lattnerf291b102008-05-09 06:17:04 +0000342 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedmaned855cb2008-08-21 00:13:15 +0000343 DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
344 "i64:64:64-f32:32:32-f64:64:64-v128:128:128";
Chris Lattnerf291b102008-05-09 06:17:04 +0000345 }
Eli Friedmane4277982008-08-20 23:11:40 +0000346};
347} // end anonymous namespace.
348
Chris Lattnerae0ee032008-12-04 23:20:07 +0000349
Eli Friedmane4277982008-08-20 23:11:40 +0000350namespace {
351class DarwinPPCTargetInfo : public PPC32TargetInfo {
352public:
353 DarwinPPCTargetInfo(const std::string& triple) : PPC32TargetInfo(triple) {}
354 virtual void getTargetDefines(std::vector<char> &Defines) const {
355 PPC32TargetInfo::getTargetDefines(Defines);
Chris Lattner8b30c412008-09-30 01:00:25 +0000356 getDarwinDefines(Defines, getTargetTriple());
Reid Spencer5f016e22007-07-11 17:01:13 +0000357 }
Daniel Dunbardcb4a1a2008-08-23 08:43:39 +0000358
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000359 /// getDefaultLangOptions - Allow the target to specify default settings for
360 /// various language options. These may be overridden by command line
361 /// options.
362 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattnerae0ee032008-12-04 23:20:07 +0000363 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000364 }
Eli Friedmane4277982008-08-20 23:11:40 +0000365};
366} // end anonymous namespace.
367
368namespace {
369class DarwinPPC64TargetInfo : public PPC64TargetInfo {
370public:
371 DarwinPPC64TargetInfo(const std::string& triple) : PPC64TargetInfo(triple) {}
372 virtual void getTargetDefines(std::vector<char> &Defines) const {
373 PPC64TargetInfo::getTargetDefines(Defines);
Chris Lattner8b30c412008-09-30 01:00:25 +0000374 getDarwinDefines(Defines, getTargetTriple());
Anders Carlsson3346ae62007-11-24 23:38:12 +0000375 }
Daniel Dunbardcb4a1a2008-08-23 08:43:39 +0000376
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000377 /// getDefaultLangOptions - Allow the target to specify default settings for
378 /// various language options. These may be overridden by command line
379 /// options.
380 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattnerae0ee032008-12-04 23:20:07 +0000381 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000382 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000383};
384} // end anonymous namespace.
385
386namespace {
Eli Friedman618234a2008-08-20 02:34:37 +0000387// Namespace for x86 abstract base class
388const Builtin::Info BuiltinInfo[] = {
Douglas Gregorb1152d82009-02-16 21:58:21 +0000389#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
390#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
Eli Friedman618234a2008-08-20 02:34:37 +0000391#include "clang/AST/X86Builtins.def"
392};
Eli Friedman61538a72008-05-20 14:21:01 +0000393
Eli Friedman618234a2008-08-20 02:34:37 +0000394const char *GCCRegNames[] = {
395 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
396 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
397 "argp", "flags", "fspr", "dirflag", "frame",
398 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
399 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
400 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
401 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
402};
403
404const TargetInfo::GCCRegAlias GCCRegAliases[] = {
405 { { "al", "ah", "eax", "rax" }, "ax" },
406 { { "bl", "bh", "ebx", "rbx" }, "bx" },
407 { { "cl", "ch", "ecx", "rcx" }, "cx" },
408 { { "dl", "dh", "edx", "rdx" }, "dx" },
409 { { "esi", "rsi" }, "si" },
410 { { "edi", "rdi" }, "di" },
411 { { "esp", "rsp" }, "sp" },
412 { { "ebp", "rbp" }, "bp" },
413};
414
415// X86 target abstract base class; x86-32 and x86-64 are very close, so
416// most of the implementation can be shared.
417class X86TargetInfo : public TargetInfo {
Chris Lattner84f0ea82009-03-02 22:40:39 +0000418 enum X86SSEEnum {
419 NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42
420 } SSELevel;
Eli Friedman618234a2008-08-20 02:34:37 +0000421public:
Chris Lattner84f0ea82009-03-02 22:40:39 +0000422 X86TargetInfo(const std::string& triple)
Chris Lattner6328cc32009-03-03 19:56:18 +0000423 : TargetInfo(triple),
424 // FIXME: hard coding to SSE2 for now. This should change to NoMMXSSE so
425 // that the driver controls this.
426 SSELevel(SSE2) {
Eli Friedman618234a2008-08-20 02:34:37 +0000427 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
Reid Spencer5f016e22007-07-11 17:01:13 +0000428 }
429 virtual void getTargetBuiltins(const Builtin::Info *&Records,
430 unsigned &NumRecords) const {
Eli Friedman618234a2008-08-20 02:34:37 +0000431 Records = BuiltinInfo;
432 NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
Reid Spencer5f016e22007-07-11 17:01:13 +0000433 }
Anders Carlsson44fe49c2007-12-08 19:32:57 +0000434 virtual const char *getTargetPrefix() const {
Eli Friedman618234a2008-08-20 02:34:37 +0000435 return "x86";
Anders Carlsson44fe49c2007-12-08 19:32:57 +0000436 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000437 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedman618234a2008-08-20 02:34:37 +0000438 unsigned &NumNames) const {
439 Names = GCCRegNames;
440 NumNames = llvm::array_lengthof(GCCRegNames);
Anders Carlsson3346ae62007-11-24 23:38:12 +0000441 }
442 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
443 unsigned &NumAliases) const {
Eli Friedman618234a2008-08-20 02:34:37 +0000444 Aliases = GCCRegAliases;
445 NumAliases = llvm::array_lengthof(GCCRegAliases);
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000446 }
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000447 virtual bool validateAsmConstraint(const char *&Name,
Eli Friedman618234a2008-08-20 02:34:37 +0000448 TargetInfo::ConstraintInfo &info) const;
449 virtual std::string convertConstraint(const char Constraint) const;
Anders Carlssond04c6e22007-11-27 04:11:28 +0000450 virtual const char *getClobbers() const {
Eli Friedman618234a2008-08-20 02:34:37 +0000451 return "~{dirflag},~{fpsr},~{flags}";
452 }
Chris Lattnerc0f59212009-03-02 22:27:17 +0000453 virtual void getTargetDefines(std::vector<char> &Defines) const;
Chris Lattner3daed522009-03-02 22:20:04 +0000454
Chris Lattner6328cc32009-03-03 19:56:18 +0000455 virtual int HandleTargetFeatures(std::string *StrArray, unsigned NumStrs,
456 std::string &ErrorReason);
Reid Spencer5f016e22007-07-11 17:01:13 +0000457};
Chris Lattner3daed522009-03-02 22:20:04 +0000458
459/// HandleTargetOptions - Handle target-specific options like -msse2 and
460/// friends. An array of arguments is passed in: if they are all valid, this
461/// should handle them and return -1. If there is an error, the index of the
462/// invalid argument should be returned along with an optional error string.
Chris Lattner6328cc32009-03-03 19:56:18 +0000463int X86TargetInfo::HandleTargetFeatures(std::string *StrArray, unsigned NumStrs,
464 std::string &ErrorReason) {
465 for (unsigned i = 0; i != NumStrs; ++i) {
466 const std::string &Feature = StrArray[i];
467 if (Feature.size() < 2) return i;
468 // Ignore explicitly disabled features.
469 if (Feature[0] == '-') continue;
470
471 // Feature strings are of the form "+feature".
472 if (Feature[0] != '+') return i;
473
474 // The set of supported subtarget features is defined in
475 // lib/Target/X86/X86.td. Here we recognize and map onto our internal
476 // state.
477 if (Feature == "+mmx")
478 SSELevel = std::max(SSELevel, MMX);
479 else if (Feature == "+sse")
480 SSELevel = std::max(SSELevel, SSE1);
481 else if (Feature == "+sse2")
482 SSELevel = std::max(SSELevel, SSE2);
483 else if (Feature == "+sse3")
484 SSELevel = std::max(SSELevel, SSE3);
485 else if (Feature == "+ssse3")
486 SSELevel = std::max(SSELevel, SSSE3);
487 else if (Feature == "+sse41")
488 SSELevel = std::max(SSELevel, SSE41);
489 else if (Feature == "+sse42")
490 SSELevel = std::max(SSELevel, SSE42);
491 else if (Feature == "+64bit" || Feature == "+slow-bt-mem")
492 // Ignore these features.
493 continue;
494 else
495 return i;
496 }
497 return -1;
Chris Lattner3daed522009-03-02 22:20:04 +0000498}
Chris Lattnerc0f59212009-03-02 22:27:17 +0000499
500/// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines
501/// that are not tied to a specific subtarget.
502void X86TargetInfo::getTargetDefines(std::vector<char> &Defs) const {
503 // Target identification.
504 if (PointerWidth == 64) {
505 Define(Defs, "_LP64");
506 Define(Defs, "__LP64__");
507 Define(Defs, "__amd64__");
508 Define(Defs, "__amd64");
509 Define(Defs, "__x86_64");
510 Define(Defs, "__x86_64__");
511 Define(Defs, "__SSE3__");
512 } else {
513 Define(Defs, "__i386__");
514 Define(Defs, "__i386");
515 Define(Defs, "i386");
516 }
517
518 // Target properties.
519 Define(Defs, "__LITTLE_ENDIAN__");
520
521 // Subtarget options.
522 Define(Defs, "__nocona");
523 Define(Defs, "__nocona__");
524 Define(Defs, "__tune_nocona__");
Chris Lattnerc0f59212009-03-02 22:27:17 +0000525 Define(Defs, "__REGISTER_PREFIX__", "");
Chris Lattner84f0ea82009-03-02 22:40:39 +0000526
527 // Each case falls through to the previous one here.
528 switch (SSELevel) {
529 case SSE42:
530 Define(Defs, "__SSE4_2__");
531 case SSE41:
532 Define(Defs, "__SSE4_1__");
533 case SSSE3:
534 Define(Defs, "__SSSE3__");
535 case SSE3:
536 Define(Defs, "__SSE3__");
537 case SSE2:
538 Define(Defs, "__SSE2__");
539 Define(Defs, "__SSE2_MATH__"); // -mfp-math=sse always implied.
540 case SSE1:
541 Define(Defs, "__SSE__");
542 Define(Defs, "__SSE_MATH__"); // -mfp-math=sse always implied.
543 case MMX:
544 Define(Defs, "__MMX__");
545 case NoMMXSSE:
546 break;
547 }
Chris Lattnerc0f59212009-03-02 22:27:17 +0000548}
549
Eli Friedman618234a2008-08-20 02:34:37 +0000550
551bool
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000552X86TargetInfo::validateAsmConstraint(const char *&Name,
Eli Friedman618234a2008-08-20 02:34:37 +0000553 TargetInfo::ConstraintInfo &info) const {
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000554 switch (*Name) {
Eli Friedman618234a2008-08-20 02:34:37 +0000555 default: return false;
556 case 'a': // eax.
557 case 'b': // ebx.
558 case 'c': // ecx.
559 case 'd': // edx.
560 case 'S': // esi.
561 case 'D': // edi.
562 case 'A': // edx:eax.
563 case 't': // top of floating point stack.
564 case 'u': // second from top of floating point stack.
565 case 'q': // Any register accessible as [r]l: a, b, c, and d.
Anders Carlssonfce09342008-10-06 00:41:45 +0000566 case 'y': // Any MMX register.
Anders Carlssona7406d42008-10-06 19:17:39 +0000567 case 'x': // Any SSE register.
Eli Friedman618234a2008-08-20 02:34:37 +0000568 case 'Q': // Any register accessible as [r]h: a, b, c, and d.
Anders Carlsson79bc64c2009-01-24 18:03:09 +0000569 case 'e': // 32-bit signed integer constant for use with zero-extending
570 // x86_64 instructions.
571 case 'Z': // 32-bit unsigned integer constant for use with zero-extending
572 // x86_64 instructions.
Eli Friedman618234a2008-08-20 02:34:37 +0000573 case 'N': // unsigned 8-bit integer constant for use with in and out
574 // instructions.
575 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
576 return true;
577 }
578}
579
580std::string
581X86TargetInfo::convertConstraint(const char Constraint) const {
582 switch (Constraint) {
583 case 'a': return std::string("{ax}");
584 case 'b': return std::string("{bx}");
585 case 'c': return std::string("{cx}");
586 case 'd': return std::string("{dx}");
587 case 'S': return std::string("{si}");
588 case 'D': return std::string("{di}");
589 case 't': // top of floating point stack.
590 return std::string("{st}");
591 case 'u': // second from top of floating point stack.
592 return std::string("{st(1)}"); // second from top of floating point stack.
593 default:
594 return std::string(1, Constraint);
595 }
596}
Eli Friedman618234a2008-08-20 02:34:37 +0000597} // end anonymous namespace
Reid Spencer5f016e22007-07-11 17:01:13 +0000598
599namespace {
Eli Friedman618234a2008-08-20 02:34:37 +0000600// X86-32 generic target
601class X86_32TargetInfo : public X86TargetInfo {
Reid Spencer5f016e22007-07-11 17:01:13 +0000602public:
Eli Friedman618234a2008-08-20 02:34:37 +0000603 X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
604 DoubleAlign = LongLongAlign = 32;
605 LongDoubleWidth = 96;
606 LongDoubleAlign = 32;
Eli Friedmaned855cb2008-08-21 00:13:15 +0000607 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
608 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
609 "a0:0:64-f80:32:32";
Eli Friedman618234a2008-08-20 02:34:37 +0000610 }
611 virtual const char *getVAListDeclaration() const {
Eli Friedman01b86682008-08-20 07:28:14 +0000612 return "typedef char* __builtin_va_list;";
Eli Friedman618234a2008-08-20 02:34:37 +0000613 }
Eli Friedman618234a2008-08-20 02:34:37 +0000614};
615} // end anonymous namespace
616
617namespace {
618// x86-32 Darwin (OS X) target
619class DarwinI386TargetInfo : public X86_32TargetInfo {
620public:
621 DarwinI386TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
622 LongDoubleWidth = 128;
623 LongDoubleAlign = 128;
Chris Lattnerd427ad42009-02-05 07:19:24 +0000624 PtrDiffType = SignedInt;
Eli Friedmaned855cb2008-08-21 00:13:15 +0000625 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
626 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
627 "a0:0:64-f80:128:128";
Eli Friedman618234a2008-08-20 02:34:37 +0000628 }
629 virtual void getTargetDefines(std::vector<char> &Defines) const {
630 X86_32TargetInfo::getTargetDefines(Defines);
Chris Lattner8b30c412008-09-30 01:00:25 +0000631 getDarwinDefines(Defines, getTargetTriple());
Eli Friedman618234a2008-08-20 02:34:37 +0000632 }
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000633 /// getDefaultLangOptions - Allow the target to specify default settings for
634 /// various language options. These may be overridden by command line
635 /// options.
636 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattnerae0ee032008-12-04 23:20:07 +0000637 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000638 }
Eli Friedman618234a2008-08-20 02:34:37 +0000639};
640} // end anonymous namespace
641
642namespace {
Chris Lattnerfd0269d2008-10-16 17:04:31 +0000643// x86-32 FreeBSD target
644class FreeBSDX86_32TargetInfo : public X86_32TargetInfo {
645public:
Eli Friedmanf509d732008-11-02 02:43:55 +0000646 FreeBSDX86_32TargetInfo(const std::string& triple) :
647 X86_32TargetInfo(triple) {
648 SizeType = UnsignedInt;
649 PtrDiffType = SignedInt;
Chris Lattnerfd0269d2008-10-16 17:04:31 +0000650 }
651 virtual void getTargetDefines(std::vector<char> &Defines) const {
652 X86_32TargetInfo::getTargetDefines(Defines);
653 getFreeBSDDefines(Defines, 0, getTargetTriple());
654 }
655};
656} // end anonymous namespace
657
658namespace {
Chris Lattnereac7aee2008-08-23 18:23:14 +0000659// x86-32 DragonFly target
660class DragonFlyX86_32TargetInfo : public X86_32TargetInfo {
661public:
Eli Friedmanf509d732008-11-02 02:43:55 +0000662 DragonFlyX86_32TargetInfo(const std::string& triple) :
663 X86_32TargetInfo(triple) {
664 SizeType = UnsignedInt;
665 PtrDiffType = SignedInt;
Chris Lattnereac7aee2008-08-23 18:23:14 +0000666 }
667 virtual void getTargetDefines(std::vector<char> &Defines) const {
668 X86_32TargetInfo::getTargetDefines(Defines);
669 getDragonFlyDefines(Defines);
670 }
671};
672} // end anonymous namespace
673
674namespace {
Eli Friedman0d4047b2008-08-21 00:24:02 +0000675// x86-32 Linux target
676class LinuxX86_32TargetInfo : public X86_32TargetInfo {
677public:
678 LinuxX86_32TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
Chris Lattner9b533162008-10-05 19:44:25 +0000679 UserLabelPrefix = "";
Eli Friedmanf509d732008-11-02 02:43:55 +0000680 SizeType = UnsignedInt;
681 PtrDiffType = SignedInt;
Chris Lattner6ad474f2009-02-13 22:28:55 +0000682 IntPtrType = SignedInt;
Eli Friedman0d4047b2008-08-21 00:24:02 +0000683 }
684 virtual void getTargetDefines(std::vector<char> &Defines) const {
685 X86_32TargetInfo::getTargetDefines(Defines);
686 getLinuxDefines(Defines);
687 }
688};
689} // end anonymous namespace
690
691namespace {
Eli Friedman29a30502008-08-21 01:40:19 +0000692// x86-32 Windows target
693class WindowsX86_32TargetInfo : public X86_32TargetInfo {
694public:
695 WindowsX86_32TargetInfo(const std::string& triple)
696 : X86_32TargetInfo(triple) {
697 // FIXME: Fix wchar_t.
698 // FIXME: We should probably enable -fms-extensions by default for
699 // this target.
Eli Friedmanf509d732008-11-02 02:43:55 +0000700 SizeType = UnsignedInt;
701 PtrDiffType = SignedInt;
Eli Friedman29a30502008-08-21 01:40:19 +0000702 }
703 virtual void getTargetDefines(std::vector<char> &Defines) const {
704 X86_32TargetInfo::getTargetDefines(Defines);
705 // This list is based off of the the list of things MingW defines
706 Define(Defines, "__WIN32__");
707 Define(Defines, "__WIN32");
708 Define(Defines, "_WIN32");
709 Define(Defines, "WIN32");
710 Define(Defines, "__WINNT__");
711 Define(Defines, "__WINNT");
712 Define(Defines, "WINNT");
Eli Friedman29a30502008-08-21 01:40:19 +0000713 Define(Defines, "_X86_");
714 Define(Defines, "__MSVCRT__");
715 }
716};
717} // end anonymous namespace
718
719namespace {
Eli Friedman618234a2008-08-20 02:34:37 +0000720// x86-64 generic target
721class X86_64TargetInfo : public X86TargetInfo {
722public:
723 X86_64TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
Chris Lattnerf291b102008-05-09 06:17:04 +0000724 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Chris Lattner778601f2009-01-28 06:58:19 +0000725 DoubleAlign = LongLongAlign = 64;
Eli Friedman61538a72008-05-20 14:21:01 +0000726 LongDoubleWidth = 128;
727 LongDoubleAlign = 128;
Chris Lattner06ebe862009-02-05 07:32:46 +0000728 IntMaxType = SignedLong;
729 UIntMaxType = UnsignedLong;
730
Eli Friedmaned855cb2008-08-21 00:13:15 +0000731 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
732 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
733 "a0:0:64-f80:128:128";
Reid Spencer5f016e22007-07-11 17:01:13 +0000734 }
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000735 virtual const char *getVAListDeclaration() const {
Eli Friedman01b86682008-08-20 07:28:14 +0000736 return "typedef struct __va_list_tag {"
737 " unsigned gp_offset;"
738 " unsigned fp_offset;"
739 " void* overflow_arg_area;"
740 " void* reg_save_area;"
741 "} __builtin_va_list[1];";
Anders Carlsson3346ae62007-11-24 23:38:12 +0000742 }
Eli Friedman618234a2008-08-20 02:34:37 +0000743};
744} // end anonymous namespace
745
746namespace {
Chris Lattnerfd0269d2008-10-16 17:04:31 +0000747// x86-64 FreeBSD target
748class FreeBSDX86_64TargetInfo : public X86_64TargetInfo {
749public:
Eli Friedmanf509d732008-11-02 02:43:55 +0000750 FreeBSDX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) {}
Chris Lattnerfd0269d2008-10-16 17:04:31 +0000751 virtual void getTargetDefines(std::vector<char> &Defines) const {
752 X86_64TargetInfo::getTargetDefines(Defines);
753 getFreeBSDDefines(Defines, 1, getTargetTriple());
754 }
755};
756} // end anonymous namespace
757
758namespace {
Daniel Dunbarb55a42b2008-09-23 17:37:57 +0000759// x86-64 Linux target
760class LinuxX86_64TargetInfo : public X86_64TargetInfo {
761public:
762 LinuxX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) {
Chris Lattner9b533162008-10-05 19:44:25 +0000763 UserLabelPrefix = "";
Daniel Dunbarb55a42b2008-09-23 17:37:57 +0000764 }
765 virtual void getTargetDefines(std::vector<char> &Defines) const {
766 X86_64TargetInfo::getTargetDefines(Defines);
767 getLinuxDefines(Defines);
Daniel Dunbarb55a42b2008-09-23 17:37:57 +0000768 }
769};
770} // end anonymous namespace
771
772namespace {
Eli Friedman618234a2008-08-20 02:34:37 +0000773// x86-64 Darwin (OS X) target
774class DarwinX86_64TargetInfo : public X86_64TargetInfo {
775public:
776 DarwinX86_64TargetInfo(const std::string& triple) :
777 X86_64TargetInfo(triple) {}
778
779 virtual void getTargetDefines(std::vector<char> &Defines) const {
780 X86_64TargetInfo::getTargetDefines(Defines);
Chris Lattner8b30c412008-09-30 01:00:25 +0000781 getDarwinDefines(Defines, getTargetTriple());
Anders Carlsson3346ae62007-11-24 23:38:12 +0000782 }
Daniel Dunbardcb4a1a2008-08-23 08:43:39 +0000783
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000784 /// getDefaultLangOptions - Allow the target to specify default settings for
785 /// various language options. These may be overridden by command line
786 /// options.
787 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattnerae0ee032008-12-04 23:20:07 +0000788 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000789 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000790};
791} // end anonymous namespace.
792
Chris Lattner393ff042008-04-21 18:56:49 +0000793namespace {
Eli Friedmana9f54962008-08-20 07:44:10 +0000794class ARMTargetInfo : public TargetInfo {
Chris Lattner393ff042008-04-21 18:56:49 +0000795public:
Eli Friedmana9f54962008-08-20 07:44:10 +0000796 ARMTargetInfo(const std::string& triple) : TargetInfo(triple) {
797 // FIXME: Are the defaults correct for ARM?
Eli Friedmaned855cb2008-08-21 00:13:15 +0000798 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
799 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:64";
Eli Friedman61538a72008-05-20 14:21:01 +0000800 }
Chris Lattnerc0f59212009-03-02 22:27:17 +0000801 virtual void getTargetDefines(std::vector<char> &Defs) const {
802 // Target identification.
803 Define(Defs, "__arm");
804 Define(Defs, "__arm__");
805
806 // Target properties.
807 Define(Defs, "__LITTLE_ENDIAN__");
808
809 // Subtarget options. [hard coded to v6 for now]
810 Define(Defs, "__ARM_ARCH_6K__");
811 Define(Defs, "__ARMEL__");
812 Define(Defs, "__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", "20000");
Chris Lattner393ff042008-04-21 18:56:49 +0000813 }
814 virtual void getTargetBuiltins(const Builtin::Info *&Records,
815 unsigned &NumRecords) const {
Eli Friedmana9f54962008-08-20 07:44:10 +0000816 // FIXME: Implement.
817 Records = 0;
Chris Lattner393ff042008-04-21 18:56:49 +0000818 NumRecords = 0;
819 }
820 virtual const char *getVAListDeclaration() const {
Eli Friedmana9f54962008-08-20 07:44:10 +0000821 return "typedef char* __builtin_va_list;";
Chris Lattner393ff042008-04-21 18:56:49 +0000822 }
823 virtual const char *getTargetPrefix() const {
Eli Friedmana9f54962008-08-20 07:44:10 +0000824 return "arm";
Chris Lattner393ff042008-04-21 18:56:49 +0000825 }
Chris Lattner393ff042008-04-21 18:56:49 +0000826 virtual void getGCCRegNames(const char * const *&Names,
827 unsigned &NumNames) const {
Eli Friedmana9f54962008-08-20 07:44:10 +0000828 // FIXME: Implement.
829 Names = 0;
Chris Lattner393ff042008-04-21 18:56:49 +0000830 NumNames = 0;
831 }
832 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
833 unsigned &NumAliases) const {
Eli Friedmana9f54962008-08-20 07:44:10 +0000834 // FIXME: Implement.
835 Aliases = 0;
Chris Lattner393ff042008-04-21 18:56:49 +0000836 NumAliases = 0;
837 }
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000838 virtual bool validateAsmConstraint(const char *&Name,
Nate Begemanad487f42008-04-22 05:03:19 +0000839 TargetInfo::ConstraintInfo &info) const {
Eli Friedmana9f54962008-08-20 07:44:10 +0000840 // FIXME: Check if this is complete
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000841 switch (*Name) {
Eli Friedmana9f54962008-08-20 07:44:10 +0000842 default:
Nate Begemanad487f42008-04-22 05:03:19 +0000843 case 'l': // r0-r7
844 case 'h': // r8-r15
845 case 'w': // VFP Floating point register single precision
846 case 'P': // VFP Floating point register double precision
847 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
848 return true;
849 }
Chris Lattner393ff042008-04-21 18:56:49 +0000850 return false;
851 }
852 virtual const char *getClobbers() const {
Eli Friedmana9f54962008-08-20 07:44:10 +0000853 // FIXME: Is this really right?
Chris Lattner393ff042008-04-21 18:56:49 +0000854 return "";
855 }
856};
857} // end anonymous namespace.
858
Eli Friedmana9f54962008-08-20 07:44:10 +0000859
860namespace {
861class DarwinARMTargetInfo : public ARMTargetInfo {
862public:
863 DarwinARMTargetInfo(const std::string& triple) : ARMTargetInfo(triple) {}
864
865 virtual void getTargetDefines(std::vector<char> &Defines) const {
866 ARMTargetInfo::getTargetDefines(Defines);
Chris Lattner8b30c412008-09-30 01:00:25 +0000867 getDarwinDefines(Defines, getTargetTriple());
Eli Friedmana9f54962008-08-20 07:44:10 +0000868 }
869};
870} // end anonymous namespace.
871
Reid Spencer5f016e22007-07-11 17:01:13 +0000872namespace {
Eli Friedman01b86682008-08-20 07:28:14 +0000873class SparcV8TargetInfo : public TargetInfo {
Chris Lattnere957f532009-01-27 01:58:38 +0000874 static const TargetInfo::GCCRegAlias GCCRegAliases[];
875 static const char * const GCCRegNames[];
Gabor Greif26658672008-02-21 16:29:08 +0000876public:
Eli Friedman01b86682008-08-20 07:28:14 +0000877 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
878 // FIXME: Support Sparc quad-precision long double?
Eli Friedmaned855cb2008-08-21 00:13:15 +0000879 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
880 "i64:64:64-f32:32:32-f64:64:64-v64:64:64";
Eli Friedman01b86682008-08-20 07:28:14 +0000881 }
Gabor Greif26658672008-02-21 16:29:08 +0000882 virtual void getTargetDefines(std::vector<char> &Defines) const {
Eli Friedman01b86682008-08-20 07:28:14 +0000883 // FIXME: This is missing a lot of important defines; some of the
884 // missing stuff is likely to break system headers.
Gabor Greif26658672008-02-21 16:29:08 +0000885 Define(Defines, "__sparc");
Eli Friedmanbf0c9bd2008-05-25 05:26:09 +0000886 Define(Defines, "__sparc__");
Gabor Greif26658672008-02-21 16:29:08 +0000887 Define(Defines, "__sparcv8");
888 }
889 virtual void getTargetBuiltins(const Builtin::Info *&Records,
890 unsigned &NumRecords) const {
Eli Friedman01b86682008-08-20 07:28:14 +0000891 // FIXME: Implement!
Gabor Greif26658672008-02-21 16:29:08 +0000892 }
893 virtual const char *getVAListDeclaration() const {
Eli Friedman01b86682008-08-20 07:28:14 +0000894 return "typedef void* __builtin_va_list;";
Gabor Greif26658672008-02-21 16:29:08 +0000895 }
896 virtual const char *getTargetPrefix() const {
Eli Friedman01b86682008-08-20 07:28:14 +0000897 return "sparc";
Gabor Greif26658672008-02-21 16:29:08 +0000898 }
899 virtual void getGCCRegNames(const char * const *&Names,
Chris Lattnere957f532009-01-27 01:58:38 +0000900 unsigned &NumNames) const;
Gabor Greif26658672008-02-21 16:29:08 +0000901 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattnere957f532009-01-27 01:58:38 +0000902 unsigned &NumAliases) const;
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000903 virtual bool validateAsmConstraint(const char *&Name,
Gabor Greif26658672008-02-21 16:29:08 +0000904 TargetInfo::ConstraintInfo &info) const {
Eli Friedman01b86682008-08-20 07:28:14 +0000905 // FIXME: Implement!
906 return false;
Gabor Greif26658672008-02-21 16:29:08 +0000907 }
908 virtual const char *getClobbers() const {
Eli Friedman01b86682008-08-20 07:28:14 +0000909 // FIXME: Implement!
910 return "";
Gabor Greif26658672008-02-21 16:29:08 +0000911 }
912};
913
Chris Lattnere957f532009-01-27 01:58:38 +0000914const char * const SparcV8TargetInfo::GCCRegNames[] = {
915 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
916 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
917 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
918 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
919};
920
921void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names,
922 unsigned &NumNames) const {
923 Names = GCCRegNames;
924 NumNames = llvm::array_lengthof(GCCRegNames);
925}
926
927const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = {
928 { { "g0" }, "r0" },
929 { { "g1" }, "r1" },
930 { { "g2" }, "r2" },
931 { { "g3" }, "r3" },
932 { { "g4" }, "r4" },
933 { { "g5" }, "r5" },
934 { { "g6" }, "r6" },
935 { { "g7" }, "r7" },
936 { { "o0" }, "r8" },
937 { { "o1" }, "r9" },
938 { { "o2" }, "r10" },
939 { { "o3" }, "r11" },
940 { { "o4" }, "r12" },
941 { { "o5" }, "r13" },
942 { { "o6", "sp" }, "r14" },
943 { { "o7" }, "r15" },
944 { { "l0" }, "r16" },
945 { { "l1" }, "r17" },
946 { { "l2" }, "r18" },
947 { { "l3" }, "r19" },
948 { { "l4" }, "r20" },
949 { { "l5" }, "r21" },
950 { { "l6" }, "r22" },
951 { { "l7" }, "r23" },
952 { { "i0" }, "r24" },
953 { { "i1" }, "r25" },
954 { { "i2" }, "r26" },
955 { { "i3" }, "r27" },
956 { { "i4" }, "r28" },
957 { { "i5" }, "r29" },
958 { { "i6", "fp" }, "r30" },
959 { { "i7" }, "r31" },
960};
961
962void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
963 unsigned &NumAliases) const {
964 Aliases = GCCRegAliases;
965 NumAliases = llvm::array_lengthof(GCCRegAliases);
966}
Gabor Greif26658672008-02-21 16:29:08 +0000967} // end anonymous namespace.
968
Eli Friedman01b86682008-08-20 07:28:14 +0000969namespace {
970class SolarisSparcV8TargetInfo : public SparcV8TargetInfo {
971public:
972 SolarisSparcV8TargetInfo(const std::string& triple) :
Eli Friedmanf509d732008-11-02 02:43:55 +0000973 SparcV8TargetInfo(triple) {
974 SizeType = UnsignedInt;
975 PtrDiffType = SignedInt;
976 }
Eli Friedman01b86682008-08-20 07:28:14 +0000977
978 virtual void getTargetDefines(std::vector<char> &Defines) const {
979 SparcV8TargetInfo::getTargetDefines(Defines);
980 getSolarisDefines(Defines);
981 }
982};
983} // end anonymous namespace.
Reid Spencer5f016e22007-07-11 17:01:13 +0000984
Chris Lattner2621fd12008-05-08 05:58:21 +0000985namespace {
986 class PIC16TargetInfo : public TargetInfo{
987 public:
988 PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) {
Sanjiv Gupta31fc07d2008-10-31 09:52:39 +0000989 IntWidth = 16;
990 LongWidth = LongLongWidth = 32;
991 PointerWidth = 16;
992 IntAlign = 8;
993 LongAlign = LongLongAlign = 8;
Eli Friedman61538a72008-05-20 14:21:01 +0000994 PointerAlign = 8;
Sanjiv Gupta31fc07d2008-10-31 09:52:39 +0000995 SizeType = UnsignedInt;
996 IntMaxType = SignedLong;
997 UIntMaxType = UnsignedLong;
Chris Lattner6ad474f2009-02-13 22:28:55 +0000998 IntPtrType = SignedShort;
Eli Friedmanf509d732008-11-02 02:43:55 +0000999 PtrDiffType = SignedInt;
Sanjiv Gupta364af812008-08-18 10:05:22 +00001000 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8";
Chris Lattner2621fd12008-05-08 05:58:21 +00001001 }
Chris Lattner927686f2008-05-09 06:08:39 +00001002 virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; }
1003 virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; }
Chris Lattner2621fd12008-05-08 05:58:21 +00001004 virtual void getTargetDefines(std::vector<char> &Defines) const {
1005 Define(Defines, "__pic16");
1006 }
1007 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1008 unsigned &NumRecords) const {}
1009 virtual const char *getVAListDeclaration() const { return "";}
1010 virtual const char *getClobbers() const {return "";}
1011 virtual const char *getTargetPrefix() const {return "";}
1012 virtual void getGCCRegNames(const char * const *&Names,
1013 unsigned &NumNames) const {}
Anders Carlsson066d2ea2009-02-28 17:11:49 +00001014 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattner2621fd12008-05-08 05:58:21 +00001015 TargetInfo::ConstraintInfo &info) const {
1016 return true;
1017 }
1018 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1019 unsigned &NumAliases) const {}
1020 virtual bool useGlobalsForAutomaticVariables() const {return true;}
1021 };
1022}
1023
Reid Spencer5f016e22007-07-11 17:01:13 +00001024//===----------------------------------------------------------------------===//
1025// Driver code
1026//===----------------------------------------------------------------------===//
1027
Ted Kremenek8448d382007-12-04 17:07:35 +00001028static inline bool IsX86(const std::string& TT) {
Ted Kremenekae360762007-12-03 22:06:55 +00001029 return (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' &&
1030 TT[4] == '-' && TT[1] - '3' < 6);
1031}
1032
Chris Lattner42e67372008-03-05 01:18:20 +00001033/// CreateTargetInfo - Return the target info object for the specified target
1034/// triple.
1035TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
Eli Friedmaned855cb2008-08-21 00:13:15 +00001036 // OS detection; this isn't really anywhere near complete.
1037 // Additions and corrections are welcome.
1038 bool isDarwin = T.find("-darwin") != std::string::npos;
Chris Lattnereac7aee2008-08-23 18:23:14 +00001039 bool isDragonFly = T.find("-dragonfly") != std::string::npos;
Chris Lattnerfd0269d2008-10-16 17:04:31 +00001040 bool isFreeBSD = T.find("-freebsd") != std::string::npos;
Eli Friedmaned855cb2008-08-21 00:13:15 +00001041 bool isSolaris = T.find("-solaris") != std::string::npos;
1042 bool isLinux = T.find("-linux") != std::string::npos;
1043 bool isWindows = T.find("-windows") != std::string::npos ||
1044 T.find("-win32") != std::string::npos ||
1045 T.find("-mingw") != std::string::npos;
Eli Friedman61538a72008-05-20 14:21:01 +00001046
Eli Friedmaned855cb2008-08-21 00:13:15 +00001047 if (T.find("ppc-") == 0 || T.find("powerpc-") == 0) {
1048 if (isDarwin)
1049 return new DarwinPPCTargetInfo(T);
1050 return new PPC32TargetInfo(T);
1051 }
Eli Friedman61538a72008-05-20 14:21:01 +00001052
Eli Friedmaned855cb2008-08-21 00:13:15 +00001053 if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0) {
1054 if (isDarwin)
1055 return new DarwinPPC64TargetInfo(T);
1056 return new PPC64TargetInfo(T);
1057 }
Chris Lattner393ff042008-04-21 18:56:49 +00001058
Eli Friedmaned855cb2008-08-21 00:13:15 +00001059 if (T.find("armv6-") == 0 || T.find("arm-") == 0) {
1060 if (isDarwin)
1061 return new DarwinARMTargetInfo(T);
1062 return new ARMTargetInfo(T);
1063 }
Eli Friedman61538a72008-05-20 14:21:01 +00001064
Eli Friedmaned855cb2008-08-21 00:13:15 +00001065 if (T.find("sparc-") == 0) {
1066 if (isSolaris)
1067 return new SolarisSparcV8TargetInfo(T);
1068 return new SparcV8TargetInfo(T);
1069 }
1070
Chris Lattner54fefbe2009-02-20 17:04:14 +00001071 if (T.find("x86_64-") == 0 || T.find("amd64-") == 0) {
Eli Friedmaned855cb2008-08-21 00:13:15 +00001072 if (isDarwin)
1073 return new DarwinX86_64TargetInfo(T);
Daniel Dunbarb55a42b2008-09-23 17:37:57 +00001074 if (isLinux)
1075 return new LinuxX86_64TargetInfo(T);
Chris Lattnerfd0269d2008-10-16 17:04:31 +00001076 if (isFreeBSD)
1077 return new FreeBSDX86_64TargetInfo(T);
Eli Friedmaned855cb2008-08-21 00:13:15 +00001078 return new X86_64TargetInfo(T);
1079 }
Eli Friedman61538a72008-05-20 14:21:01 +00001080
Chris Lattner2621fd12008-05-08 05:58:21 +00001081 if (T.find("pic16-") == 0)
1082 return new PIC16TargetInfo(T);
1083
Eli Friedmaned855cb2008-08-21 00:13:15 +00001084 if (IsX86(T)) {
1085 if (isDarwin)
1086 return new DarwinI386TargetInfo(T);
Eli Friedman0d4047b2008-08-21 00:24:02 +00001087 if (isLinux)
1088 return new LinuxX86_32TargetInfo(T);
Chris Lattnereac7aee2008-08-23 18:23:14 +00001089 if (isDragonFly)
1090 return new DragonFlyX86_32TargetInfo(T);
Chris Lattnerfd0269d2008-10-16 17:04:31 +00001091 if (isFreeBSD)
1092 return new FreeBSDX86_32TargetInfo(T);
Eli Friedman29a30502008-08-21 01:40:19 +00001093 if (isWindows)
1094 return new WindowsX86_32TargetInfo(T);
Eli Friedmaned855cb2008-08-21 00:13:15 +00001095 return new X86_32TargetInfo(T);
1096 }
Eli Friedman61538a72008-05-20 14:21:01 +00001097
Chris Lattner42e67372008-03-05 01:18:20 +00001098 return NULL;
Reid Spencer5f016e22007-07-11 17:01:13 +00001099}
Ted Kremenekfb79f7c2008-03-04 17:47:18 +00001100