blob: d79787615aa9bb4fc4dab01530a2b6529ebd86c8 [file] [log] [blame]
Chris Lattner5ba61f02006-10-14 07:39:34 +00001//===--- Targets.cpp - Implement -arch option and targets -----------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner5b12ab82007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Chris Lattner5ba61f02006-10-14 07:39:34 +00007//
8//===----------------------------------------------------------------------===//
9//
Ted Kremenek6f6ff372007-12-12 18:05:32 +000010// This file implements construction of a TargetInfo object from a
11// target triple.
Chris Lattner5ba61f02006-10-14 07:39:34 +000012//
13//===----------------------------------------------------------------------===//
14
Chris Lattner10a5b382007-01-29 05:24:35 +000015#include "clang/AST/Builtins.h"
Anders Carlsson895af082007-12-09 23:17:02 +000016#include "clang/AST/TargetBuiltins.h"
Chris Lattner5ba61f02006-10-14 07:39:34 +000017#include "clang/Basic/TargetInfo.h"
Chris Lattnerc7c6dd42008-12-04 22:54:33 +000018#include "clang/Basic/LangOptions.h"
Anders Carlsson5fa3f342007-11-24 23:38:12 +000019#include "llvm/ADT/STLExtras.h"
Eli Friedman7cef49e2008-05-20 14:27:34 +000020#include "llvm/ADT/APFloat.h"
Chris Lattner5ba61f02006-10-14 07:39:34 +000021using namespace clang;
22
Chris Lattner5ba61f02006-10-14 07:39:34 +000023//===----------------------------------------------------------------------===//
Chris Lattner1f5ad112006-10-14 18:32:12 +000024// Common code shared among targets.
Chris Lattner5ba61f02006-10-14 07:39:34 +000025//===----------------------------------------------------------------------===//
26
Chris Lattnerb2d486a2007-10-06 06:57:34 +000027static void Define(std::vector<char> &Buf, const char *Macro,
28 const char *Val = "1") {
29 const char *Def = "#define ";
30 Buf.insert(Buf.end(), Def, Def+strlen(Def));
31 Buf.insert(Buf.end(), Macro, Macro+strlen(Macro));
32 Buf.push_back(' ');
33 Buf.insert(Buf.end(), Val, Val+strlen(Val));
34 Buf.push_back('\n');
35}
36
Chris Lattner09d98f52008-10-05 21:50:58 +000037//===----------------------------------------------------------------------===//
38// Defines specific to certain operating systems.
39//===----------------------------------------------------------------------===//
40
Eli Friedmanda8f5a92008-08-20 07:28:14 +000041static void getSolarisDefines(std::vector<char> &Defs) {
42 Define(Defs, "__SUN__");
43 Define(Defs, "__SOLARIS__");
44}
Chris Lattner5ba61f02006-10-14 07:39:34 +000045
Nate Begeman95439102009-01-18 01:08:03 +000046static void getFreeBSDDefines(std::vector<char> &Defs, bool is64Bit,
47 const char *Triple) {
Chris Lattner3c3e2cc2008-10-16 17:04:31 +000048 // FreeBSD defines; list based off of gcc output
49
50 const char *FreeBSD = strstr(Triple, "-freebsd");
51 FreeBSD += strlen("-freebsd");
52 char release[] = "X";
53 release[0] = FreeBSD[0];
54 char version[] = "X00001";
55 version[0] = FreeBSD[0];
56
57 Define(Defs, "__FreeBSD__", release);
58 Define(Defs, "__FreeBSD_cc_version", version);
59 Define(Defs, "__KPRINTF_ATTRIBUTE__");
60 Define(Defs, "unix");
61 Define(Defs, "bsd");
62 if (is64Bit) {
63 Define(Defs, "__LP64__");
64 }
65}
66
Chris Lattner09d98f52008-10-05 21:50:58 +000067static void getDragonFlyDefines(std::vector<char> &Defs) {
68 // DragonFly defines; list based off of gcc output
69 Define(Defs, "__DragonFly__");
70 Define(Defs, "__DragonFly_cc_version", "100001");
71 Define(Defs, "__ELF__");
72 Define(Defs, "__KPRINTF_ATTRIBUTE__");
73 Define(Defs, "__tune_i386__");
74 Define(Defs, "unix");
75 Define(Defs, "__unix");
76 Define(Defs, "__unix__");
77}
78
79static void getLinuxDefines(std::vector<char> &Defs) {
80 // Linux defines; list based off of gcc output
81 Define(Defs, "__unix__");
82 Define(Defs, "__unix");
83 Define(Defs, "unix");
84 Define(Defs, "__linux__");
85 Define(Defs, "__linux");
86 Define(Defs, "linux");
87 Define(Defs, "__gnu_linux__");
88}
89
Chris Lattner2ca529c2008-12-04 23:20:07 +000090/// getDarwinNumber - Parse the 'darwin number' out of the specific targe
91/// triple. For example, if we have darwin8.5 return 8,5,4. If any entry is
92/// not defined, return 0's. Return true if we have -darwin in the string or
93/// false otherwise.
94static bool getDarwinNumber(const char *Triple, unsigned &Maj, unsigned &Min) {
95 Maj = Min = 0;
96 const char *Darwin = strstr(Triple, "-darwin");
97 if (Darwin == 0) return false;
98
99 Darwin += strlen("-darwin");
100 if (Darwin[0] < '0' || Darwin[0] > '9')
101 return true;
102
103 Maj = Darwin[0]-'0';
104 ++Darwin;
105
106 // Handle "darwin11".
107 if (Maj == 1 && Darwin[0] >= '0' && Darwin[0] <= '9') {
108 Maj = 10+Darwin[0]-'0';
109 ++Darwin;
110 }
111
112 // Handle minor version: 10.4.9 -> darwin8.9 -> "1049"
113 if (Darwin[0] == '.' && Darwin[1] >= '0' && Darwin[1] <= '9' &&
114 Darwin[2] == '\0')
115 Min = Darwin[1]-'0';
116
117 return true;
118}
119
Chris Lattnerb3793bb2008-09-30 01:00:25 +0000120static void getDarwinDefines(std::vector<char> &Defs, const char *Triple) {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000121 Define(Defs, "__APPLE__");
122 Define(Defs, "__MACH__");
Chris Lattner81813122009-02-05 07:19:24 +0000123 Define(Defs, "OBJC_NEW_PROPERTIES");
124
125 // FIXME: OBJC_ZEROCOST_EXCEPTIONS when using zero cost eh.
Chris Lattnerb3793bb2008-09-30 01:00:25 +0000126
127 // Figure out which "darwin number" the target triple is. "darwin9" -> 10.5.
Chris Lattner2ca529c2008-12-04 23:20:07 +0000128 unsigned Maj, Min;
129 if (getDarwinNumber(Triple, Maj, Min)) {
Chris Lattner97d74942008-09-30 20:30:12 +0000130 char DarwinStr[] = "1000";
Chris Lattner2ca529c2008-12-04 23:20:07 +0000131 if (Maj >= 4 && Maj <= 13) { // 10.0-10.9
132 // darwin7 -> 1030, darwin8 -> 1040, darwin9 -> 1050, etc.
133 DarwinStr[2] = '0' + Maj-4;
Chris Lattnerb3793bb2008-09-30 01:00:25 +0000134 }
Chris Lattner2ca529c2008-12-04 23:20:07 +0000135
136 // Handle minor version: 10.4.9 -> darwin8.9 -> "1049"
137 DarwinStr[3] = Min+'0';
Chris Lattner97d74942008-09-30 20:30:12 +0000138 Define(Defs, "__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", DarwinStr);
Chris Lattnerb3793bb2008-09-30 01:00:25 +0000139 }
Eli Friedman3fd920a2008-08-20 02:34:37 +0000140}
Chris Lattner5ba61f02006-10-14 07:39:34 +0000141
Chris Lattner2ca529c2008-12-04 23:20:07 +0000142/// GetDarwinLanguageOptions - Set the default language options for darwin.
143static void GetDarwinLanguageOptions(LangOptions &Opts,
144 const char *Triple) {
145 Opts.NeXTRuntime = true;
146
147 unsigned Maj, Min;
148 if (!getDarwinNumber(Triple, Maj, Min))
149 return;
150
151 // Blocks default to on for 10.6 (darwin10) and beyond.
152 if (Maj > 9)
153 Opts.Blocks = 1;
154}
155
156
Chris Lattner09d98f52008-10-05 21:50:58 +0000157//===----------------------------------------------------------------------===//
158// Defines specific to certain architectures.
159//===----------------------------------------------------------------------===//
Eli Friedmanff594f22008-08-21 00:24:02 +0000160
Chris Lattner1f5ad112006-10-14 18:32:12 +0000161/// getPowerPCDefines - Return a set of the PowerPC-specific #defines that are
162/// not tied to a specific subtarget.
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000163static void getPowerPCDefines(std::vector<char> &Defs, bool is64Bit) {
Chris Lattner9c837532006-10-15 01:05:46 +0000164 // Target identification.
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000165 Define(Defs, "__ppc__");
166 Define(Defs, "_ARCH_PPC");
167 Define(Defs, "__POWERPC__");
Chris Lattner9c837532006-10-15 01:05:46 +0000168 if (is64Bit) {
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000169 Define(Defs, "_ARCH_PPC64");
170 Define(Defs, "_LP64");
171 Define(Defs, "__LP64__");
172 Define(Defs, "__ppc64__");
Chris Lattner9c837532006-10-15 01:05:46 +0000173 } else {
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000174 Define(Defs, "__ppc__");
Chris Lattner9c837532006-10-15 01:05:46 +0000175 }
Chris Lattner1f5ad112006-10-14 18:32:12 +0000176
Chris Lattner9c837532006-10-15 01:05:46 +0000177 // Target properties.
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000178 Define(Defs, "_BIG_ENDIAN");
179 Define(Defs, "__BIG_ENDIAN__");
Chris Lattner9c837532006-10-15 01:05:46 +0000180
Chris Lattner9c837532006-10-15 01:05:46 +0000181 // Subtarget options.
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000182 Define(Defs, "__NATURAL_ALIGNMENT__");
183 Define(Defs, "__REGISTER_PREFIX__", "");
Chris Lattner9c837532006-10-15 01:05:46 +0000184
Chris Lattnerac7ed9a2008-10-05 21:49:27 +0000185 // FIXME: Should be controlled by command line option.
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000186 Define(Defs, "__LONG_DOUBLE_128__");
Chris Lattner1f5ad112006-10-14 18:32:12 +0000187}
188
189/// getX86Defines - Return a set of the X86-specific #defines that are
190/// not tied to a specific subtarget.
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000191static void getX86Defines(std::vector<char> &Defs, bool is64Bit) {
Chris Lattner9c837532006-10-15 01:05:46 +0000192 // Target identification.
193 if (is64Bit) {
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000194 Define(Defs, "_LP64");
195 Define(Defs, "__LP64__");
196 Define(Defs, "__amd64__");
197 Define(Defs, "__amd64");
198 Define(Defs, "__x86_64");
199 Define(Defs, "__x86_64__");
Chris Lattner9c837532006-10-15 01:05:46 +0000200 } else {
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000201 Define(Defs, "__i386__");
202 Define(Defs, "__i386");
203 Define(Defs, "i386");
Chris Lattner9c837532006-10-15 01:05:46 +0000204 }
205
206 // Target properties.
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000207 Define(Defs, "__LITTLE_ENDIAN__");
Chris Lattner9c837532006-10-15 01:05:46 +0000208
Chris Lattner9c837532006-10-15 01:05:46 +0000209 // Subtarget options.
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000210 Define(Defs, "__nocona");
211 Define(Defs, "__nocona__");
212 Define(Defs, "__tune_nocona__");
213 Define(Defs, "__SSE2_MATH__");
214 Define(Defs, "__SSE2__");
215 Define(Defs, "__SSE_MATH__");
216 Define(Defs, "__SSE__");
217 Define(Defs, "__MMX__");
218 Define(Defs, "__REGISTER_PREFIX__", "");
Chris Lattner1f5ad112006-10-14 18:32:12 +0000219}
220
Chris Lattner0dcd9aa2008-04-21 20:19:54 +0000221/// getARMDefines - Return a set of the ARM-specific #defines that are
Chris Lattner17df24e2008-04-21 18:56:49 +0000222/// not tied to a specific subtarget.
223static void getARMDefines(std::vector<char> &Defs) {
224 // Target identification.
225 Define(Defs, "__arm");
226 Define(Defs, "__arm__");
227
228 // Target properties.
229 Define(Defs, "__LITTLE_ENDIAN__");
230
Chris Lattner17df24e2008-04-21 18:56:49 +0000231 // Subtarget options. [hard coded to v6 for now]
232 Define(Defs, "__ARM_ARCH_6K__");
233 Define(Defs, "__ARMEL__");
234 Define(Defs, "__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", "20000");
Chris Lattner17df24e2008-04-21 18:56:49 +0000235}
236
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000237//===----------------------------------------------------------------------===//
238// Specific target implementations.
239//===----------------------------------------------------------------------===//
Anders Carlssona7408e72007-10-13 00:45:48 +0000240
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000241namespace {
242// PPC abstract base class
243class PPCTargetInfo : public TargetInfo {
244 static const Builtin::Info BuiltinInfo[];
245 static const char * const GCCRegNames[];
246 static const TargetInfo::GCCRegAlias GCCRegAliases[];
247
248public:
249 PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {
250 CharIsSigned = false;
251 }
252 virtual void getTargetBuiltins(const Builtin::Info *&Records,
253 unsigned &NumRecords) const {
Chris Lattner10a5b382007-01-29 05:24:35 +0000254 Records = BuiltinInfo;
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000255 NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner10a5b382007-01-29 05:24:35 +0000256 }
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000257 virtual const char *getVAListDeclaration() const {
Chris Lattner69f9bc22008-10-27 01:11:29 +0000258 return "typedef char* __builtin_va_list;";
259 // This is the right definition for ABI/V4: System V.4/eabi.
260 /*return "typedef struct __va_list_tag {"
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000261 " unsigned char gpr;"
262 " unsigned char fpr;"
263 " unsigned short reserved;"
264 " void* overflow_arg_area;"
265 " void* reg_save_area;"
Chris Lattner69f9bc22008-10-27 01:11:29 +0000266 "} __builtin_va_list[1];";*/
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000267 }
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000268 virtual const char *getTargetPrefix() const {
269 return "ppc";
Anders Carlssonf511f642007-11-27 04:11:28 +0000270 }
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000271 virtual void getGCCRegNames(const char * const *&Names,
272 unsigned &NumNames) const;
273 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
274 unsigned &NumAliases) const;
275 virtual bool validateAsmConstraint(char c,
276 TargetInfo::ConstraintInfo &info) const {
Anders Carlssonf511f642007-11-27 04:11:28 +0000277 switch (c) {
278 default: return false;
279 case 'O': // Zero
280 return true;
281 case 'b': // Base register
282 case 'f': // Floating point register
283 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
284 return true;
285 }
286 }
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000287 virtual const char *getClobbers() const {
288 return "";
Anders Carlssonf511f642007-11-27 04:11:28 +0000289 }
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000290};
Anders Carlssonf511f642007-11-27 04:11:28 +0000291
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000292const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
293#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
294#include "clang/AST/PPCBuiltins.def"
295};
Chris Lattner17df24e2008-04-21 18:56:49 +0000296
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000297const char * const PPCTargetInfo::GCCRegNames[] = {
298 "0", "1", "2", "3", "4", "5", "6", "7",
299 "8", "9", "10", "11", "12", "13", "14", "15",
300 "16", "17", "18", "19", "20", "21", "22", "23",
301 "24", "25", "26", "27", "28", "29", "30", "31",
302 "0", "1", "2", "3", "4", "5", "6", "7",
303 "8", "9", "10", "11", "12", "13", "14", "15",
304 "16", "17", "18", "19", "20", "21", "22", "23",
305 "24", "25", "26", "27", "28", "29", "30", "31",
306 "mq", "lr", "ctr", "ap",
307 "0", "1", "2", "3", "4", "5", "6", "7",
308 "xer",
309 "0", "1", "2", "3", "4", "5", "6", "7",
310 "8", "9", "10", "11", "12", "13", "14", "15",
311 "16", "17", "18", "19", "20", "21", "22", "23",
312 "24", "25", "26", "27", "28", "29", "30", "31",
313 "vrsave", "vscr",
314 "spe_acc", "spefscr",
315 "sfp"
316};
Chris Lattner10a5b382007-01-29 05:24:35 +0000317
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000318void PPCTargetInfo::getGCCRegNames(const char * const *&Names,
319 unsigned &NumNames) const {
320 Names = GCCRegNames;
321 NumNames = llvm::array_lengthof(GCCRegNames);
322}
Chris Lattner5ba61f02006-10-14 07:39:34 +0000323
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000324const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
325 // While some of these aliases do map to different registers
326 // they still share the same register name.
327 { { "cc", "cr0", "fr0", "r0", "v0"}, "0" },
328 { { "cr1", "fr1", "r1", "sp", "v1"}, "1" },
329 { { "cr2", "fr2", "r2", "toc", "v2"}, "2" },
330 { { "cr3", "fr3", "r3", "v3"}, "3" },
331 { { "cr4", "fr4", "r4", "v4"}, "4" },
332 { { "cr5", "fr5", "r5", "v5"}, "5" },
333 { { "cr6", "fr6", "r6", "v6"}, "6" },
334 { { "cr7", "fr7", "r7", "v7"}, "7" },
335 { { "fr8", "r8", "v8"}, "8" },
336 { { "fr9", "r9", "v9"}, "9" },
337 { { "fr10", "r10", "v10"}, "10" },
338 { { "fr11", "r11", "v11"}, "11" },
339 { { "fr12", "r12", "v12"}, "12" },
340 { { "fr13", "r13", "v13"}, "13" },
341 { { "fr14", "r14", "v14"}, "14" },
342 { { "fr15", "r15", "v15"}, "15" },
343 { { "fr16", "r16", "v16"}, "16" },
344 { { "fr17", "r17", "v17"}, "17" },
345 { { "fr18", "r18", "v18"}, "18" },
346 { { "fr19", "r19", "v19"}, "19" },
347 { { "fr20", "r20", "v20"}, "20" },
348 { { "fr21", "r21", "v21"}, "21" },
349 { { "fr22", "r22", "v22"}, "22" },
350 { { "fr23", "r23", "v23"}, "23" },
351 { { "fr24", "r24", "v24"}, "24" },
352 { { "fr25", "r25", "v25"}, "25" },
353 { { "fr26", "r26", "v26"}, "26" },
354 { { "fr27", "r27", "v27"}, "27" },
355 { { "fr28", "r28", "v28"}, "28" },
356 { { "fr29", "r29", "v29"}, "29" },
357 { { "fr30", "r30", "v30"}, "30" },
358 { { "fr31", "r31", "v31"}, "31" },
359};
360
361void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
362 unsigned &NumAliases) const {
363 Aliases = GCCRegAliases;
364 NumAliases = llvm::array_lengthof(GCCRegAliases);
365}
366} // end anonymous namespace.
Chris Lattner02dffbd2006-10-14 07:50:21 +0000367
Chris Lattner5ba61f02006-10-14 07:39:34 +0000368namespace {
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000369class PPC32TargetInfo : public PPCTargetInfo {
Chris Lattner5ba61f02006-10-14 07:39:34 +0000370public:
Eli Friedman873f65a2008-08-21 00:13:15 +0000371 PPC32TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
372 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
373 "i64:64:64-f32:32:32-f64:64:64-v128:128:128";
374 }
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000375 virtual void getTargetDefines(std::vector<char> &Defines) const {
Chris Lattner1f5ad112006-10-14 18:32:12 +0000376 getPowerPCDefines(Defines, false);
377 }
Chris Lattner5ba61f02006-10-14 07:39:34 +0000378};
379} // end anonymous namespace.
380
381namespace {
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000382class PPC64TargetInfo : public PPCTargetInfo {
Chris Lattner5ba61f02006-10-14 07:39:34 +0000383public:
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000384 PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
Chris Lattnerba7a6c12008-05-09 06:17:04 +0000385 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedman873f65a2008-08-21 00:13:15 +0000386 DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
387 "i64:64:64-f32:32:32-f64:64:64-v128:128:128";
Chris Lattnerba7a6c12008-05-09 06:17:04 +0000388 }
Chris Lattnerb2d486a2007-10-06 06:57:34 +0000389 virtual void getTargetDefines(std::vector<char> &Defines) const {
Chris Lattner1f5ad112006-10-14 18:32:12 +0000390 getPowerPCDefines(Defines, true);
391 }
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000392};
393} // end anonymous namespace.
394
Chris Lattner2ca529c2008-12-04 23:20:07 +0000395
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000396namespace {
397class DarwinPPCTargetInfo : public PPC32TargetInfo {
398public:
399 DarwinPPCTargetInfo(const std::string& triple) : PPC32TargetInfo(triple) {}
400 virtual void getTargetDefines(std::vector<char> &Defines) const {
401 PPC32TargetInfo::getTargetDefines(Defines);
Chris Lattnerb3793bb2008-09-30 01:00:25 +0000402 getDarwinDefines(Defines, getTargetTriple());
Chris Lattner10a5b382007-01-29 05:24:35 +0000403 }
Daniel Dunbarb8767ac2008-08-23 08:43:39 +0000404
Chris Lattnerc7c6dd42008-12-04 22:54:33 +0000405 /// getDefaultLangOptions - Allow the target to specify default settings for
406 /// various language options. These may be overridden by command line
407 /// options.
408 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattner2ca529c2008-12-04 23:20:07 +0000409 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattnerc7c6dd42008-12-04 22:54:33 +0000410 }
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000411};
412} // end anonymous namespace.
413
414namespace {
415class DarwinPPC64TargetInfo : public PPC64TargetInfo {
416public:
417 DarwinPPC64TargetInfo(const std::string& triple) : PPC64TargetInfo(triple) {}
418 virtual void getTargetDefines(std::vector<char> &Defines) const {
419 PPC64TargetInfo::getTargetDefines(Defines);
Chris Lattnerb3793bb2008-09-30 01:00:25 +0000420 getDarwinDefines(Defines, getTargetTriple());
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000421 }
Daniel Dunbarb8767ac2008-08-23 08:43:39 +0000422
Chris Lattnerc7c6dd42008-12-04 22:54:33 +0000423 /// getDefaultLangOptions - Allow the target to specify default settings for
424 /// various language options. These may be overridden by command line
425 /// options.
426 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattner2ca529c2008-12-04 23:20:07 +0000427 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattnerc7c6dd42008-12-04 22:54:33 +0000428 }
Chris Lattner5ba61f02006-10-14 07:39:34 +0000429};
430} // end anonymous namespace.
431
432namespace {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000433// Namespace for x86 abstract base class
434const Builtin::Info BuiltinInfo[] = {
435#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS },
436#include "clang/AST/X86Builtins.def"
437};
Eli Friedmanb5366062008-05-20 14:21:01 +0000438
Eli Friedman3fd920a2008-08-20 02:34:37 +0000439const char *GCCRegNames[] = {
440 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
441 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
442 "argp", "flags", "fspr", "dirflag", "frame",
443 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
444 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
445 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
446 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
447};
448
449const TargetInfo::GCCRegAlias GCCRegAliases[] = {
450 { { "al", "ah", "eax", "rax" }, "ax" },
451 { { "bl", "bh", "ebx", "rbx" }, "bx" },
452 { { "cl", "ch", "ecx", "rcx" }, "cx" },
453 { { "dl", "dh", "edx", "rdx" }, "dx" },
454 { { "esi", "rsi" }, "si" },
455 { { "edi", "rdi" }, "di" },
456 { { "esp", "rsp" }, "sp" },
457 { { "ebp", "rbp" }, "bp" },
458};
459
460// X86 target abstract base class; x86-32 and x86-64 are very close, so
461// most of the implementation can be shared.
462class X86TargetInfo : public TargetInfo {
463public:
464 X86TargetInfo(const std::string& triple) : TargetInfo(triple) {
465 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
Chris Lattner1f5ad112006-10-14 18:32:12 +0000466 }
Chris Lattner10a5b382007-01-29 05:24:35 +0000467 virtual void getTargetBuiltins(const Builtin::Info *&Records,
468 unsigned &NumRecords) const {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000469 Records = BuiltinInfo;
470 NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner10a5b382007-01-29 05:24:35 +0000471 }
Anders Carlsson050f4942007-12-08 19:32:57 +0000472 virtual const char *getTargetPrefix() const {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000473 return "x86";
Anders Carlsson050f4942007-12-08 19:32:57 +0000474 }
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000475 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedman3fd920a2008-08-20 02:34:37 +0000476 unsigned &NumNames) const {
477 Names = GCCRegNames;
478 NumNames = llvm::array_lengthof(GCCRegNames);
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000479 }
480 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
481 unsigned &NumAliases) const {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000482 Aliases = GCCRegAliases;
483 NumAliases = llvm::array_lengthof(GCCRegAliases);
Anders Carlssona7408e72007-10-13 00:45:48 +0000484 }
Anders Carlssonf511f642007-11-27 04:11:28 +0000485 virtual bool validateAsmConstraint(char c,
Eli Friedman3fd920a2008-08-20 02:34:37 +0000486 TargetInfo::ConstraintInfo &info) const;
487 virtual std::string convertConstraint(const char Constraint) const;
Anders Carlssonf511f642007-11-27 04:11:28 +0000488 virtual const char *getClobbers() const {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000489 return "~{dirflag},~{fpsr},~{flags}";
490 }
Chris Lattner5ba61f02006-10-14 07:39:34 +0000491};
Eli Friedman3fd920a2008-08-20 02:34:37 +0000492
493bool
494X86TargetInfo::validateAsmConstraint(char c,
495 TargetInfo::ConstraintInfo &info) const {
496 switch (c) {
497 default: return false;
498 case 'a': // eax.
499 case 'b': // ebx.
500 case 'c': // ecx.
501 case 'd': // edx.
502 case 'S': // esi.
503 case 'D': // edi.
504 case 'A': // edx:eax.
505 case 't': // top of floating point stack.
506 case 'u': // second from top of floating point stack.
507 case 'q': // Any register accessible as [r]l: a, b, c, and d.
Anders Carlsson83661ac2008-10-06 00:41:45 +0000508 case 'y': // Any MMX register.
Anders Carlsson5f7ee682008-10-06 19:17:39 +0000509 case 'x': // Any SSE register.
Eli Friedman3fd920a2008-08-20 02:34:37 +0000510 case 'Q': // Any register accessible as [r]h: a, b, c, and d.
Anders Carlssona0b89212009-01-24 18:03:09 +0000511 case 'e': // 32-bit signed integer constant for use with zero-extending
512 // x86_64 instructions.
513 case 'Z': // 32-bit unsigned integer constant for use with zero-extending
514 // x86_64 instructions.
Eli Friedman3fd920a2008-08-20 02:34:37 +0000515 case 'N': // unsigned 8-bit integer constant for use with in and out
516 // instructions.
517 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
518 return true;
519 }
520}
521
522std::string
523X86TargetInfo::convertConstraint(const char Constraint) const {
524 switch (Constraint) {
525 case 'a': return std::string("{ax}");
526 case 'b': return std::string("{bx}");
527 case 'c': return std::string("{cx}");
528 case 'd': return std::string("{dx}");
529 case 'S': return std::string("{si}");
530 case 'D': return std::string("{di}");
531 case 't': // top of floating point stack.
532 return std::string("{st}");
533 case 'u': // second from top of floating point stack.
534 return std::string("{st(1)}"); // second from top of floating point stack.
535 default:
536 return std::string(1, Constraint);
537 }
538}
Eli Friedman3fd920a2008-08-20 02:34:37 +0000539} // end anonymous namespace
Chris Lattner5ba61f02006-10-14 07:39:34 +0000540
541namespace {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000542// X86-32 generic target
543class X86_32TargetInfo : public X86TargetInfo {
Chris Lattner5ba61f02006-10-14 07:39:34 +0000544public:
Eli Friedman3fd920a2008-08-20 02:34:37 +0000545 X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
546 DoubleAlign = LongLongAlign = 32;
547 LongDoubleWidth = 96;
548 LongDoubleAlign = 32;
Eli Friedman873f65a2008-08-21 00:13:15 +0000549 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
550 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
551 "a0:0:64-f80:32:32";
Eli Friedman3fd920a2008-08-20 02:34:37 +0000552 }
553 virtual const char *getVAListDeclaration() const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +0000554 return "typedef char* __builtin_va_list;";
Eli Friedman3fd920a2008-08-20 02:34:37 +0000555 }
556 virtual void getTargetDefines(std::vector<char> &Defines) const {
557 getX86Defines(Defines, false);
558 }
559};
560} // end anonymous namespace
561
562namespace {
563// x86-32 Darwin (OS X) target
564class DarwinI386TargetInfo : public X86_32TargetInfo {
565public:
566 DarwinI386TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
567 LongDoubleWidth = 128;
568 LongDoubleAlign = 128;
Chris Lattner81813122009-02-05 07:19:24 +0000569 PtrDiffType = SignedInt;
Eli Friedman873f65a2008-08-21 00:13:15 +0000570 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
571 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
572 "a0:0:64-f80:128:128";
Eli Friedman3fd920a2008-08-20 02:34:37 +0000573 }
574 virtual void getTargetDefines(std::vector<char> &Defines) const {
575 X86_32TargetInfo::getTargetDefines(Defines);
Chris Lattnerb3793bb2008-09-30 01:00:25 +0000576 getDarwinDefines(Defines, getTargetTriple());
Eli Friedman3fd920a2008-08-20 02:34:37 +0000577 }
Chris Lattnerc7c6dd42008-12-04 22:54:33 +0000578 /// getDefaultLangOptions - Allow the target to specify default settings for
579 /// various language options. These may be overridden by command line
580 /// options.
581 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattner2ca529c2008-12-04 23:20:07 +0000582 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattnerc7c6dd42008-12-04 22:54:33 +0000583 }
Eli Friedman3fd920a2008-08-20 02:34:37 +0000584};
585} // end anonymous namespace
586
587namespace {
Chris Lattner3c3e2cc2008-10-16 17:04:31 +0000588// x86-32 FreeBSD target
589class FreeBSDX86_32TargetInfo : public X86_32TargetInfo {
590public:
Eli Friedmand50881c2008-11-02 02:43:55 +0000591 FreeBSDX86_32TargetInfo(const std::string& triple) :
592 X86_32TargetInfo(triple) {
593 SizeType = UnsignedInt;
594 PtrDiffType = SignedInt;
Chris Lattner3c3e2cc2008-10-16 17:04:31 +0000595 }
596 virtual void getTargetDefines(std::vector<char> &Defines) const {
597 X86_32TargetInfo::getTargetDefines(Defines);
598 getFreeBSDDefines(Defines, 0, getTargetTriple());
599 }
600};
601} // end anonymous namespace
602
603namespace {
Chris Lattner5637ef52008-08-23 18:23:14 +0000604// x86-32 DragonFly target
605class DragonFlyX86_32TargetInfo : public X86_32TargetInfo {
606public:
Eli Friedmand50881c2008-11-02 02:43:55 +0000607 DragonFlyX86_32TargetInfo(const std::string& triple) :
608 X86_32TargetInfo(triple) {
609 SizeType = UnsignedInt;
610 PtrDiffType = SignedInt;
Chris Lattner5637ef52008-08-23 18:23:14 +0000611 }
612 virtual void getTargetDefines(std::vector<char> &Defines) const {
613 X86_32TargetInfo::getTargetDefines(Defines);
614 getDragonFlyDefines(Defines);
615 }
616};
617} // end anonymous namespace
618
619namespace {
Eli Friedmanff594f22008-08-21 00:24:02 +0000620// x86-32 Linux target
621class LinuxX86_32TargetInfo : public X86_32TargetInfo {
622public:
623 LinuxX86_32TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
Chris Lattner4ecd7532008-10-05 19:44:25 +0000624 UserLabelPrefix = "";
Eli Friedmand50881c2008-11-02 02:43:55 +0000625 SizeType = UnsignedInt;
626 PtrDiffType = SignedInt;
Eli Friedmanff594f22008-08-21 00:24:02 +0000627 }
628 virtual void getTargetDefines(std::vector<char> &Defines) const {
629 X86_32TargetInfo::getTargetDefines(Defines);
630 getLinuxDefines(Defines);
631 }
632};
633} // end anonymous namespace
634
635namespace {
Eli Friedmanc968a6a2008-08-21 01:40:19 +0000636// x86-32 Windows target
637class WindowsX86_32TargetInfo : public X86_32TargetInfo {
638public:
639 WindowsX86_32TargetInfo(const std::string& triple)
640 : X86_32TargetInfo(triple) {
641 // FIXME: Fix wchar_t.
642 // FIXME: We should probably enable -fms-extensions by default for
643 // this target.
Eli Friedmand50881c2008-11-02 02:43:55 +0000644 SizeType = UnsignedInt;
645 PtrDiffType = SignedInt;
Eli Friedmanc968a6a2008-08-21 01:40:19 +0000646 }
647 virtual void getTargetDefines(std::vector<char> &Defines) const {
648 X86_32TargetInfo::getTargetDefines(Defines);
649 // This list is based off of the the list of things MingW defines
650 Define(Defines, "__WIN32__");
651 Define(Defines, "__WIN32");
652 Define(Defines, "_WIN32");
653 Define(Defines, "WIN32");
654 Define(Defines, "__WINNT__");
655 Define(Defines, "__WINNT");
656 Define(Defines, "WINNT");
Eli Friedmanc968a6a2008-08-21 01:40:19 +0000657 Define(Defines, "_X86_");
658 Define(Defines, "__MSVCRT__");
659 }
660};
661} // end anonymous namespace
662
663namespace {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000664// x86-64 generic target
665class X86_64TargetInfo : public X86TargetInfo {
666public:
667 X86_64TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
Chris Lattnerba7a6c12008-05-09 06:17:04 +0000668 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Chris Lattner22ebe7b2009-01-28 06:58:19 +0000669 DoubleAlign = LongLongAlign = 64;
Eli Friedmanb5366062008-05-20 14:21:01 +0000670 LongDoubleWidth = 128;
671 LongDoubleAlign = 128;
Eli Friedman873f65a2008-08-21 00:13:15 +0000672 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
673 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
674 "a0:0:64-f80:128:128";
Chris Lattner10a5b382007-01-29 05:24:35 +0000675 }
Anders Carlssona7408e72007-10-13 00:45:48 +0000676 virtual const char *getVAListDeclaration() const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +0000677 return "typedef struct __va_list_tag {"
678 " unsigned gp_offset;"
679 " unsigned fp_offset;"
680 " void* overflow_arg_area;"
681 " void* reg_save_area;"
682 "} __builtin_va_list[1];";
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000683 }
Eli Friedman3fd920a2008-08-20 02:34:37 +0000684 virtual void getTargetDefines(std::vector<char> &Defines) const {
685 getX86Defines(Defines, true);
Anders Carlsson050f4942007-12-08 19:32:57 +0000686 }
Eli Friedman3fd920a2008-08-20 02:34:37 +0000687};
688} // end anonymous namespace
689
690namespace {
Chris Lattner3c3e2cc2008-10-16 17:04:31 +0000691// x86-64 FreeBSD target
692class FreeBSDX86_64TargetInfo : public X86_64TargetInfo {
693public:
Eli Friedmand50881c2008-11-02 02:43:55 +0000694 FreeBSDX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) {}
Chris Lattner3c3e2cc2008-10-16 17:04:31 +0000695 virtual void getTargetDefines(std::vector<char> &Defines) const {
696 X86_64TargetInfo::getTargetDefines(Defines);
697 getFreeBSDDefines(Defines, 1, getTargetTriple());
698 }
699};
700} // end anonymous namespace
701
702namespace {
Daniel Dunbard0921de2008-09-23 17:37:57 +0000703// x86-64 Linux target
704class LinuxX86_64TargetInfo : public X86_64TargetInfo {
705public:
706 LinuxX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) {
Chris Lattner4ecd7532008-10-05 19:44:25 +0000707 UserLabelPrefix = "";
Daniel Dunbard0921de2008-09-23 17:37:57 +0000708 }
709 virtual void getTargetDefines(std::vector<char> &Defines) const {
710 X86_64TargetInfo::getTargetDefines(Defines);
711 getLinuxDefines(Defines);
Daniel Dunbard0921de2008-09-23 17:37:57 +0000712 }
713};
714} // end anonymous namespace
715
716namespace {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000717// x86-64 Darwin (OS X) target
718class DarwinX86_64TargetInfo : public X86_64TargetInfo {
719public:
720 DarwinX86_64TargetInfo(const std::string& triple) :
721 X86_64TargetInfo(triple) {}
722
723 virtual void getTargetDefines(std::vector<char> &Defines) const {
724 X86_64TargetInfo::getTargetDefines(Defines);
Chris Lattnerb3793bb2008-09-30 01:00:25 +0000725 getDarwinDefines(Defines, getTargetTriple());
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000726 }
Daniel Dunbarb8767ac2008-08-23 08:43:39 +0000727
Chris Lattnerc7c6dd42008-12-04 22:54:33 +0000728 /// getDefaultLangOptions - Allow the target to specify default settings for
729 /// various language options. These may be overridden by command line
730 /// options.
731 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattner2ca529c2008-12-04 23:20:07 +0000732 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattnerc7c6dd42008-12-04 22:54:33 +0000733 }
Chris Lattner5ba61f02006-10-14 07:39:34 +0000734};
735} // end anonymous namespace.
736
Chris Lattner17df24e2008-04-21 18:56:49 +0000737namespace {
Eli Friedmanf05b7722008-08-20 07:44:10 +0000738class ARMTargetInfo : public TargetInfo {
Chris Lattner17df24e2008-04-21 18:56:49 +0000739public:
Eli Friedmanf05b7722008-08-20 07:44:10 +0000740 ARMTargetInfo(const std::string& triple) : TargetInfo(triple) {
741 // FIXME: Are the defaults correct for ARM?
Eli Friedman873f65a2008-08-21 00:13:15 +0000742 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
743 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:64";
Eli Friedmanb5366062008-05-20 14:21:01 +0000744 }
Chris Lattner17df24e2008-04-21 18:56:49 +0000745 virtual void getTargetDefines(std::vector<char> &Defines) const {
Chris Lattner17df24e2008-04-21 18:56:49 +0000746 getARMDefines(Defines);
747 }
748 virtual void getTargetBuiltins(const Builtin::Info *&Records,
749 unsigned &NumRecords) const {
Eli Friedmanf05b7722008-08-20 07:44:10 +0000750 // FIXME: Implement.
751 Records = 0;
Chris Lattner17df24e2008-04-21 18:56:49 +0000752 NumRecords = 0;
753 }
754 virtual const char *getVAListDeclaration() const {
Eli Friedmanf05b7722008-08-20 07:44:10 +0000755 return "typedef char* __builtin_va_list;";
Chris Lattner17df24e2008-04-21 18:56:49 +0000756 }
757 virtual const char *getTargetPrefix() const {
Eli Friedmanf05b7722008-08-20 07:44:10 +0000758 return "arm";
Chris Lattner17df24e2008-04-21 18:56:49 +0000759 }
Chris Lattner17df24e2008-04-21 18:56:49 +0000760 virtual void getGCCRegNames(const char * const *&Names,
761 unsigned &NumNames) const {
Eli Friedmanf05b7722008-08-20 07:44:10 +0000762 // FIXME: Implement.
763 Names = 0;
Chris Lattner17df24e2008-04-21 18:56:49 +0000764 NumNames = 0;
765 }
766 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
767 unsigned &NumAliases) const {
Eli Friedmanf05b7722008-08-20 07:44:10 +0000768 // FIXME: Implement.
769 Aliases = 0;
Chris Lattner17df24e2008-04-21 18:56:49 +0000770 NumAliases = 0;
771 }
772 virtual bool validateAsmConstraint(char c,
Nate Begeman2908fa02008-04-22 05:03:19 +0000773 TargetInfo::ConstraintInfo &info) const {
Eli Friedmanf05b7722008-08-20 07:44:10 +0000774 // FIXME: Check if this is complete
Nate Begeman2908fa02008-04-22 05:03:19 +0000775 switch (c) {
Eli Friedmanf05b7722008-08-20 07:44:10 +0000776 default:
Nate Begeman2908fa02008-04-22 05:03:19 +0000777 case 'l': // r0-r7
778 case 'h': // r8-r15
779 case 'w': // VFP Floating point register single precision
780 case 'P': // VFP Floating point register double precision
781 info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister);
782 return true;
783 }
Chris Lattner17df24e2008-04-21 18:56:49 +0000784 return false;
785 }
786 virtual const char *getClobbers() const {
Eli Friedmanf05b7722008-08-20 07:44:10 +0000787 // FIXME: Is this really right?
Chris Lattner17df24e2008-04-21 18:56:49 +0000788 return "";
789 }
790};
791} // end anonymous namespace.
792
Eli Friedmanf05b7722008-08-20 07:44:10 +0000793
794namespace {
795class DarwinARMTargetInfo : public ARMTargetInfo {
796public:
797 DarwinARMTargetInfo(const std::string& triple) : ARMTargetInfo(triple) {}
798
799 virtual void getTargetDefines(std::vector<char> &Defines) const {
800 ARMTargetInfo::getTargetDefines(Defines);
Chris Lattnerb3793bb2008-09-30 01:00:25 +0000801 getDarwinDefines(Defines, getTargetTriple());
Eli Friedmanf05b7722008-08-20 07:44:10 +0000802 }
803};
804} // end anonymous namespace.
805
Chris Lattner5ba61f02006-10-14 07:39:34 +0000806namespace {
Eli Friedmanda8f5a92008-08-20 07:28:14 +0000807class SparcV8TargetInfo : public TargetInfo {
Chris Lattner9b415d62009-01-27 01:58:38 +0000808 static const TargetInfo::GCCRegAlias GCCRegAliases[];
809 static const char * const GCCRegNames[];
Gabor Greif49991682008-02-21 16:29:08 +0000810public:
Eli Friedmanda8f5a92008-08-20 07:28:14 +0000811 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
812 // FIXME: Support Sparc quad-precision long double?
Eli Friedman873f65a2008-08-21 00:13:15 +0000813 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
814 "i64:64:64-f32:32:32-f64:64:64-v64:64:64";
Eli Friedmanda8f5a92008-08-20 07:28:14 +0000815 }
Gabor Greif49991682008-02-21 16:29:08 +0000816 virtual void getTargetDefines(std::vector<char> &Defines) const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +0000817 // FIXME: This is missing a lot of important defines; some of the
818 // missing stuff is likely to break system headers.
Gabor Greif49991682008-02-21 16:29:08 +0000819 Define(Defines, "__sparc");
Eli Friedmanb2bef7c2008-05-25 05:26:09 +0000820 Define(Defines, "__sparc__");
Gabor Greif49991682008-02-21 16:29:08 +0000821 Define(Defines, "__sparcv8");
822 }
823 virtual void getTargetBuiltins(const Builtin::Info *&Records,
824 unsigned &NumRecords) const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +0000825 // FIXME: Implement!
Gabor Greif49991682008-02-21 16:29:08 +0000826 }
827 virtual const char *getVAListDeclaration() const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +0000828 return "typedef void* __builtin_va_list;";
Gabor Greif49991682008-02-21 16:29:08 +0000829 }
830 virtual const char *getTargetPrefix() const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +0000831 return "sparc";
Gabor Greif49991682008-02-21 16:29:08 +0000832 }
833 virtual void getGCCRegNames(const char * const *&Names,
Chris Lattner9b415d62009-01-27 01:58:38 +0000834 unsigned &NumNames) const;
Gabor Greif49991682008-02-21 16:29:08 +0000835 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattner9b415d62009-01-27 01:58:38 +0000836 unsigned &NumAliases) const;
Gabor Greif49991682008-02-21 16:29:08 +0000837 virtual bool validateAsmConstraint(char c,
838 TargetInfo::ConstraintInfo &info) const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +0000839 // FIXME: Implement!
840 return false;
Gabor Greif49991682008-02-21 16:29:08 +0000841 }
842 virtual const char *getClobbers() const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +0000843 // FIXME: Implement!
844 return "";
Gabor Greif49991682008-02-21 16:29:08 +0000845 }
846};
847
Chris Lattner9b415d62009-01-27 01:58:38 +0000848const char * const SparcV8TargetInfo::GCCRegNames[] = {
849 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
850 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
851 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
852 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
853};
854
855void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names,
856 unsigned &NumNames) const {
857 Names = GCCRegNames;
858 NumNames = llvm::array_lengthof(GCCRegNames);
859}
860
861const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = {
862 { { "g0" }, "r0" },
863 { { "g1" }, "r1" },
864 { { "g2" }, "r2" },
865 { { "g3" }, "r3" },
866 { { "g4" }, "r4" },
867 { { "g5" }, "r5" },
868 { { "g6" }, "r6" },
869 { { "g7" }, "r7" },
870 { { "o0" }, "r8" },
871 { { "o1" }, "r9" },
872 { { "o2" }, "r10" },
873 { { "o3" }, "r11" },
874 { { "o4" }, "r12" },
875 { { "o5" }, "r13" },
876 { { "o6", "sp" }, "r14" },
877 { { "o7" }, "r15" },
878 { { "l0" }, "r16" },
879 { { "l1" }, "r17" },
880 { { "l2" }, "r18" },
881 { { "l3" }, "r19" },
882 { { "l4" }, "r20" },
883 { { "l5" }, "r21" },
884 { { "l6" }, "r22" },
885 { { "l7" }, "r23" },
886 { { "i0" }, "r24" },
887 { { "i1" }, "r25" },
888 { { "i2" }, "r26" },
889 { { "i3" }, "r27" },
890 { { "i4" }, "r28" },
891 { { "i5" }, "r29" },
892 { { "i6", "fp" }, "r30" },
893 { { "i7" }, "r31" },
894};
895
896void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
897 unsigned &NumAliases) const {
898 Aliases = GCCRegAliases;
899 NumAliases = llvm::array_lengthof(GCCRegAliases);
900}
Gabor Greif49991682008-02-21 16:29:08 +0000901} // end anonymous namespace.
902
Eli Friedmanda8f5a92008-08-20 07:28:14 +0000903namespace {
904class SolarisSparcV8TargetInfo : public SparcV8TargetInfo {
905public:
906 SolarisSparcV8TargetInfo(const std::string& triple) :
Eli Friedmand50881c2008-11-02 02:43:55 +0000907 SparcV8TargetInfo(triple) {
908 SizeType = UnsignedInt;
909 PtrDiffType = SignedInt;
910 }
Eli Friedmanda8f5a92008-08-20 07:28:14 +0000911
912 virtual void getTargetDefines(std::vector<char> &Defines) const {
913 SparcV8TargetInfo::getTargetDefines(Defines);
914 getSolarisDefines(Defines);
915 }
916};
917} // end anonymous namespace.
Chris Lattner5ba61f02006-10-14 07:39:34 +0000918
Chris Lattnerb781dc792008-05-08 05:58:21 +0000919namespace {
920 class PIC16TargetInfo : public TargetInfo{
921 public:
922 PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) {
Sanjiv Guptad7959242008-10-31 09:52:39 +0000923 IntWidth = 16;
924 LongWidth = LongLongWidth = 32;
925 PointerWidth = 16;
926 IntAlign = 8;
927 LongAlign = LongLongAlign = 8;
Eli Friedmanb5366062008-05-20 14:21:01 +0000928 PointerAlign = 8;
Sanjiv Guptad7959242008-10-31 09:52:39 +0000929 SizeType = UnsignedInt;
930 IntMaxType = SignedLong;
931 UIntMaxType = UnsignedLong;
Eli Friedmand50881c2008-11-02 02:43:55 +0000932 PtrDiffType = SignedInt;
Sanjiv Gupta14f18f32008-08-18 10:05:22 +0000933 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8";
Chris Lattnerb781dc792008-05-08 05:58:21 +0000934 }
Chris Lattner5e2ef0c2008-05-09 06:08:39 +0000935 virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; }
936 virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; }
Chris Lattnerb781dc792008-05-08 05:58:21 +0000937 virtual void getTargetDefines(std::vector<char> &Defines) const {
938 Define(Defines, "__pic16");
939 }
940 virtual void getTargetBuiltins(const Builtin::Info *&Records,
941 unsigned &NumRecords) const {}
942 virtual const char *getVAListDeclaration() const { return "";}
943 virtual const char *getClobbers() const {return "";}
944 virtual const char *getTargetPrefix() const {return "";}
945 virtual void getGCCRegNames(const char * const *&Names,
946 unsigned &NumNames) const {}
947 virtual bool validateAsmConstraint(char c,
948 TargetInfo::ConstraintInfo &info) const {
949 return true;
950 }
951 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
952 unsigned &NumAliases) const {}
953 virtual bool useGlobalsForAutomaticVariables() const {return true;}
954 };
955}
956
Chris Lattner5ba61f02006-10-14 07:39:34 +0000957//===----------------------------------------------------------------------===//
958// Driver code
959//===----------------------------------------------------------------------===//
960
Ted Kremenek0c2bea22007-12-04 17:07:35 +0000961static inline bool IsX86(const std::string& TT) {
Ted Kremenekb0615542007-12-03 22:06:55 +0000962 return (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' &&
963 TT[4] == '-' && TT[1] - '3' < 6);
964}
965
Chris Lattner855d0242008-03-05 01:18:20 +0000966/// CreateTargetInfo - Return the target info object for the specified target
967/// triple.
968TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
Eli Friedman873f65a2008-08-21 00:13:15 +0000969 // OS detection; this isn't really anywhere near complete.
970 // Additions and corrections are welcome.
971 bool isDarwin = T.find("-darwin") != std::string::npos;
Chris Lattner5637ef52008-08-23 18:23:14 +0000972 bool isDragonFly = T.find("-dragonfly") != std::string::npos;
Chris Lattner3c3e2cc2008-10-16 17:04:31 +0000973 bool isFreeBSD = T.find("-freebsd") != std::string::npos;
Eli Friedman873f65a2008-08-21 00:13:15 +0000974 bool isSolaris = T.find("-solaris") != std::string::npos;
975 bool isLinux = T.find("-linux") != std::string::npos;
976 bool isWindows = T.find("-windows") != std::string::npos ||
977 T.find("-win32") != std::string::npos ||
978 T.find("-mingw") != std::string::npos;
Eli Friedmanb5366062008-05-20 14:21:01 +0000979
Eli Friedman873f65a2008-08-21 00:13:15 +0000980 if (T.find("ppc-") == 0 || T.find("powerpc-") == 0) {
981 if (isDarwin)
982 return new DarwinPPCTargetInfo(T);
983 return new PPC32TargetInfo(T);
984 }
Eli Friedmanb5366062008-05-20 14:21:01 +0000985
Eli Friedman873f65a2008-08-21 00:13:15 +0000986 if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0) {
987 if (isDarwin)
988 return new DarwinPPC64TargetInfo(T);
989 return new PPC64TargetInfo(T);
990 }
Chris Lattner17df24e2008-04-21 18:56:49 +0000991
Eli Friedman873f65a2008-08-21 00:13:15 +0000992 if (T.find("armv6-") == 0 || T.find("arm-") == 0) {
993 if (isDarwin)
994 return new DarwinARMTargetInfo(T);
995 return new ARMTargetInfo(T);
996 }
Eli Friedmanb5366062008-05-20 14:21:01 +0000997
Eli Friedman873f65a2008-08-21 00:13:15 +0000998 if (T.find("sparc-") == 0) {
999 if (isSolaris)
1000 return new SolarisSparcV8TargetInfo(T);
1001 return new SparcV8TargetInfo(T);
1002 }
1003
1004 if (T.find("x86_64-") == 0) {
1005 if (isDarwin)
1006 return new DarwinX86_64TargetInfo(T);
Daniel Dunbard0921de2008-09-23 17:37:57 +00001007 if (isLinux)
1008 return new LinuxX86_64TargetInfo(T);
Chris Lattner3c3e2cc2008-10-16 17:04:31 +00001009 if (isFreeBSD)
1010 return new FreeBSDX86_64TargetInfo(T);
Eli Friedman873f65a2008-08-21 00:13:15 +00001011 return new X86_64TargetInfo(T);
1012 }
Eli Friedmanb5366062008-05-20 14:21:01 +00001013
Chris Lattnerb781dc792008-05-08 05:58:21 +00001014 if (T.find("pic16-") == 0)
1015 return new PIC16TargetInfo(T);
1016
Eli Friedman873f65a2008-08-21 00:13:15 +00001017 if (IsX86(T)) {
1018 if (isDarwin)
1019 return new DarwinI386TargetInfo(T);
Eli Friedmanff594f22008-08-21 00:24:02 +00001020 if (isLinux)
1021 return new LinuxX86_32TargetInfo(T);
Chris Lattner5637ef52008-08-23 18:23:14 +00001022 if (isDragonFly)
1023 return new DragonFlyX86_32TargetInfo(T);
Chris Lattner3c3e2cc2008-10-16 17:04:31 +00001024 if (isFreeBSD)
1025 return new FreeBSDX86_32TargetInfo(T);
Eli Friedmanc968a6a2008-08-21 01:40:19 +00001026 if (isWindows)
1027 return new WindowsX86_32TargetInfo(T);
Eli Friedman873f65a2008-08-21 00:13:15 +00001028 return new X86_32TargetInfo(T);
1029 }
Eli Friedmanb5366062008-05-20 14:21:01 +00001030
Chris Lattner855d0242008-03-05 01:18:20 +00001031 return NULL;
Chris Lattner5ba61f02006-10-14 07:39:34 +00001032}
Ted Kremenekc490bdb2008-03-04 17:47:18 +00001033