blob: bb9c861a17094821da0d56d6ee0684a81a78925b [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)
423 : TargetInfo(triple), SSELevel(SSE2) {
Eli Friedman618234a2008-08-20 02:34:37 +0000424 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
Reid Spencer5f016e22007-07-11 17:01:13 +0000425 }
426 virtual void getTargetBuiltins(const Builtin::Info *&Records,
427 unsigned &NumRecords) const {
Eli Friedman618234a2008-08-20 02:34:37 +0000428 Records = BuiltinInfo;
429 NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
Reid Spencer5f016e22007-07-11 17:01:13 +0000430 }
Anders Carlsson44fe49c2007-12-08 19:32:57 +0000431 virtual const char *getTargetPrefix() const {
Eli Friedman618234a2008-08-20 02:34:37 +0000432 return "x86";
Anders Carlsson44fe49c2007-12-08 19:32:57 +0000433 }
Anders Carlsson3346ae62007-11-24 23:38:12 +0000434 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedman618234a2008-08-20 02:34:37 +0000435 unsigned &NumNames) const {
436 Names = GCCRegNames;
437 NumNames = llvm::array_lengthof(GCCRegNames);
Anders Carlsson3346ae62007-11-24 23:38:12 +0000438 }
439 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
440 unsigned &NumAliases) const {
Eli Friedman618234a2008-08-20 02:34:37 +0000441 Aliases = GCCRegAliases;
442 NumAliases = llvm::array_lengthof(GCCRegAliases);
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000443 }
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000444 virtual bool validateAsmConstraint(const char *&Name,
Eli Friedman618234a2008-08-20 02:34:37 +0000445 TargetInfo::ConstraintInfo &info) const;
446 virtual std::string convertConstraint(const char Constraint) const;
Anders Carlssond04c6e22007-11-27 04:11:28 +0000447 virtual const char *getClobbers() const {
Eli Friedman618234a2008-08-20 02:34:37 +0000448 return "~{dirflag},~{fpsr},~{flags}";
449 }
Chris Lattnerc0f59212009-03-02 22:27:17 +0000450 virtual void getTargetDefines(std::vector<char> &Defines) const;
Chris Lattner3daed522009-03-02 22:20:04 +0000451
452 virtual int HandleTargetOptions(std::string *StrArray, unsigned NumStrs,
453 std::string &ErrorReason);
Reid Spencer5f016e22007-07-11 17:01:13 +0000454};
Chris Lattner3daed522009-03-02 22:20:04 +0000455
456/// HandleTargetOptions - Handle target-specific options like -msse2 and
457/// friends. An array of arguments is passed in: if they are all valid, this
458/// should handle them and return -1. If there is an error, the index of the
459/// invalid argument should be returned along with an optional error string.
460int X86TargetInfo::HandleTargetOptions(std::string *StrArray, unsigned NumStrs,
461 std::string &ErrorReason) {
462 if (NumStrs == 0)
463 return -1;
464 return 0;
465}
Chris Lattnerc0f59212009-03-02 22:27:17 +0000466
467/// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines
468/// that are not tied to a specific subtarget.
469void X86TargetInfo::getTargetDefines(std::vector<char> &Defs) const {
470 // Target identification.
471 if (PointerWidth == 64) {
472 Define(Defs, "_LP64");
473 Define(Defs, "__LP64__");
474 Define(Defs, "__amd64__");
475 Define(Defs, "__amd64");
476 Define(Defs, "__x86_64");
477 Define(Defs, "__x86_64__");
478 Define(Defs, "__SSE3__");
479 } else {
480 Define(Defs, "__i386__");
481 Define(Defs, "__i386");
482 Define(Defs, "i386");
483 }
484
485 // Target properties.
486 Define(Defs, "__LITTLE_ENDIAN__");
487
488 // Subtarget options.
489 Define(Defs, "__nocona");
490 Define(Defs, "__nocona__");
491 Define(Defs, "__tune_nocona__");
Chris Lattnerc0f59212009-03-02 22:27:17 +0000492 Define(Defs, "__REGISTER_PREFIX__", "");
Chris Lattner84f0ea82009-03-02 22:40:39 +0000493
494 // Each case falls through to the previous one here.
495 switch (SSELevel) {
496 case SSE42:
497 Define(Defs, "__SSE4_2__");
498 case SSE41:
499 Define(Defs, "__SSE4_1__");
500 case SSSE3:
501 Define(Defs, "__SSSE3__");
502 case SSE3:
503 Define(Defs, "__SSE3__");
504 case SSE2:
505 Define(Defs, "__SSE2__");
506 Define(Defs, "__SSE2_MATH__"); // -mfp-math=sse always implied.
507 case SSE1:
508 Define(Defs, "__SSE__");
509 Define(Defs, "__SSE_MATH__"); // -mfp-math=sse always implied.
510 case MMX:
511 Define(Defs, "__MMX__");
512 case NoMMXSSE:
513 break;
514 }
Chris Lattnerc0f59212009-03-02 22:27:17 +0000515}
516
Eli Friedman618234a2008-08-20 02:34:37 +0000517
518bool
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000519X86TargetInfo::validateAsmConstraint(const char *&Name,
Eli Friedman618234a2008-08-20 02:34:37 +0000520 TargetInfo::ConstraintInfo &info) const {
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000521 switch (*Name) {
Eli Friedman618234a2008-08-20 02:34:37 +0000522 default: return false;
523 case 'a': // eax.
524 case 'b': // ebx.
525 case 'c': // ecx.
526 case 'd': // edx.
527 case 'S': // esi.
528 case 'D': // edi.
529 case 'A': // edx:eax.
530 case 't': // top of floating point stack.
531 case 'u': // second from top of floating point stack.
532 case 'q': // Any register accessible as [r]l: a, b, c, and d.
Anders Carlssonfce09342008-10-06 00:41:45 +0000533 case 'y': // Any MMX register.
Anders Carlssona7406d42008-10-06 19:17:39 +0000534 case 'x': // Any SSE register.
Eli Friedman618234a2008-08-20 02:34:37 +0000535 case 'Q': // Any register accessible as [r]h: a, b, c, and d.
Anders Carlsson79bc64c2009-01-24 18:03:09 +0000536 case 'e': // 32-bit signed integer constant for use with zero-extending
537 // x86_64 instructions.
538 case 'Z': // 32-bit unsigned integer constant for use with zero-extending
539 // x86_64 instructions.
Eli Friedman618234a2008-08-20 02:34:37 +0000540 case 'N': // unsigned 8-bit integer constant for use with in and out
541 // instructions.
542 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
543 return true;
544 }
545}
546
547std::string
548X86TargetInfo::convertConstraint(const char Constraint) const {
549 switch (Constraint) {
550 case 'a': return std::string("{ax}");
551 case 'b': return std::string("{bx}");
552 case 'c': return std::string("{cx}");
553 case 'd': return std::string("{dx}");
554 case 'S': return std::string("{si}");
555 case 'D': return std::string("{di}");
556 case 't': // top of floating point stack.
557 return std::string("{st}");
558 case 'u': // second from top of floating point stack.
559 return std::string("{st(1)}"); // second from top of floating point stack.
560 default:
561 return std::string(1, Constraint);
562 }
563}
Eli Friedman618234a2008-08-20 02:34:37 +0000564} // end anonymous namespace
Reid Spencer5f016e22007-07-11 17:01:13 +0000565
566namespace {
Eli Friedman618234a2008-08-20 02:34:37 +0000567// X86-32 generic target
568class X86_32TargetInfo : public X86TargetInfo {
Reid Spencer5f016e22007-07-11 17:01:13 +0000569public:
Eli Friedman618234a2008-08-20 02:34:37 +0000570 X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
571 DoubleAlign = LongLongAlign = 32;
572 LongDoubleWidth = 96;
573 LongDoubleAlign = 32;
Eli Friedmaned855cb2008-08-21 00:13:15 +0000574 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
575 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
576 "a0:0:64-f80:32:32";
Eli Friedman618234a2008-08-20 02:34:37 +0000577 }
578 virtual const char *getVAListDeclaration() const {
Eli Friedman01b86682008-08-20 07:28:14 +0000579 return "typedef char* __builtin_va_list;";
Eli Friedman618234a2008-08-20 02:34:37 +0000580 }
Eli Friedman618234a2008-08-20 02:34:37 +0000581};
582} // end anonymous namespace
583
584namespace {
585// x86-32 Darwin (OS X) target
586class DarwinI386TargetInfo : public X86_32TargetInfo {
587public:
588 DarwinI386TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
589 LongDoubleWidth = 128;
590 LongDoubleAlign = 128;
Chris Lattnerd427ad42009-02-05 07:19:24 +0000591 PtrDiffType = SignedInt;
Eli Friedmaned855cb2008-08-21 00:13:15 +0000592 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
593 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
594 "a0:0:64-f80:128:128";
Eli Friedman618234a2008-08-20 02:34:37 +0000595 }
596 virtual void getTargetDefines(std::vector<char> &Defines) const {
597 X86_32TargetInfo::getTargetDefines(Defines);
Chris Lattner8b30c412008-09-30 01:00:25 +0000598 getDarwinDefines(Defines, getTargetTriple());
Eli Friedman618234a2008-08-20 02:34:37 +0000599 }
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000600 /// getDefaultLangOptions - Allow the target to specify default settings for
601 /// various language options. These may be overridden by command line
602 /// options.
603 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattnerae0ee032008-12-04 23:20:07 +0000604 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000605 }
Eli Friedman618234a2008-08-20 02:34:37 +0000606};
607} // end anonymous namespace
608
609namespace {
Chris Lattnerfd0269d2008-10-16 17:04:31 +0000610// x86-32 FreeBSD target
611class FreeBSDX86_32TargetInfo : public X86_32TargetInfo {
612public:
Eli Friedmanf509d732008-11-02 02:43:55 +0000613 FreeBSDX86_32TargetInfo(const std::string& triple) :
614 X86_32TargetInfo(triple) {
615 SizeType = UnsignedInt;
616 PtrDiffType = SignedInt;
Chris Lattnerfd0269d2008-10-16 17:04:31 +0000617 }
618 virtual void getTargetDefines(std::vector<char> &Defines) const {
619 X86_32TargetInfo::getTargetDefines(Defines);
620 getFreeBSDDefines(Defines, 0, getTargetTriple());
621 }
622};
623} // end anonymous namespace
624
625namespace {
Chris Lattnereac7aee2008-08-23 18:23:14 +0000626// x86-32 DragonFly target
627class DragonFlyX86_32TargetInfo : public X86_32TargetInfo {
628public:
Eli Friedmanf509d732008-11-02 02:43:55 +0000629 DragonFlyX86_32TargetInfo(const std::string& triple) :
630 X86_32TargetInfo(triple) {
631 SizeType = UnsignedInt;
632 PtrDiffType = SignedInt;
Chris Lattnereac7aee2008-08-23 18:23:14 +0000633 }
634 virtual void getTargetDefines(std::vector<char> &Defines) const {
635 X86_32TargetInfo::getTargetDefines(Defines);
636 getDragonFlyDefines(Defines);
637 }
638};
639} // end anonymous namespace
640
641namespace {
Eli Friedman0d4047b2008-08-21 00:24:02 +0000642// x86-32 Linux target
643class LinuxX86_32TargetInfo : public X86_32TargetInfo {
644public:
645 LinuxX86_32TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
Chris Lattner9b533162008-10-05 19:44:25 +0000646 UserLabelPrefix = "";
Eli Friedmanf509d732008-11-02 02:43:55 +0000647 SizeType = UnsignedInt;
648 PtrDiffType = SignedInt;
Chris Lattner6ad474f2009-02-13 22:28:55 +0000649 IntPtrType = SignedInt;
Eli Friedman0d4047b2008-08-21 00:24:02 +0000650 }
651 virtual void getTargetDefines(std::vector<char> &Defines) const {
652 X86_32TargetInfo::getTargetDefines(Defines);
653 getLinuxDefines(Defines);
654 }
655};
656} // end anonymous namespace
657
658namespace {
Eli Friedman29a30502008-08-21 01:40:19 +0000659// x86-32 Windows target
660class WindowsX86_32TargetInfo : public X86_32TargetInfo {
661public:
662 WindowsX86_32TargetInfo(const std::string& triple)
663 : X86_32TargetInfo(triple) {
664 // FIXME: Fix wchar_t.
665 // FIXME: We should probably enable -fms-extensions by default for
666 // this target.
Eli Friedmanf509d732008-11-02 02:43:55 +0000667 SizeType = UnsignedInt;
668 PtrDiffType = SignedInt;
Eli Friedman29a30502008-08-21 01:40:19 +0000669 }
670 virtual void getTargetDefines(std::vector<char> &Defines) const {
671 X86_32TargetInfo::getTargetDefines(Defines);
672 // This list is based off of the the list of things MingW defines
673 Define(Defines, "__WIN32__");
674 Define(Defines, "__WIN32");
675 Define(Defines, "_WIN32");
676 Define(Defines, "WIN32");
677 Define(Defines, "__WINNT__");
678 Define(Defines, "__WINNT");
679 Define(Defines, "WINNT");
Eli Friedman29a30502008-08-21 01:40:19 +0000680 Define(Defines, "_X86_");
681 Define(Defines, "__MSVCRT__");
682 }
683};
684} // end anonymous namespace
685
686namespace {
Eli Friedman618234a2008-08-20 02:34:37 +0000687// x86-64 generic target
688class X86_64TargetInfo : public X86TargetInfo {
689public:
690 X86_64TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
Chris Lattnerf291b102008-05-09 06:17:04 +0000691 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Chris Lattner778601f2009-01-28 06:58:19 +0000692 DoubleAlign = LongLongAlign = 64;
Eli Friedman61538a72008-05-20 14:21:01 +0000693 LongDoubleWidth = 128;
694 LongDoubleAlign = 128;
Chris Lattner06ebe862009-02-05 07:32:46 +0000695 IntMaxType = SignedLong;
696 UIntMaxType = UnsignedLong;
697
Eli Friedmaned855cb2008-08-21 00:13:15 +0000698 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
699 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
700 "a0:0:64-f80:128:128";
Reid Spencer5f016e22007-07-11 17:01:13 +0000701 }
Anders Carlssonfb5e5ba2007-10-13 00:45:48 +0000702 virtual const char *getVAListDeclaration() const {
Eli Friedman01b86682008-08-20 07:28:14 +0000703 return "typedef struct __va_list_tag {"
704 " unsigned gp_offset;"
705 " unsigned fp_offset;"
706 " void* overflow_arg_area;"
707 " void* reg_save_area;"
708 "} __builtin_va_list[1];";
Anders Carlsson3346ae62007-11-24 23:38:12 +0000709 }
Eli Friedman618234a2008-08-20 02:34:37 +0000710};
711} // end anonymous namespace
712
713namespace {
Chris Lattnerfd0269d2008-10-16 17:04:31 +0000714// x86-64 FreeBSD target
715class FreeBSDX86_64TargetInfo : public X86_64TargetInfo {
716public:
Eli Friedmanf509d732008-11-02 02:43:55 +0000717 FreeBSDX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) {}
Chris Lattnerfd0269d2008-10-16 17:04:31 +0000718 virtual void getTargetDefines(std::vector<char> &Defines) const {
719 X86_64TargetInfo::getTargetDefines(Defines);
720 getFreeBSDDefines(Defines, 1, getTargetTriple());
721 }
722};
723} // end anonymous namespace
724
725namespace {
Daniel Dunbarb55a42b2008-09-23 17:37:57 +0000726// x86-64 Linux target
727class LinuxX86_64TargetInfo : public X86_64TargetInfo {
728public:
729 LinuxX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) {
Chris Lattner9b533162008-10-05 19:44:25 +0000730 UserLabelPrefix = "";
Daniel Dunbarb55a42b2008-09-23 17:37:57 +0000731 }
732 virtual void getTargetDefines(std::vector<char> &Defines) const {
733 X86_64TargetInfo::getTargetDefines(Defines);
734 getLinuxDefines(Defines);
Daniel Dunbarb55a42b2008-09-23 17:37:57 +0000735 }
736};
737} // end anonymous namespace
738
739namespace {
Eli Friedman618234a2008-08-20 02:34:37 +0000740// x86-64 Darwin (OS X) target
741class DarwinX86_64TargetInfo : public X86_64TargetInfo {
742public:
743 DarwinX86_64TargetInfo(const std::string& triple) :
744 X86_64TargetInfo(triple) {}
745
746 virtual void getTargetDefines(std::vector<char> &Defines) const {
747 X86_64TargetInfo::getTargetDefines(Defines);
Chris Lattner8b30c412008-09-30 01:00:25 +0000748 getDarwinDefines(Defines, getTargetTriple());
Anders Carlsson3346ae62007-11-24 23:38:12 +0000749 }
Daniel Dunbardcb4a1a2008-08-23 08:43:39 +0000750
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000751 /// getDefaultLangOptions - Allow the target to specify default settings for
752 /// various language options. These may be overridden by command line
753 /// options.
754 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattnerae0ee032008-12-04 23:20:07 +0000755 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattner8fc4dfb2008-12-04 22:54:33 +0000756 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000757};
758} // end anonymous namespace.
759
Chris Lattner393ff042008-04-21 18:56:49 +0000760namespace {
Eli Friedmana9f54962008-08-20 07:44:10 +0000761class ARMTargetInfo : public TargetInfo {
Chris Lattner393ff042008-04-21 18:56:49 +0000762public:
Eli Friedmana9f54962008-08-20 07:44:10 +0000763 ARMTargetInfo(const std::string& triple) : TargetInfo(triple) {
764 // FIXME: Are the defaults correct for ARM?
Eli Friedmaned855cb2008-08-21 00:13:15 +0000765 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
766 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:64";
Eli Friedman61538a72008-05-20 14:21:01 +0000767 }
Chris Lattnerc0f59212009-03-02 22:27:17 +0000768 virtual void getTargetDefines(std::vector<char> &Defs) const {
769 // Target identification.
770 Define(Defs, "__arm");
771 Define(Defs, "__arm__");
772
773 // Target properties.
774 Define(Defs, "__LITTLE_ENDIAN__");
775
776 // Subtarget options. [hard coded to v6 for now]
777 Define(Defs, "__ARM_ARCH_6K__");
778 Define(Defs, "__ARMEL__");
779 Define(Defs, "__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", "20000");
Chris Lattner393ff042008-04-21 18:56:49 +0000780 }
781 virtual void getTargetBuiltins(const Builtin::Info *&Records,
782 unsigned &NumRecords) const {
Eli Friedmana9f54962008-08-20 07:44:10 +0000783 // FIXME: Implement.
784 Records = 0;
Chris Lattner393ff042008-04-21 18:56:49 +0000785 NumRecords = 0;
786 }
787 virtual const char *getVAListDeclaration() const {
Eli Friedmana9f54962008-08-20 07:44:10 +0000788 return "typedef char* __builtin_va_list;";
Chris Lattner393ff042008-04-21 18:56:49 +0000789 }
790 virtual const char *getTargetPrefix() const {
Eli Friedmana9f54962008-08-20 07:44:10 +0000791 return "arm";
Chris Lattner393ff042008-04-21 18:56:49 +0000792 }
Chris Lattner393ff042008-04-21 18:56:49 +0000793 virtual void getGCCRegNames(const char * const *&Names,
794 unsigned &NumNames) const {
Eli Friedmana9f54962008-08-20 07:44:10 +0000795 // FIXME: Implement.
796 Names = 0;
Chris Lattner393ff042008-04-21 18:56:49 +0000797 NumNames = 0;
798 }
799 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
800 unsigned &NumAliases) const {
Eli Friedmana9f54962008-08-20 07:44:10 +0000801 // FIXME: Implement.
802 Aliases = 0;
Chris Lattner393ff042008-04-21 18:56:49 +0000803 NumAliases = 0;
804 }
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000805 virtual bool validateAsmConstraint(const char *&Name,
Nate Begemanad487f42008-04-22 05:03:19 +0000806 TargetInfo::ConstraintInfo &info) const {
Eli Friedmana9f54962008-08-20 07:44:10 +0000807 // FIXME: Check if this is complete
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000808 switch (*Name) {
Eli Friedmana9f54962008-08-20 07:44:10 +0000809 default:
Nate Begemanad487f42008-04-22 05:03:19 +0000810 case 'l': // r0-r7
811 case 'h': // r8-r15
812 case 'w': // VFP Floating point register single precision
813 case 'P': // VFP Floating point register double precision
814 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
815 return true;
816 }
Chris Lattner393ff042008-04-21 18:56:49 +0000817 return false;
818 }
819 virtual const char *getClobbers() const {
Eli Friedmana9f54962008-08-20 07:44:10 +0000820 // FIXME: Is this really right?
Chris Lattner393ff042008-04-21 18:56:49 +0000821 return "";
822 }
823};
824} // end anonymous namespace.
825
Eli Friedmana9f54962008-08-20 07:44:10 +0000826
827namespace {
828class DarwinARMTargetInfo : public ARMTargetInfo {
829public:
830 DarwinARMTargetInfo(const std::string& triple) : ARMTargetInfo(triple) {}
831
832 virtual void getTargetDefines(std::vector<char> &Defines) const {
833 ARMTargetInfo::getTargetDefines(Defines);
Chris Lattner8b30c412008-09-30 01:00:25 +0000834 getDarwinDefines(Defines, getTargetTriple());
Eli Friedmana9f54962008-08-20 07:44:10 +0000835 }
836};
837} // end anonymous namespace.
838
Reid Spencer5f016e22007-07-11 17:01:13 +0000839namespace {
Eli Friedman01b86682008-08-20 07:28:14 +0000840class SparcV8TargetInfo : public TargetInfo {
Chris Lattnere957f532009-01-27 01:58:38 +0000841 static const TargetInfo::GCCRegAlias GCCRegAliases[];
842 static const char * const GCCRegNames[];
Gabor Greif26658672008-02-21 16:29:08 +0000843public:
Eli Friedman01b86682008-08-20 07:28:14 +0000844 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
845 // FIXME: Support Sparc quad-precision long double?
Eli Friedmaned855cb2008-08-21 00:13:15 +0000846 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
847 "i64:64:64-f32:32:32-f64:64:64-v64:64:64";
Eli Friedman01b86682008-08-20 07:28:14 +0000848 }
Gabor Greif26658672008-02-21 16:29:08 +0000849 virtual void getTargetDefines(std::vector<char> &Defines) const {
Eli Friedman01b86682008-08-20 07:28:14 +0000850 // FIXME: This is missing a lot of important defines; some of the
851 // missing stuff is likely to break system headers.
Gabor Greif26658672008-02-21 16:29:08 +0000852 Define(Defines, "__sparc");
Eli Friedmanbf0c9bd2008-05-25 05:26:09 +0000853 Define(Defines, "__sparc__");
Gabor Greif26658672008-02-21 16:29:08 +0000854 Define(Defines, "__sparcv8");
855 }
856 virtual void getTargetBuiltins(const Builtin::Info *&Records,
857 unsigned &NumRecords) const {
Eli Friedman01b86682008-08-20 07:28:14 +0000858 // FIXME: Implement!
Gabor Greif26658672008-02-21 16:29:08 +0000859 }
860 virtual const char *getVAListDeclaration() const {
Eli Friedman01b86682008-08-20 07:28:14 +0000861 return "typedef void* __builtin_va_list;";
Gabor Greif26658672008-02-21 16:29:08 +0000862 }
863 virtual const char *getTargetPrefix() const {
Eli Friedman01b86682008-08-20 07:28:14 +0000864 return "sparc";
Gabor Greif26658672008-02-21 16:29:08 +0000865 }
866 virtual void getGCCRegNames(const char * const *&Names,
Chris Lattnere957f532009-01-27 01:58:38 +0000867 unsigned &NumNames) const;
Gabor Greif26658672008-02-21 16:29:08 +0000868 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattnere957f532009-01-27 01:58:38 +0000869 unsigned &NumAliases) const;
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000870 virtual bool validateAsmConstraint(const char *&Name,
Gabor Greif26658672008-02-21 16:29:08 +0000871 TargetInfo::ConstraintInfo &info) const {
Eli Friedman01b86682008-08-20 07:28:14 +0000872 // FIXME: Implement!
873 return false;
Gabor Greif26658672008-02-21 16:29:08 +0000874 }
875 virtual const char *getClobbers() const {
Eli Friedman01b86682008-08-20 07:28:14 +0000876 // FIXME: Implement!
877 return "";
Gabor Greif26658672008-02-21 16:29:08 +0000878 }
879};
880
Chris Lattnere957f532009-01-27 01:58:38 +0000881const char * const SparcV8TargetInfo::GCCRegNames[] = {
882 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
883 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
884 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
885 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
886};
887
888void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names,
889 unsigned &NumNames) const {
890 Names = GCCRegNames;
891 NumNames = llvm::array_lengthof(GCCRegNames);
892}
893
894const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = {
895 { { "g0" }, "r0" },
896 { { "g1" }, "r1" },
897 { { "g2" }, "r2" },
898 { { "g3" }, "r3" },
899 { { "g4" }, "r4" },
900 { { "g5" }, "r5" },
901 { { "g6" }, "r6" },
902 { { "g7" }, "r7" },
903 { { "o0" }, "r8" },
904 { { "o1" }, "r9" },
905 { { "o2" }, "r10" },
906 { { "o3" }, "r11" },
907 { { "o4" }, "r12" },
908 { { "o5" }, "r13" },
909 { { "o6", "sp" }, "r14" },
910 { { "o7" }, "r15" },
911 { { "l0" }, "r16" },
912 { { "l1" }, "r17" },
913 { { "l2" }, "r18" },
914 { { "l3" }, "r19" },
915 { { "l4" }, "r20" },
916 { { "l5" }, "r21" },
917 { { "l6" }, "r22" },
918 { { "l7" }, "r23" },
919 { { "i0" }, "r24" },
920 { { "i1" }, "r25" },
921 { { "i2" }, "r26" },
922 { { "i3" }, "r27" },
923 { { "i4" }, "r28" },
924 { { "i5" }, "r29" },
925 { { "i6", "fp" }, "r30" },
926 { { "i7" }, "r31" },
927};
928
929void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
930 unsigned &NumAliases) const {
931 Aliases = GCCRegAliases;
932 NumAliases = llvm::array_lengthof(GCCRegAliases);
933}
Gabor Greif26658672008-02-21 16:29:08 +0000934} // end anonymous namespace.
935
Eli Friedman01b86682008-08-20 07:28:14 +0000936namespace {
937class SolarisSparcV8TargetInfo : public SparcV8TargetInfo {
938public:
939 SolarisSparcV8TargetInfo(const std::string& triple) :
Eli Friedmanf509d732008-11-02 02:43:55 +0000940 SparcV8TargetInfo(triple) {
941 SizeType = UnsignedInt;
942 PtrDiffType = SignedInt;
943 }
Eli Friedman01b86682008-08-20 07:28:14 +0000944
945 virtual void getTargetDefines(std::vector<char> &Defines) const {
946 SparcV8TargetInfo::getTargetDefines(Defines);
947 getSolarisDefines(Defines);
948 }
949};
950} // end anonymous namespace.
Reid Spencer5f016e22007-07-11 17:01:13 +0000951
Chris Lattner2621fd12008-05-08 05:58:21 +0000952namespace {
953 class PIC16TargetInfo : public TargetInfo{
954 public:
955 PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) {
Sanjiv Gupta31fc07d2008-10-31 09:52:39 +0000956 IntWidth = 16;
957 LongWidth = LongLongWidth = 32;
958 PointerWidth = 16;
959 IntAlign = 8;
960 LongAlign = LongLongAlign = 8;
Eli Friedman61538a72008-05-20 14:21:01 +0000961 PointerAlign = 8;
Sanjiv Gupta31fc07d2008-10-31 09:52:39 +0000962 SizeType = UnsignedInt;
963 IntMaxType = SignedLong;
964 UIntMaxType = UnsignedLong;
Chris Lattner6ad474f2009-02-13 22:28:55 +0000965 IntPtrType = SignedShort;
Eli Friedmanf509d732008-11-02 02:43:55 +0000966 PtrDiffType = SignedInt;
Sanjiv Gupta364af812008-08-18 10:05:22 +0000967 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8";
Chris Lattner2621fd12008-05-08 05:58:21 +0000968 }
Chris Lattner927686f2008-05-09 06:08:39 +0000969 virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; }
970 virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; }
Chris Lattner2621fd12008-05-08 05:58:21 +0000971 virtual void getTargetDefines(std::vector<char> &Defines) const {
972 Define(Defines, "__pic16");
973 }
974 virtual void getTargetBuiltins(const Builtin::Info *&Records,
975 unsigned &NumRecords) const {}
976 virtual const char *getVAListDeclaration() const { return "";}
977 virtual const char *getClobbers() const {return "";}
978 virtual const char *getTargetPrefix() const {return "";}
979 virtual void getGCCRegNames(const char * const *&Names,
980 unsigned &NumNames) const {}
Anders Carlsson066d2ea2009-02-28 17:11:49 +0000981 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattner2621fd12008-05-08 05:58:21 +0000982 TargetInfo::ConstraintInfo &info) const {
983 return true;
984 }
985 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
986 unsigned &NumAliases) const {}
987 virtual bool useGlobalsForAutomaticVariables() const {return true;}
988 };
989}
990
Reid Spencer5f016e22007-07-11 17:01:13 +0000991//===----------------------------------------------------------------------===//
992// Driver code
993//===----------------------------------------------------------------------===//
994
Ted Kremenek8448d382007-12-04 17:07:35 +0000995static inline bool IsX86(const std::string& TT) {
Ted Kremenekae360762007-12-03 22:06:55 +0000996 return (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' &&
997 TT[4] == '-' && TT[1] - '3' < 6);
998}
999
Chris Lattner42e67372008-03-05 01:18:20 +00001000/// CreateTargetInfo - Return the target info object for the specified target
1001/// triple.
1002TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
Eli Friedmaned855cb2008-08-21 00:13:15 +00001003 // OS detection; this isn't really anywhere near complete.
1004 // Additions and corrections are welcome.
1005 bool isDarwin = T.find("-darwin") != std::string::npos;
Chris Lattnereac7aee2008-08-23 18:23:14 +00001006 bool isDragonFly = T.find("-dragonfly") != std::string::npos;
Chris Lattnerfd0269d2008-10-16 17:04:31 +00001007 bool isFreeBSD = T.find("-freebsd") != std::string::npos;
Eli Friedmaned855cb2008-08-21 00:13:15 +00001008 bool isSolaris = T.find("-solaris") != std::string::npos;
1009 bool isLinux = T.find("-linux") != std::string::npos;
1010 bool isWindows = T.find("-windows") != std::string::npos ||
1011 T.find("-win32") != std::string::npos ||
1012 T.find("-mingw") != std::string::npos;
Eli Friedman61538a72008-05-20 14:21:01 +00001013
Eli Friedmaned855cb2008-08-21 00:13:15 +00001014 if (T.find("ppc-") == 0 || T.find("powerpc-") == 0) {
1015 if (isDarwin)
1016 return new DarwinPPCTargetInfo(T);
1017 return new PPC32TargetInfo(T);
1018 }
Eli Friedman61538a72008-05-20 14:21:01 +00001019
Eli Friedmaned855cb2008-08-21 00:13:15 +00001020 if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0) {
1021 if (isDarwin)
1022 return new DarwinPPC64TargetInfo(T);
1023 return new PPC64TargetInfo(T);
1024 }
Chris Lattner393ff042008-04-21 18:56:49 +00001025
Eli Friedmaned855cb2008-08-21 00:13:15 +00001026 if (T.find("armv6-") == 0 || T.find("arm-") == 0) {
1027 if (isDarwin)
1028 return new DarwinARMTargetInfo(T);
1029 return new ARMTargetInfo(T);
1030 }
Eli Friedman61538a72008-05-20 14:21:01 +00001031
Eli Friedmaned855cb2008-08-21 00:13:15 +00001032 if (T.find("sparc-") == 0) {
1033 if (isSolaris)
1034 return new SolarisSparcV8TargetInfo(T);
1035 return new SparcV8TargetInfo(T);
1036 }
1037
Chris Lattner54fefbe2009-02-20 17:04:14 +00001038 if (T.find("x86_64-") == 0 || T.find("amd64-") == 0) {
Eli Friedmaned855cb2008-08-21 00:13:15 +00001039 if (isDarwin)
1040 return new DarwinX86_64TargetInfo(T);
Daniel Dunbarb55a42b2008-09-23 17:37:57 +00001041 if (isLinux)
1042 return new LinuxX86_64TargetInfo(T);
Chris Lattnerfd0269d2008-10-16 17:04:31 +00001043 if (isFreeBSD)
1044 return new FreeBSDX86_64TargetInfo(T);
Eli Friedmaned855cb2008-08-21 00:13:15 +00001045 return new X86_64TargetInfo(T);
1046 }
Eli Friedman61538a72008-05-20 14:21:01 +00001047
Chris Lattner2621fd12008-05-08 05:58:21 +00001048 if (T.find("pic16-") == 0)
1049 return new PIC16TargetInfo(T);
1050
Eli Friedmaned855cb2008-08-21 00:13:15 +00001051 if (IsX86(T)) {
1052 if (isDarwin)
1053 return new DarwinI386TargetInfo(T);
Eli Friedman0d4047b2008-08-21 00:24:02 +00001054 if (isLinux)
1055 return new LinuxX86_32TargetInfo(T);
Chris Lattnereac7aee2008-08-23 18:23:14 +00001056 if (isDragonFly)
1057 return new DragonFlyX86_32TargetInfo(T);
Chris Lattnerfd0269d2008-10-16 17:04:31 +00001058 if (isFreeBSD)
1059 return new FreeBSDX86_32TargetInfo(T);
Eli Friedman29a30502008-08-21 01:40:19 +00001060 if (isWindows)
1061 return new WindowsX86_32TargetInfo(T);
Eli Friedmaned855cb2008-08-21 00:13:15 +00001062 return new X86_32TargetInfo(T);
1063 }
Eli Friedman61538a72008-05-20 14:21:01 +00001064
Chris Lattner42e67372008-03-05 01:18:20 +00001065 return NULL;
Reid Spencer5f016e22007-07-11 17:01:13 +00001066}
Ted Kremenekfb79f7c2008-03-04 17:47:18 +00001067