blob: 281dfa7a077e7abfe500a4d2adefd9206aeebb03 [file] [log] [blame]
Chris Lattner4b009652007-07-25 00:24:17 +00001//===--- Targets.cpp - Implement -arch option and targets -----------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner959e5be2007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Chris Lattner4b009652007-07-25 00:24:17 +00007//
8//===----------------------------------------------------------------------===//
9//
Anton Korobeynikove7772382009-05-03 13:42:53 +000010// This file implements construction of a TargetInfo object from a
Ted Kremenek38591a22007-12-12 18:05:32 +000011// target triple.
Chris Lattner4b009652007-07-25 00:24:17 +000012//
13//===----------------------------------------------------------------------===//
14
Douglas Gregor2e8a7aa2009-02-16 21:58:21 +000015// FIXME: Layering violation
Chris Lattner4b009652007-07-25 00:24:17 +000016#include "clang/AST/Builtins.h"
Anders Carlssone1449c12007-12-09 23:17:02 +000017#include "clang/AST/TargetBuiltins.h"
Chris Lattner4b009652007-07-25 00:24:17 +000018#include "clang/Basic/TargetInfo.h"
Chris Lattnerddae7102008-12-04 22:54:33 +000019#include "clang/Basic/LangOptions.h"
Anders Carlsson7dd1c952007-11-24 23:38:12 +000020#include "llvm/ADT/STLExtras.h"
Eli Friedmand4011892008-05-20 14:27:34 +000021#include "llvm/ADT/APFloat.h"
Chris Lattnerc345a802009-03-20 16:06:38 +000022#include "llvm/ADT/SmallString.h"
Chris Lattner4b009652007-07-25 00:24:17 +000023using namespace clang;
24
Chris Lattner4b009652007-07-25 00:24:17 +000025//===----------------------------------------------------------------------===//
26// Common code shared among targets.
27//===----------------------------------------------------------------------===//
28
Chris Lattner0db667a2007-10-06 06:57:34 +000029static void Define(std::vector<char> &Buf, const char *Macro,
30 const char *Val = "1") {
31 const char *Def = "#define ";
32 Buf.insert(Buf.end(), Def, Def+strlen(Def));
33 Buf.insert(Buf.end(), Macro, Macro+strlen(Macro));
34 Buf.push_back(' ');
35 Buf.insert(Buf.end(), Val, Val+strlen(Val));
36 Buf.push_back('\n');
37}
38
Chris Lattnerc345a802009-03-20 16:06:38 +000039/// DefineStd - Define a macro name and standard variants. For example if
40/// MacroName is "unix", then this will define "__unix", "__unix__", and "unix"
41/// when in GNU mode.
Anton Korobeynikove7772382009-05-03 13:42:53 +000042static void DefineStd(std::vector<char> &Buf, const char *MacroName,
Chris Lattnerc345a802009-03-20 16:06:38 +000043 const LangOptions &Opts) {
44 assert(MacroName[0] != '_' && "Identifier should be in the user's namespace");
Anton Korobeynikove7772382009-05-03 13:42:53 +000045
Chris Lattnerc345a802009-03-20 16:06:38 +000046 // If in GNU mode (e.g. -std=gnu99 but not -std=c99) define the raw identifier
47 // in the user's namespace.
48 if (Opts.GNUMode)
49 Define(Buf, MacroName);
Anton Korobeynikove7772382009-05-03 13:42:53 +000050
Chris Lattnerc345a802009-03-20 16:06:38 +000051 // Define __unix.
52 llvm::SmallString<20> TmpStr;
53 TmpStr = "__";
54 TmpStr += MacroName;
55 Define(Buf, TmpStr.c_str());
Anton Korobeynikove7772382009-05-03 13:42:53 +000056
Chris Lattnerc345a802009-03-20 16:06:38 +000057 // Define __unix__.
58 TmpStr += "__";
59 Define(Buf, TmpStr.c_str());
60}
61
Chris Lattnerbd00eb82008-10-05 21:50:58 +000062//===----------------------------------------------------------------------===//
63// Defines specific to certain operating systems.
64//===----------------------------------------------------------------------===//
65
Douglas Gregor5415abd2009-05-21 23:51:30 +000066static void getSolarisDefines(const LangOptions &Opts, std::vector<char> &Defs) {
67 DefineStd(Defs, "sun", Opts);
68 DefineStd(Defs, "unix", Opts);
69 Define(Defs, "__ELF__", "1");
Eli Friedmanff158dd2008-08-20 07:28:14 +000070}
Chris Lattner4b009652007-07-25 00:24:17 +000071
Chris Lattnerab81f162009-03-20 15:55:34 +000072static void getFreeBSDDefines(const LangOptions &Opts, bool is64Bit,
73 const char *Triple, std::vector<char> &Defs) {
Chris Lattner98cb2a22008-10-16 17:04:31 +000074 // FreeBSD defines; list based off of gcc output
75
76 const char *FreeBSD = strstr(Triple, "-freebsd");
77 FreeBSD += strlen("-freebsd");
78 char release[] = "X";
79 release[0] = FreeBSD[0];
80 char version[] = "X00001";
81 version[0] = FreeBSD[0];
82
83 Define(Defs, "__FreeBSD__", release);
84 Define(Defs, "__FreeBSD_cc_version", version);
85 Define(Defs, "__KPRINTF_ATTRIBUTE__");
Chris Lattnerc345a802009-03-20 16:06:38 +000086 DefineStd(Defs, "unix", Opts);
Anton Korobeynikovfb820852009-02-14 16:42:50 +000087 Define(Defs, "__ELF__", "1");
Chris Lattner98cb2a22008-10-16 17:04:31 +000088 if (is64Bit) {
89 Define(Defs, "__LP64__");
90 }
91}
92
Chris Lattnerab81f162009-03-20 15:55:34 +000093static void getDragonFlyDefines(const LangOptions &Opts,
94 std::vector<char> &Defs) {
Chris Lattnerbd00eb82008-10-05 21:50:58 +000095 // DragonFly defines; list based off of gcc output
96 Define(Defs, "__DragonFly__");
97 Define(Defs, "__DragonFly_cc_version", "100001");
98 Define(Defs, "__ELF__");
99 Define(Defs, "__KPRINTF_ATTRIBUTE__");
100 Define(Defs, "__tune_i386__");
Chris Lattnerc345a802009-03-20 16:06:38 +0000101 DefineStd(Defs, "unix", Opts);
Chris Lattnerbd00eb82008-10-05 21:50:58 +0000102}
103
Chris Lattnerab81f162009-03-20 15:55:34 +0000104static void getLinuxDefines(const LangOptions &Opts, std::vector<char> &Defs) {
Chris Lattnerbd00eb82008-10-05 21:50:58 +0000105 // Linux defines; list based off of gcc output
Chris Lattnerc345a802009-03-20 16:06:38 +0000106 DefineStd(Defs, "unix", Opts);
107 DefineStd(Defs, "linux", Opts);
Chris Lattnerbd00eb82008-10-05 21:50:58 +0000108 Define(Defs, "__gnu_linux__");
Argiris Kirtzidis99de9532009-02-14 15:02:45 +0000109 Define(Defs, "__ELF__", "1");
Chris Lattnerbd00eb82008-10-05 21:50:58 +0000110}
111
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000112/// getDarwinNumber - Parse the 'darwin number' out of the specific targe
Daniel Dunbar93f64532009-04-10 19:52:24 +0000113/// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000114/// not defined, return 0's. Return true if we have -darwin in the string or
115/// false otherwise.
Daniel Dunbar93f64532009-04-10 19:52:24 +0000116static bool getDarwinNumber(const char *Triple, unsigned &Maj, unsigned &Min, unsigned &Revision) {
117 Maj = Min = Revision = 0;
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000118 const char *Darwin = strstr(Triple, "-darwin");
119 if (Darwin == 0) return false;
Anton Korobeynikove7772382009-05-03 13:42:53 +0000120
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000121 Darwin += strlen("-darwin");
122 if (Darwin[0] < '0' || Darwin[0] > '9')
123 return true;
Anton Korobeynikove7772382009-05-03 13:42:53 +0000124
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000125 Maj = Darwin[0]-'0';
126 ++Darwin;
Anton Korobeynikove7772382009-05-03 13:42:53 +0000127
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000128 // Handle "darwin11".
129 if (Maj == 1 && Darwin[0] >= '0' && Darwin[0] <= '9') {
Daniel Dunbar93f64532009-04-10 19:52:24 +0000130 Maj = Maj*10 + (Darwin[0] - '0');
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000131 ++Darwin;
132 }
Anton Korobeynikove7772382009-05-03 13:42:53 +0000133
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000134 // Handle minor version: 10.4.9 -> darwin8.9 -> "1049"
Daniel Dunbar93f64532009-04-10 19:52:24 +0000135 if (Darwin[0] != '.')
136 return true;
Anton Korobeynikove7772382009-05-03 13:42:53 +0000137
Daniel Dunbar93f64532009-04-10 19:52:24 +0000138 ++Darwin;
139 if (Darwin[0] < '0' || Darwin[0] > '9')
140 return true;
Anton Korobeynikove7772382009-05-03 13:42:53 +0000141
Daniel Dunbar93f64532009-04-10 19:52:24 +0000142 Min = Darwin[0]-'0';
143 ++Darwin;
144
145 // Handle 10.4.11 -> darwin8.11
146 if (Min == 1 && Darwin[0] >= '0' && Darwin[0] <= '9') {
147 Min = Min*10 + (Darwin[0] - '0');
148 ++Darwin;
149 }
Anton Korobeynikove7772382009-05-03 13:42:53 +0000150
Daniel Dunbar93f64532009-04-10 19:52:24 +0000151 // Handle revision darwin8.9.1
152 if (Darwin[0] != '.')
153 return true;
Anton Korobeynikove7772382009-05-03 13:42:53 +0000154
Daniel Dunbar93f64532009-04-10 19:52:24 +0000155 ++Darwin;
156 if (Darwin[0] < '0' || Darwin[0] > '9')
157 return true;
Anton Korobeynikove7772382009-05-03 13:42:53 +0000158
Daniel Dunbar93f64532009-04-10 19:52:24 +0000159 Revision = Darwin[0]-'0';
160 ++Darwin;
Anton Korobeynikove7772382009-05-03 13:42:53 +0000161
Daniel Dunbar93f64532009-04-10 19:52:24 +0000162 if (Revision == 1 && Darwin[0] >= '0' && Darwin[0] <= '9') {
163 Revision = Revision*10 + (Darwin[0] - '0');
164 ++Darwin;
165 }
Anton Korobeynikove7772382009-05-03 13:42:53 +0000166
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000167 return true;
168}
169
Daniel Dunbar93f64532009-04-10 19:52:24 +0000170static void getDarwinDefines(std::vector<char> &Defs, const LangOptions &Opts) {
Eli Friedman872996c2008-08-20 02:34:37 +0000171 Define(Defs, "__APPLE__");
172 Define(Defs, "__MACH__");
Chris Lattner8405e092009-02-05 07:19:24 +0000173 Define(Defs, "OBJC_NEW_PROPERTIES");
Anton Korobeynikove7772382009-05-03 13:42:53 +0000174
Chris Lattner8181e622009-04-07 16:50:40 +0000175 // __weak is always defined, for use in blocks and with objc pointers.
176 Define(Defs, "__weak", "__attribute__((objc_gc(weak)))");
Anton Korobeynikove7772382009-05-03 13:42:53 +0000177
Chris Lattner8181e622009-04-07 16:50:40 +0000178 // Darwin defines __strong even in C mode (just to nothing).
179 if (!Opts.ObjC1 || Opts.getGCMode() == LangOptions::NonGC)
Chris Lattner33854aa2009-04-07 04:48:21 +0000180 Define(Defs, "__strong", "");
Chris Lattner8181e622009-04-07 16:50:40 +0000181 else
Chris Lattner33854aa2009-04-07 04:48:21 +0000182 Define(Defs, "__strong", "__attribute__((objc_gc(strong)))");
Daniel Dunbar93f64532009-04-10 19:52:24 +0000183}
184
185static void getDarwinOSXDefines(std::vector<char> &Defs, const char *Triple) {
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000186 // Figure out which "darwin number" the target triple is. "darwin9" -> 10.5.
Daniel Dunbar93f64532009-04-10 19:52:24 +0000187 unsigned Maj, Min, Rev;
188 if (getDarwinNumber(Triple, Maj, Min, Rev)) {
189 char MacOSXStr[] = "1000";
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000190 if (Maj >= 4 && Maj <= 13) { // 10.0-10.9
191 // darwin7 -> 1030, darwin8 -> 1040, darwin9 -> 1050, etc.
Daniel Dunbar93f64532009-04-10 19:52:24 +0000192 MacOSXStr[2] = '0' + Maj-4;
193 }
Anton Korobeynikove7772382009-05-03 13:42:53 +0000194
Daniel Dunbar93f64532009-04-10 19:52:24 +0000195 // Handle minor version: 10.4.9 -> darwin8.9 -> "1049"
196 // Cap 10.4.11 -> darwin8.11 -> "1049"
197 MacOSXStr[3] = std::min(Min, 9U)+'0';
198 Define(Defs, "__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", MacOSXStr);
199 }
200}
201
Anton Korobeynikove7772382009-05-03 13:42:53 +0000202static void getDarwinIPhoneOSDefines(std::vector<char> &Defs,
Daniel Dunbar93f64532009-04-10 19:52:24 +0000203 const char *Triple) {
204 // Figure out which "darwin number" the target triple is. "darwin9" -> 10.5.
205 unsigned Maj, Min, Rev;
206 if (getDarwinNumber(Triple, Maj, Min, Rev)) {
207 // When targetting iPhone OS, interpret the minor version and
208 // revision as the iPhone OS version
209 char iPhoneOSStr[] = "10000";
210 if (Min >= 2 && Min <= 9) { // iPhone OS 2.0-9.0
211 // darwin9.2.0 -> 20000, darwin9.3.0 -> 30000, etc.
212 iPhoneOSStr[0] = '0' + Min;
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000213 }
Anton Korobeynikove7772382009-05-03 13:42:53 +0000214
Daniel Dunbar93f64532009-04-10 19:52:24 +0000215 // Handle minor version: 2.2 -> darwin9.2.2 -> 20200
216 iPhoneOSStr[2] = std::min(Rev, 9U)+'0';
Anton Korobeynikove7772382009-05-03 13:42:53 +0000217 Define(Defs, "__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__",
Daniel Dunbar93f64532009-04-10 19:52:24 +0000218 iPhoneOSStr);
Chris Lattnerc5dc8eb2008-09-30 01:00:25 +0000219 }
Eli Friedman872996c2008-08-20 02:34:37 +0000220}
Chris Lattner4b009652007-07-25 00:24:17 +0000221
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000222/// GetDarwinLanguageOptions - Set the default language options for darwin.
223static void GetDarwinLanguageOptions(LangOptions &Opts,
224 const char *Triple) {
225 Opts.NeXTRuntime = true;
Anton Korobeynikove7772382009-05-03 13:42:53 +0000226
Daniel Dunbar93f64532009-04-10 19:52:24 +0000227 unsigned Maj, Min, Rev;
228 if (!getDarwinNumber(Triple, Maj, Min, Rev))
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000229 return;
Anton Korobeynikove7772382009-05-03 13:42:53 +0000230
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000231 // Blocks default to on for 10.6 (darwin10) and beyond.
Fariborz Jahaniand09b9f72009-02-12 17:54:33 +0000232 // As does nonfragile-abi for 64bit mode
Anton Korobeynikove7772382009-05-03 13:42:53 +0000233 if (Maj > 9)
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000234 Opts.Blocks = 1;
Fariborz Jahanian27f58962009-02-24 23:34:44 +0000235
Fariborz Jahanian72efecb2009-02-24 23:38:42 +0000236 if (Maj >= 9 && Opts.ObjC1 && !strncmp(Triple, "x86_64", 6))
237 Opts.ObjCNonFragileABI = 1;
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000238}
239
240
Chris Lattnerbd00eb82008-10-05 21:50:58 +0000241//===----------------------------------------------------------------------===//
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000242// Specific target implementations.
243//===----------------------------------------------------------------------===//
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000244
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000245namespace {
246// PPC abstract base class
247class PPCTargetInfo : public TargetInfo {
248 static const Builtin::Info BuiltinInfo[];
249 static const char * const GCCRegNames[];
250 static const TargetInfo::GCCRegAlias GCCRegAliases[];
251
252public:
253 PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {
254 CharIsSigned = false;
255 }
256 virtual void getTargetBuiltins(const Builtin::Info *&Records,
257 unsigned &NumRecords) const {
Chris Lattner4b009652007-07-25 00:24:17 +0000258 Records = BuiltinInfo;
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000259 NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner4b009652007-07-25 00:24:17 +0000260 }
Anton Korobeynikove7772382009-05-03 13:42:53 +0000261
Chris Lattner79682402009-03-20 15:52:06 +0000262 virtual void getTargetDefines(const LangOptions &Opts,
263 std::vector<char> &Defines) const;
Anton Korobeynikove7772382009-05-03 13:42:53 +0000264
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000265 virtual const char *getVAListDeclaration() const {
Chris Lattnera07708f2008-10-27 01:11:29 +0000266 return "typedef char* __builtin_va_list;";
267 // This is the right definition for ABI/V4: System V.4/eabi.
268 /*return "typedef struct __va_list_tag {"
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000269 " unsigned char gpr;"
270 " unsigned char fpr;"
271 " unsigned short reserved;"
272 " void* overflow_arg_area;"
273 " void* reg_save_area;"
Chris Lattnera07708f2008-10-27 01:11:29 +0000274 "} __builtin_va_list[1];";*/
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000275 }
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000276 virtual const char *getTargetPrefix() const {
277 return "ppc";
Anders Carlsson4ce42302007-11-27 04:11:28 +0000278 }
Anton Korobeynikove7772382009-05-03 13:42:53 +0000279 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000280 unsigned &NumNames) const;
Anton Korobeynikove7772382009-05-03 13:42:53 +0000281 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000282 unsigned &NumAliases) const;
Anders Carlsson36834a72009-02-28 17:11:49 +0000283 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattnerc49cc1a2009-04-26 07:16:29 +0000284 TargetInfo::ConstraintInfo &Info) const {
Anders Carlsson36834a72009-02-28 17:11:49 +0000285 switch (*Name) {
Anders Carlsson4ce42302007-11-27 04:11:28 +0000286 default: return false;
287 case 'O': // Zero
288 return true;
289 case 'b': // Base register
290 case 'f': // Floating point register
Chris Lattnerc49cc1a2009-04-26 07:16:29 +0000291 Info.setAllowsRegister();
Anders Carlsson4ce42302007-11-27 04:11:28 +0000292 return true;
293 }
294 }
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000295 virtual const char *getClobbers() const {
296 return "";
Anders Carlsson4ce42302007-11-27 04:11:28 +0000297 }
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000298};
Anders Carlsson4ce42302007-11-27 04:11:28 +0000299
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000300const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
Douglas Gregor2e8a7aa2009-02-16 21:58:21 +0000301#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
302#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000303#include "clang/AST/PPCBuiltins.def"
304};
Anton Korobeynikove7772382009-05-03 13:42:53 +0000305
306
Chris Lattnerbef1d722009-03-02 22:27:17 +0000307/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
308/// #defines that are not tied to a specific subtarget.
Chris Lattner79682402009-03-20 15:52:06 +0000309void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
310 std::vector<char> &Defs) const {
Chris Lattnerbef1d722009-03-02 22:27:17 +0000311 // Target identification.
312 Define(Defs, "__ppc__");
313 Define(Defs, "_ARCH_PPC");
314 Define(Defs, "__POWERPC__");
315 if (PointerWidth == 64) {
316 Define(Defs, "_ARCH_PPC64");
317 Define(Defs, "_LP64");
318 Define(Defs, "__LP64__");
319 Define(Defs, "__ppc64__");
320 } else {
321 Define(Defs, "__ppc__");
322 }
Anton Korobeynikove7772382009-05-03 13:42:53 +0000323
Chris Lattnerbef1d722009-03-02 22:27:17 +0000324 // Target properties.
325 Define(Defs, "_BIG_ENDIAN");
326 Define(Defs, "__BIG_ENDIAN__");
Anton Korobeynikove7772382009-05-03 13:42:53 +0000327
Chris Lattnerbef1d722009-03-02 22:27:17 +0000328 // Subtarget options.
329 Define(Defs, "__NATURAL_ALIGNMENT__");
330 Define(Defs, "__REGISTER_PREFIX__", "");
Anton Korobeynikove7772382009-05-03 13:42:53 +0000331
Chris Lattnerbef1d722009-03-02 22:27:17 +0000332 // FIXME: Should be controlled by command line option.
333 Define(Defs, "__LONG_DOUBLE_128__");
334}
335
Chris Lattner9fd73612008-04-21 18:56:49 +0000336
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000337const char * const PPCTargetInfo::GCCRegNames[] = {
338 "0", "1", "2", "3", "4", "5", "6", "7",
339 "8", "9", "10", "11", "12", "13", "14", "15",
340 "16", "17", "18", "19", "20", "21", "22", "23",
341 "24", "25", "26", "27", "28", "29", "30", "31",
342 "0", "1", "2", "3", "4", "5", "6", "7",
343 "8", "9", "10", "11", "12", "13", "14", "15",
344 "16", "17", "18", "19", "20", "21", "22", "23",
345 "24", "25", "26", "27", "28", "29", "30", "31",
346 "mq", "lr", "ctr", "ap",
347 "0", "1", "2", "3", "4", "5", "6", "7",
348 "xer",
349 "0", "1", "2", "3", "4", "5", "6", "7",
350 "8", "9", "10", "11", "12", "13", "14", "15",
351 "16", "17", "18", "19", "20", "21", "22", "23",
352 "24", "25", "26", "27", "28", "29", "30", "31",
353 "vrsave", "vscr",
354 "spe_acc", "spefscr",
355 "sfp"
356};
Chris Lattner4b009652007-07-25 00:24:17 +0000357
Anton Korobeynikove7772382009-05-03 13:42:53 +0000358void PPCTargetInfo::getGCCRegNames(const char * const *&Names,
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000359 unsigned &NumNames) const {
360 Names = GCCRegNames;
361 NumNames = llvm::array_lengthof(GCCRegNames);
362}
Chris Lattner4b009652007-07-25 00:24:17 +0000363
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000364const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
365 // While some of these aliases do map to different registers
366 // they still share the same register name.
Anton Korobeynikove7772382009-05-03 13:42:53 +0000367 { { "cc", "cr0", "fr0", "r0", "v0"}, "0" },
368 { { "cr1", "fr1", "r1", "sp", "v1"}, "1" },
369 { { "cr2", "fr2", "r2", "toc", "v2"}, "2" },
370 { { "cr3", "fr3", "r3", "v3"}, "3" },
371 { { "cr4", "fr4", "r4", "v4"}, "4" },
372 { { "cr5", "fr5", "r5", "v5"}, "5" },
373 { { "cr6", "fr6", "r6", "v6"}, "6" },
374 { { "cr7", "fr7", "r7", "v7"}, "7" },
375 { { "fr8", "r8", "v8"}, "8" },
376 { { "fr9", "r9", "v9"}, "9" },
377 { { "fr10", "r10", "v10"}, "10" },
378 { { "fr11", "r11", "v11"}, "11" },
379 { { "fr12", "r12", "v12"}, "12" },
380 { { "fr13", "r13", "v13"}, "13" },
381 { { "fr14", "r14", "v14"}, "14" },
382 { { "fr15", "r15", "v15"}, "15" },
383 { { "fr16", "r16", "v16"}, "16" },
384 { { "fr17", "r17", "v17"}, "17" },
385 { { "fr18", "r18", "v18"}, "18" },
386 { { "fr19", "r19", "v19"}, "19" },
387 { { "fr20", "r20", "v20"}, "20" },
388 { { "fr21", "r21", "v21"}, "21" },
389 { { "fr22", "r22", "v22"}, "22" },
390 { { "fr23", "r23", "v23"}, "23" },
391 { { "fr24", "r24", "v24"}, "24" },
392 { { "fr25", "r25", "v25"}, "25" },
393 { { "fr26", "r26", "v26"}, "26" },
394 { { "fr27", "r27", "v27"}, "27" },
395 { { "fr28", "r28", "v28"}, "28" },
396 { { "fr29", "r29", "v29"}, "29" },
397 { { "fr30", "r30", "v30"}, "30" },
398 { { "fr31", "r31", "v31"}, "31" },
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000399};
400
Anton Korobeynikove7772382009-05-03 13:42:53 +0000401void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000402 unsigned &NumAliases) const {
403 Aliases = GCCRegAliases;
404 NumAliases = llvm::array_lengthof(GCCRegAliases);
405}
406} // end anonymous namespace.
Chris Lattner4b009652007-07-25 00:24:17 +0000407
408namespace {
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000409class PPC32TargetInfo : public PPCTargetInfo {
Chris Lattner4b009652007-07-25 00:24:17 +0000410public:
Eli Friedman2b161652008-08-21 00:13:15 +0000411 PPC32TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
412 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
413 "i64:64:64-f32:32:32-f64:64:64-v128:128:128";
414 }
Chris Lattner4b009652007-07-25 00:24:17 +0000415};
416} // end anonymous namespace.
417
418namespace {
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000419class PPC64TargetInfo : public PPCTargetInfo {
Chris Lattner4b009652007-07-25 00:24:17 +0000420public:
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000421 PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
Chris Lattnere5fde952008-05-09 06:17:04 +0000422 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedman2b161652008-08-21 00:13:15 +0000423 DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
424 "i64:64:64-f32:32:32-f64:64:64-v128:128:128";
Chris Lattnere5fde952008-05-09 06:17:04 +0000425 }
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000426};
427} // end anonymous namespace.
428
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000429
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000430namespace {
431class DarwinPPCTargetInfo : public PPC32TargetInfo {
432public:
433 DarwinPPCTargetInfo(const std::string& triple) : PPC32TargetInfo(triple) {}
Chris Lattner79682402009-03-20 15:52:06 +0000434 virtual void getTargetDefines(const LangOptions &Opts,
435 std::vector<char> &Defines) const {
436 PPC32TargetInfo::getTargetDefines(Opts, Defines);
Daniel Dunbar93f64532009-04-10 19:52:24 +0000437 getDarwinDefines(Defines, Opts);
438 getDarwinOSXDefines(Defines, getTargetTriple());
Chris Lattner4b009652007-07-25 00:24:17 +0000439 }
Daniel Dunbar34542952008-08-23 08:43:39 +0000440
Chris Lattnerddae7102008-12-04 22:54:33 +0000441 /// getDefaultLangOptions - Allow the target to specify default settings for
442 /// various language options. These may be overridden by command line
Anton Korobeynikove7772382009-05-03 13:42:53 +0000443 /// options.
Chris Lattnerddae7102008-12-04 22:54:33 +0000444 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000445 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattnerddae7102008-12-04 22:54:33 +0000446 }
Eli Friedmanfd5a4122008-08-20 23:11:40 +0000447};
448} // end anonymous namespace.
449
450namespace {
451class DarwinPPC64TargetInfo : public PPC64TargetInfo {
452public:
453 DarwinPPC64TargetInfo(const std::string& triple) : PPC64TargetInfo(triple) {}
Chris Lattner79682402009-03-20 15:52:06 +0000454 virtual void getTargetDefines(const LangOptions &Opts,
455 std::vector<char> &Defines) const {
456 PPC64TargetInfo::getTargetDefines(Opts, Defines);
Daniel Dunbar93f64532009-04-10 19:52:24 +0000457 getDarwinDefines(Defines, Opts);
458 getDarwinOSXDefines(Defines, getTargetTriple());
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000459 }
Daniel Dunbar34542952008-08-23 08:43:39 +0000460
Chris Lattnerddae7102008-12-04 22:54:33 +0000461 /// getDefaultLangOptions - Allow the target to specify default settings for
462 /// various language options. These may be overridden by command line
Anton Korobeynikove7772382009-05-03 13:42:53 +0000463 /// options.
Chris Lattnerddae7102008-12-04 22:54:33 +0000464 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000465 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattnerddae7102008-12-04 22:54:33 +0000466 }
Chris Lattner4b009652007-07-25 00:24:17 +0000467};
468} // end anonymous namespace.
469
470namespace {
Eli Friedman872996c2008-08-20 02:34:37 +0000471// Namespace for x86 abstract base class
472const Builtin::Info BuiltinInfo[] = {
Douglas Gregor2e8a7aa2009-02-16 21:58:21 +0000473#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
474#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
Eli Friedman872996c2008-08-20 02:34:37 +0000475#include "clang/AST/X86Builtins.def"
476};
Eli Friedman0b7b1cb2008-05-20 14:21:01 +0000477
Eli Friedman872996c2008-08-20 02:34:37 +0000478const char *GCCRegNames[] = {
479 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
480 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
481 "argp", "flags", "fspr", "dirflag", "frame",
482 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
483 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
484 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
485 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
486};
487
488const TargetInfo::GCCRegAlias GCCRegAliases[] = {
489 { { "al", "ah", "eax", "rax" }, "ax" },
490 { { "bl", "bh", "ebx", "rbx" }, "bx" },
491 { { "cl", "ch", "ecx", "rcx" }, "cx" },
492 { { "dl", "dh", "edx", "rdx" }, "dx" },
493 { { "esi", "rsi" }, "si" },
494 { { "edi", "rdi" }, "di" },
495 { { "esp", "rsp" }, "sp" },
496 { { "ebp", "rbp" }, "bp" },
497};
498
499// X86 target abstract base class; x86-32 and x86-64 are very close, so
500// most of the implementation can be shared.
501class X86TargetInfo : public TargetInfo {
Chris Lattner715fe4c2009-03-02 22:40:39 +0000502 enum X86SSEEnum {
503 NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42
504 } SSELevel;
Eli Friedman872996c2008-08-20 02:34:37 +0000505public:
Anton Korobeynikove7772382009-05-03 13:42:53 +0000506 X86TargetInfo(const std::string& triple)
Daniel Dunbar07181d72009-05-06 03:16:41 +0000507 : TargetInfo(triple), SSELevel(NoMMXSSE) {
Eli Friedman872996c2008-08-20 02:34:37 +0000508 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
Chris Lattner4b009652007-07-25 00:24:17 +0000509 }
510 virtual void getTargetBuiltins(const Builtin::Info *&Records,
511 unsigned &NumRecords) const {
Eli Friedman872996c2008-08-20 02:34:37 +0000512 Records = BuiltinInfo;
513 NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner4b009652007-07-25 00:24:17 +0000514 }
Anders Carlsson333052c2007-12-08 19:32:57 +0000515 virtual const char *getTargetPrefix() const {
Eli Friedman872996c2008-08-20 02:34:37 +0000516 return "x86";
Anton Korobeynikove7772382009-05-03 13:42:53 +0000517 }
518 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedman872996c2008-08-20 02:34:37 +0000519 unsigned &NumNames) const {
520 Names = GCCRegNames;
521 NumNames = llvm::array_lengthof(GCCRegNames);
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000522 }
Anton Korobeynikove7772382009-05-03 13:42:53 +0000523 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000524 unsigned &NumAliases) const {
Eli Friedman872996c2008-08-20 02:34:37 +0000525 Aliases = GCCRegAliases;
526 NumAliases = llvm::array_lengthof(GCCRegAliases);
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000527 }
Anders Carlsson36834a72009-02-28 17:11:49 +0000528 virtual bool validateAsmConstraint(const char *&Name,
Eli Friedman872996c2008-08-20 02:34:37 +0000529 TargetInfo::ConstraintInfo &info) const;
530 virtual std::string convertConstraint(const char Constraint) const;
Anders Carlsson4ce42302007-11-27 04:11:28 +0000531 virtual const char *getClobbers() const {
Eli Friedman872996c2008-08-20 02:34:37 +0000532 return "~{dirflag},~{fpsr},~{flags}";
533 }
Chris Lattner79682402009-03-20 15:52:06 +0000534 virtual void getTargetDefines(const LangOptions &Opts,
535 std::vector<char> &Defines) const;
Daniel Dunbar0838f962009-05-06 21:07:50 +0000536 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
537 const std::string &Name,
538 bool Enabled) const;
Daniel Dunbar07181d72009-05-06 03:16:41 +0000539 virtual void getDefaultFeatures(const std::string &CPU,
Daniel Dunbar0838f962009-05-06 21:07:50 +0000540 llvm::StringMap<bool> &Features) const;
Daniel Dunbar07181d72009-05-06 03:16:41 +0000541 virtual void HandleTargetFeatures(const llvm::StringMap<bool> &Features);
Chris Lattner4b009652007-07-25 00:24:17 +0000542};
Chris Lattner7d6220c2009-03-02 22:20:04 +0000543
Daniel Dunbar07181d72009-05-06 03:16:41 +0000544void X86TargetInfo::getDefaultFeatures(const std::string &CPU,
Daniel Dunbar0838f962009-05-06 21:07:50 +0000545 llvm::StringMap<bool> &Features) const {
Daniel Dunbar07181d72009-05-06 03:16:41 +0000546 // FIXME: This should not be here.
547 Features["3dnow"] = false;
548 Features["3dnowa"] = false;
549 Features["mmx"] = false;
550 Features["sse"] = false;
551 Features["sse2"] = false;
552 Features["sse3"] = false;
553 Features["ssse3"] = false;
554 Features["sse41"] = false;
555 Features["sse42"] = false;
Anton Korobeynikove7772382009-05-03 13:42:53 +0000556
Daniel Dunbar07181d72009-05-06 03:16:41 +0000557 // LLVM does not currently recognize this.
558 // Features["sse4a"] = false;
Anton Korobeynikove7772382009-05-03 13:42:53 +0000559
Daniel Dunbar07181d72009-05-06 03:16:41 +0000560 // FIXME: This *really* should not be here.
561
562 // X86_64 always has SSE2.
563 if (PointerWidth == 64)
564 Features["sse2"] = Features["sse"] = Features["mmx"] = true;
565
Daniel Dunbarc2e55de2009-05-06 21:56:32 +0000566 if (CPU == "generic" || CPU == "i386" || CPU == "i486" || CPU == "i586" ||
567 CPU == "pentium" || CPU == "i686" || CPU == "pentiumpro")
568 ;
569 else if (CPU == "pentium-mmx" || CPU == "pentium2")
570 setFeatureEnabled(Features, "mmx", true);
571 else if (CPU == "pentium3")
572 setFeatureEnabled(Features, "sse", true);
573 else if (CPU == "pentium-m" || CPU == "pentium4" || CPU == "x86-64")
574 setFeatureEnabled(Features, "sse2", true);
575 else if (CPU == "yonah" || CPU == "prescott" || CPU == "nocona")
576 setFeatureEnabled(Features, "sse3", true);
577 else if (CPU == "core2")
578 setFeatureEnabled(Features, "ssse3", true);
579 else if (CPU == "penryn") {
580 setFeatureEnabled(Features, "sse4", true);
581 Features["sse42"] = false;
582 } else if (CPU == "atom")
583 setFeatureEnabled(Features, "sse3", true);
584 else if (CPU == "corei7")
585 setFeatureEnabled(Features, "sse4", true);
586 else if (CPU == "k6" || CPU == "winchip-c6")
587 setFeatureEnabled(Features, "mmx", true);
588 else if (CPU == "k6-2" || CPU == "k6-3" || CPU == "athlon" ||
589 CPU == "athlon-tbird" || CPU == "winchip2" || CPU == "c3") {
590 setFeatureEnabled(Features, "mmx", true);
591 setFeatureEnabled(Features, "3dnow", true);
592 } else if (CPU == "athlon-4" || CPU == "athlon-xp" || CPU == "athlon-mp") {
593 setFeatureEnabled(Features, "sse", true);
594 setFeatureEnabled(Features, "3dnowa", true);
595 } else if (CPU == "k8" || CPU == "opteron" || CPU == "athlon64" ||
596 CPU == "athlon-fx") {
597 setFeatureEnabled(Features, "sse2", true);
598 setFeatureEnabled(Features, "3dnowa", true);
599 } else if (CPU == "c3-2")
600 setFeatureEnabled(Features, "sse", true);
Daniel Dunbar07181d72009-05-06 03:16:41 +0000601}
602
Daniel Dunbar0838f962009-05-06 21:07:50 +0000603bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
604 const std::string &Name,
605 bool Enabled) const {
606 // FIXME: This *really* should not be here.
607 if (!Features.count(Name) && Name != "sse4")
608 return false;
609
610 if (Enabled) {
611 if (Name == "mmx")
612 Features["mmx"] = true;
613 else if (Name == "sse")
614 Features["mmx"] = Features["sse"] = true;
615 else if (Name == "sse2")
616 Features["mmx"] = Features["sse"] = Features["sse2"] = true;
617 else if (Name == "sse3")
618 Features["mmx"] = Features["sse"] = Features["sse2"] =
619 Features["sse3"] = true;
620 else if (Name == "ssse3")
621 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
622 Features["ssse3"] = true;
623 else if (Name == "sse4")
624 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
625 Features["ssse3"] = Features["sse41"] = Features["sse42"] = true;
626 else if (Name == "3dnow")
627 Features["3dnowa"] = true;
628 else if (Name == "3dnowa")
629 Features["3dnow"] = Features["3dnowa"] = true;
630 } else {
631 if (Name == "mmx")
632 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
633 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
634 else if (Name == "sse")
635 Features["sse"] = Features["sse2"] = Features["sse3"] =
636 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
637 else if (Name == "sse2")
638 Features["sse2"] = Features["sse3"] = Features["ssse3"] =
639 Features["sse41"] = Features["sse42"] = false;
640 else if (Name == "sse3")
641 Features["sse3"] = Features["ssse3"] = Features["sse41"] =
642 Features["sse42"] = false;
643 else if (Name == "ssse3")
644 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
645 else if (Name == "sse4")
646 Features["sse41"] = Features["sse42"] = false;
647 else if (Name == "3dnow")
648 Features["3dnow"] = Features["3dnowa"] = false;
649 else if (Name == "3dnowa")
650 Features["3dnowa"] = false;
651 }
652
653 return true;
654}
655
Daniel Dunbar07181d72009-05-06 03:16:41 +0000656/// HandleTargetOptions - Perform initialization based on the user
657/// configured set of features.
658void X86TargetInfo::HandleTargetFeatures(const llvm::StringMap<bool>&Features) {
659 if (Features.lookup("sse42"))
660 SSELevel = SSE42;
661 else if (Features.lookup("sse41"))
662 SSELevel = SSE41;
663 else if (Features.lookup("ssse3"))
664 SSELevel = SSSE3;
665 else if (Features.lookup("sse3"))
666 SSELevel = SSE3;
667 else if (Features.lookup("sse2"))
668 SSELevel = SSE2;
669 else if (Features.lookup("sse"))
670 SSELevel = SSE1;
671 else if (Features.lookup("mmx"))
672 SSELevel = MMX;
Chris Lattner7d6220c2009-03-02 22:20:04 +0000673}
Chris Lattnerbef1d722009-03-02 22:27:17 +0000674
675/// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines
676/// that are not tied to a specific subtarget.
Chris Lattner79682402009-03-20 15:52:06 +0000677void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
678 std::vector<char> &Defs) const {
Chris Lattnerbef1d722009-03-02 22:27:17 +0000679 // Target identification.
680 if (PointerWidth == 64) {
681 Define(Defs, "_LP64");
682 Define(Defs, "__LP64__");
683 Define(Defs, "__amd64__");
684 Define(Defs, "__amd64");
685 Define(Defs, "__x86_64");
686 Define(Defs, "__x86_64__");
Chris Lattnerbef1d722009-03-02 22:27:17 +0000687 } else {
Chris Lattnerc345a802009-03-20 16:06:38 +0000688 DefineStd(Defs, "i386", Opts);
Chris Lattnerbef1d722009-03-02 22:27:17 +0000689 }
Anton Korobeynikove7772382009-05-03 13:42:53 +0000690
Chris Lattnerbef1d722009-03-02 22:27:17 +0000691 // Target properties.
692 Define(Defs, "__LITTLE_ENDIAN__");
Anton Korobeynikove7772382009-05-03 13:42:53 +0000693
Chris Lattnerbef1d722009-03-02 22:27:17 +0000694 // Subtarget options.
695 Define(Defs, "__nocona");
696 Define(Defs, "__nocona__");
697 Define(Defs, "__tune_nocona__");
Chris Lattnerbef1d722009-03-02 22:27:17 +0000698 Define(Defs, "__REGISTER_PREFIX__", "");
Chris Lattner715fe4c2009-03-02 22:40:39 +0000699
Chris Lattner25ac1c12009-04-19 17:32:33 +0000700 // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline
701 // functions in glibc header files that use FP Stack inline asm which the
702 // backend can't deal with (PR879).
703 Define(Defs, "__NO_MATH_INLINES");
Anton Korobeynikove7772382009-05-03 13:42:53 +0000704
Chris Lattner715fe4c2009-03-02 22:40:39 +0000705 // Each case falls through to the previous one here.
706 switch (SSELevel) {
707 case SSE42:
708 Define(Defs, "__SSE4_2__");
709 case SSE41:
710 Define(Defs, "__SSE4_1__");
711 case SSSE3:
712 Define(Defs, "__SSSE3__");
713 case SSE3:
714 Define(Defs, "__SSE3__");
715 case SSE2:
716 Define(Defs, "__SSE2__");
717 Define(Defs, "__SSE2_MATH__"); // -mfp-math=sse always implied.
718 case SSE1:
719 Define(Defs, "__SSE__");
720 Define(Defs, "__SSE_MATH__"); // -mfp-math=sse always implied.
721 case MMX:
722 Define(Defs, "__MMX__");
723 case NoMMXSSE:
724 break;
725 }
Chris Lattnerbef1d722009-03-02 22:27:17 +0000726}
Anton Korobeynikove7772382009-05-03 13:42:53 +0000727
728
Eli Friedman872996c2008-08-20 02:34:37 +0000729bool
Anders Carlsson36834a72009-02-28 17:11:49 +0000730X86TargetInfo::validateAsmConstraint(const char *&Name,
Chris Lattnerc49cc1a2009-04-26 07:16:29 +0000731 TargetInfo::ConstraintInfo &Info) const {
Anders Carlsson36834a72009-02-28 17:11:49 +0000732 switch (*Name) {
Eli Friedman872996c2008-08-20 02:34:37 +0000733 default: return false;
734 case 'a': // eax.
735 case 'b': // ebx.
736 case 'c': // ecx.
737 case 'd': // edx.
738 case 'S': // esi.
739 case 'D': // edi.
740 case 'A': // edx:eax.
741 case 't': // top of floating point stack.
742 case 'u': // second from top of floating point stack.
743 case 'q': // Any register accessible as [r]l: a, b, c, and d.
Anders Carlsson2285e622008-10-06 00:41:45 +0000744 case 'y': // Any MMX register.
Anders Carlssond2459f92008-10-06 19:17:39 +0000745 case 'x': // Any SSE register.
Eli Friedman872996c2008-08-20 02:34:37 +0000746 case 'Q': // Any register accessible as [r]h: a, b, c, and d.
Anton Korobeynikove7772382009-05-03 13:42:53 +0000747 case 'e': // 32-bit signed integer constant for use with zero-extending
Anders Carlssonff235da2009-01-24 18:03:09 +0000748 // x86_64 instructions.
Anton Korobeynikove7772382009-05-03 13:42:53 +0000749 case 'Z': // 32-bit unsigned integer constant for use with zero-extending
Anders Carlssonff235da2009-01-24 18:03:09 +0000750 // x86_64 instructions.
Eli Friedman872996c2008-08-20 02:34:37 +0000751 case 'N': // unsigned 8-bit integer constant for use with in and out
752 // instructions.
Chris Lattnerc49cc1a2009-04-26 07:16:29 +0000753 Info.setAllowsRegister();
Eli Friedman872996c2008-08-20 02:34:37 +0000754 return true;
755 }
756}
757
758std::string
759X86TargetInfo::convertConstraint(const char Constraint) const {
760 switch (Constraint) {
761 case 'a': return std::string("{ax}");
762 case 'b': return std::string("{bx}");
763 case 'c': return std::string("{cx}");
764 case 'd': return std::string("{dx}");
765 case 'S': return std::string("{si}");
766 case 'D': return std::string("{di}");
767 case 't': // top of floating point stack.
768 return std::string("{st}");
769 case 'u': // second from top of floating point stack.
770 return std::string("{st(1)}"); // second from top of floating point stack.
771 default:
772 return std::string(1, Constraint);
773 }
774}
Eli Friedman872996c2008-08-20 02:34:37 +0000775} // end anonymous namespace
Chris Lattner4b009652007-07-25 00:24:17 +0000776
777namespace {
Eli Friedman872996c2008-08-20 02:34:37 +0000778// X86-32 generic target
779class X86_32TargetInfo : public X86TargetInfo {
Chris Lattner4b009652007-07-25 00:24:17 +0000780public:
Eli Friedman872996c2008-08-20 02:34:37 +0000781 X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
782 DoubleAlign = LongLongAlign = 32;
783 LongDoubleWidth = 96;
784 LongDoubleAlign = 32;
Eli Friedman2b161652008-08-21 00:13:15 +0000785 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
786 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
787 "a0:0:64-f80:32:32";
Eli Friedman04ede302009-03-29 20:31:09 +0000788 SizeType = UnsignedInt;
789 PtrDiffType = SignedInt;
790 IntPtrType = SignedInt;
Anton Korobeynikov8fcffeb2009-04-03 23:38:25 +0000791 RegParmMax = 3;
Eli Friedman872996c2008-08-20 02:34:37 +0000792 }
793 virtual const char *getVAListDeclaration() const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000794 return "typedef char* __builtin_va_list;";
Eli Friedman872996c2008-08-20 02:34:37 +0000795 }
Eli Friedman872996c2008-08-20 02:34:37 +0000796};
797} // end anonymous namespace
798
799namespace {
800// x86-32 Darwin (OS X) target
801class DarwinI386TargetInfo : public X86_32TargetInfo {
802public:
803 DarwinI386TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
804 LongDoubleWidth = 128;
805 LongDoubleAlign = 128;
Eli Friedman04ede302009-03-29 20:31:09 +0000806 SizeType = UnsignedLong;
807 IntPtrType = SignedLong;
Eli Friedman2b161652008-08-21 00:13:15 +0000808 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
809 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
810 "a0:0:64-f80:128:128";
Eli Friedman8f575172009-04-19 21:38:35 +0000811 TLSSupported = false;
Eli Friedman872996c2008-08-20 02:34:37 +0000812 }
Daniel Dunbarc3a48932009-03-31 23:42:16 +0000813
Anton Korobeynikove7772382009-05-03 13:42:53 +0000814 virtual const char *getStringSymbolPrefix(bool IsConstant) const {
Daniel Dunbarc3a48932009-03-31 23:42:16 +0000815 return IsConstant ? "\01LC" : "\01lC";
816 }
817
Anton Korobeynikove7772382009-05-03 13:42:53 +0000818 virtual const char *getUnicodeStringSymbolPrefix() const {
Daniel Dunbar6a916482009-04-03 00:57:44 +0000819 return "__utf16_string_";
820 }
821
Anton Korobeynikove7772382009-05-03 13:42:53 +0000822 virtual const char *getUnicodeStringSection() const {
Daniel Dunbar6a916482009-04-03 00:57:44 +0000823 return "__TEXT,__ustring";
824 }
825
Anton Korobeynikove7772382009-05-03 13:42:53 +0000826 virtual const char *getCFStringSymbolPrefix() const {
Daniel Dunbarc3a48932009-03-31 23:42:16 +0000827 return "\01LC";
828 }
829
Chris Lattner79682402009-03-20 15:52:06 +0000830 virtual void getTargetDefines(const LangOptions &Opts,
831 std::vector<char> &Defines) const {
832 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Daniel Dunbar93f64532009-04-10 19:52:24 +0000833 getDarwinDefines(Defines, Opts);
834 getDarwinOSXDefines(Defines, getTargetTriple());
Eli Friedman872996c2008-08-20 02:34:37 +0000835 }
Daniel Dunbarc3a48932009-03-31 23:42:16 +0000836
Chris Lattnerddae7102008-12-04 22:54:33 +0000837 /// getDefaultLangOptions - Allow the target to specify default settings for
838 /// various language options. These may be overridden by command line
Anton Korobeynikove7772382009-05-03 13:42:53 +0000839 /// options.
Chris Lattnerddae7102008-12-04 22:54:33 +0000840 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattnerd7bc88b2008-12-04 23:20:07 +0000841 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattnerddae7102008-12-04 22:54:33 +0000842 }
Eli Friedman872996c2008-08-20 02:34:37 +0000843};
844} // end anonymous namespace
845
846namespace {
Chris Lattner98cb2a22008-10-16 17:04:31 +0000847// x86-32 FreeBSD target
848class FreeBSDX86_32TargetInfo : public X86_32TargetInfo {
849public:
Eli Friedman7cca0982008-11-02 02:43:55 +0000850 FreeBSDX86_32TargetInfo(const std::string& triple) :
Eli Friedman04ede302009-03-29 20:31:09 +0000851 X86_32TargetInfo(triple) { }
Chris Lattner79682402009-03-20 15:52:06 +0000852 virtual void getTargetDefines(const LangOptions &Opts,
853 std::vector<char> &Defines) const {
854 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerab81f162009-03-20 15:55:34 +0000855 getFreeBSDDefines(Opts, 0, getTargetTriple(), Defines);
Chris Lattner98cb2a22008-10-16 17:04:31 +0000856 }
857};
858} // end anonymous namespace
859
860namespace {
Chris Lattnerd4faca42008-08-23 18:23:14 +0000861// x86-32 DragonFly target
862class DragonFlyX86_32TargetInfo : public X86_32TargetInfo {
863public:
Eli Friedman7cca0982008-11-02 02:43:55 +0000864 DragonFlyX86_32TargetInfo(const std::string& triple) :
Eli Friedman04ede302009-03-29 20:31:09 +0000865 X86_32TargetInfo(triple) { }
Chris Lattner79682402009-03-20 15:52:06 +0000866 virtual void getTargetDefines(const LangOptions &Opts,
867 std::vector<char> &Defines) const {
868 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerab81f162009-03-20 15:55:34 +0000869 getDragonFlyDefines(Opts, Defines);
Chris Lattnerd4faca42008-08-23 18:23:14 +0000870 }
871};
872} // end anonymous namespace
873
874namespace {
Eli Friedman5fb0a022008-08-21 00:24:02 +0000875// x86-32 Linux target
876class LinuxX86_32TargetInfo : public X86_32TargetInfo {
877public:
878 LinuxX86_32TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
Chris Lattner5edfe012008-10-05 19:44:25 +0000879 UserLabelPrefix = "";
Eli Friedman5fb0a022008-08-21 00:24:02 +0000880 }
Chris Lattner79682402009-03-20 15:52:06 +0000881 virtual void getTargetDefines(const LangOptions &Opts,
882 std::vector<char> &Defines) const {
883 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerab81f162009-03-20 15:55:34 +0000884 getLinuxDefines(Opts, Defines);
Eli Friedman5fb0a022008-08-21 00:24:02 +0000885 }
886};
887} // end anonymous namespace
888
889namespace {
Douglas Gregor5415abd2009-05-21 23:51:30 +0000890// x86-32 Solaris target
891class SolarisX86_32TargetInfo : public X86_32TargetInfo {
892public:
893 SolarisX86_32TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
894 UserLabelPrefix = "";
895 WCharType = WCharType = SignedLong;
896 }
897 virtual void getTargetDefines(const LangOptions &Opts,
898 std::vector<char> &Defines) const {
899 X86_32TargetInfo::getTargetDefines(Opts, Defines);
900 getSolarisDefines(Opts, Defines);
901 }
902};
903} // end anonymous namespace
904
905
906namespace {
Eli Friedman23cb7912008-08-21 01:40:19 +0000907// x86-32 Windows target
908class WindowsX86_32TargetInfo : public X86_32TargetInfo {
909public:
910 WindowsX86_32TargetInfo(const std::string& triple)
911 : X86_32TargetInfo(triple) {
Eli Friedman8f575172009-04-19 21:38:35 +0000912 TLSSupported = false;
Eli Friedman23cb7912008-08-21 01:40:19 +0000913 // FIXME: Fix wchar_t.
914 // FIXME: We should probably enable -fms-extensions by default for
915 // this target.
916 }
Chris Lattner79682402009-03-20 15:52:06 +0000917 virtual void getTargetDefines(const LangOptions &Opts,
918 std::vector<char> &Defines) const {
919 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Eli Friedman23cb7912008-08-21 01:40:19 +0000920 // This list is based off of the the list of things MingW defines
Eli Friedman23cb7912008-08-21 01:40:19 +0000921 Define(Defines, "_WIN32");
Chris Lattnerc345a802009-03-20 16:06:38 +0000922 DefineStd(Defines, "WIN32", Opts);
923 DefineStd(Defines, "WINNT", Opts);
Eli Friedman23cb7912008-08-21 01:40:19 +0000924 Define(Defines, "_X86_");
925 Define(Defines, "__MSVCRT__");
926 }
927};
928} // end anonymous namespace
929
930namespace {
Eli Friedman872996c2008-08-20 02:34:37 +0000931// x86-64 generic target
932class X86_64TargetInfo : public X86TargetInfo {
933public:
Chris Lattner79682402009-03-20 15:52:06 +0000934 X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) {
Chris Lattnere5fde952008-05-09 06:17:04 +0000935 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Chris Lattner4dfc45a2009-01-28 06:58:19 +0000936 DoubleAlign = LongLongAlign = 64;
Eli Friedman0b7b1cb2008-05-20 14:21:01 +0000937 LongDoubleWidth = 128;
938 LongDoubleAlign = 128;
Chris Lattnerbfbfbaf2009-02-05 07:32:46 +0000939 IntMaxType = SignedLong;
940 UIntMaxType = UnsignedLong;
Anton Korobeynikov8fcffeb2009-04-03 23:38:25 +0000941 RegParmMax = 6;
Chris Lattnerbfbfbaf2009-02-05 07:32:46 +0000942
Eli Friedman2b161652008-08-21 00:13:15 +0000943 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
944 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
945 "a0:0:64-f80:128:128";
Chris Lattner4b009652007-07-25 00:24:17 +0000946 }
Anders Carlsson8b58e8a2007-10-13 00:45:48 +0000947 virtual const char *getVAListDeclaration() const {
Eli Friedmanff158dd2008-08-20 07:28:14 +0000948 return "typedef struct __va_list_tag {"
949 " unsigned gp_offset;"
950 " unsigned fp_offset;"
951 " void* overflow_arg_area;"
952 " void* reg_save_area;"
953 "} __builtin_va_list[1];";
Anders Carlsson7dd1c952007-11-24 23:38:12 +0000954 }
Eli Friedman872996c2008-08-20 02:34:37 +0000955};
956} // end anonymous namespace
957
958namespace {
Chris Lattner98cb2a22008-10-16 17:04:31 +0000959// x86-64 FreeBSD target
960class FreeBSDX86_64TargetInfo : public X86_64TargetInfo {
961public:
Chris Lattner79682402009-03-20 15:52:06 +0000962 FreeBSDX86_64TargetInfo(const std::string &triple)
963 : X86_64TargetInfo(triple) {}
964 virtual void getTargetDefines(const LangOptions &Opts,
965 std::vector<char> &Defines) const {
966 X86_64TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerab81f162009-03-20 15:55:34 +0000967 getFreeBSDDefines(Opts, 1, getTargetTriple(), Defines);
Chris Lattner98cb2a22008-10-16 17:04:31 +0000968 }
969};
970} // end anonymous namespace
971
972namespace {
Daniel Dunbare5a80f22008-09-23 17:37:57 +0000973// x86-64 Linux target
974class LinuxX86_64TargetInfo : public X86_64TargetInfo {
975public:
976 LinuxX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) {
Chris Lattner5edfe012008-10-05 19:44:25 +0000977 UserLabelPrefix = "";
Daniel Dunbare5a80f22008-09-23 17:37:57 +0000978 }
Chris Lattner79682402009-03-20 15:52:06 +0000979 virtual void getTargetDefines(const LangOptions &Opts,
980 std::vector<char> &Defines) const {
981 X86_64TargetInfo::getTargetDefines(Opts, Defines);
Chris Lattnerab81f162009-03-20 15:55:34 +0000982 getLinuxDefines(Opts, Defines);
Daniel Dunbare5a80f22008-09-23 17:37:57 +0000983 }
984};
985} // end anonymous namespace
986
987namespace {
Douglas Gregor5415abd2009-05-21 23:51:30 +0000988// x86-64 Solaris target
989class SolarisX86_64TargetInfo : public X86_64TargetInfo {
990public:
991 SolarisX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) {
992 UserLabelPrefix = "";
993 WCharType = WCharType = SignedLong;
994 }
995 virtual void getTargetDefines(const LangOptions &Opts,
996 std::vector<char> &Defines) const {
997 X86_64TargetInfo::getTargetDefines(Opts, Defines);
998 getSolarisDefines(Opts, Defines);
999 }
1000};
1001} // end anonymous namespace
1002
1003namespace {
Eli Friedman872996c2008-08-20 02:34:37 +00001004// x86-64 Darwin (OS X) target
1005class DarwinX86_64TargetInfo : public X86_64TargetInfo {
1006public:
Eli Friedman8f575172009-04-19 21:38:35 +00001007 DarwinX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) {
1008 TLSSupported = false;
1009 }
Eli Friedman872996c2008-08-20 02:34:37 +00001010
Anton Korobeynikove7772382009-05-03 13:42:53 +00001011 virtual const char *getStringSymbolPrefix(bool IsConstant) const {
Daniel Dunbarc3a48932009-03-31 23:42:16 +00001012 return IsConstant ? "\01LC" : "\01lC";
1013 }
1014
Anton Korobeynikove7772382009-05-03 13:42:53 +00001015 virtual const char *getUnicodeStringSymbolPrefix() const {
Daniel Dunbar6a916482009-04-03 00:57:44 +00001016 return "__utf16_string_";
1017 }
1018
Anton Korobeynikove7772382009-05-03 13:42:53 +00001019 virtual const char *getUnicodeStringSection() const {
Daniel Dunbar6a916482009-04-03 00:57:44 +00001020 return "__TEXT,__ustring";
1021 }
1022
Anton Korobeynikove7772382009-05-03 13:42:53 +00001023 virtual const char *getCFStringSymbolPrefix() const {
Daniel Dunbarc3a48932009-03-31 23:42:16 +00001024 return "\01L_unnamed_cfstring_";
1025 }
1026
Chris Lattner79682402009-03-20 15:52:06 +00001027 virtual void getTargetDefines(const LangOptions &Opts,
1028 std::vector<char> &Defines) const {
1029 X86_64TargetInfo::getTargetDefines(Opts, Defines);
Daniel Dunbar93f64532009-04-10 19:52:24 +00001030 getDarwinDefines(Defines, Opts);
1031 getDarwinOSXDefines(Defines, getTargetTriple());
Anders Carlsson7dd1c952007-11-24 23:38:12 +00001032 }
Daniel Dunbar34542952008-08-23 08:43:39 +00001033
Chris Lattnerddae7102008-12-04 22:54:33 +00001034 /// getDefaultLangOptions - Allow the target to specify default settings for
1035 /// various language options. These may be overridden by command line
Anton Korobeynikove7772382009-05-03 13:42:53 +00001036 /// options.
Chris Lattnerddae7102008-12-04 22:54:33 +00001037 virtual void getDefaultLangOptions(LangOptions &Opts) {
Chris Lattnerd7bc88b2008-12-04 23:20:07 +00001038 GetDarwinLanguageOptions(Opts, getTargetTriple());
Chris Lattnerddae7102008-12-04 22:54:33 +00001039 }
Chris Lattner4b009652007-07-25 00:24:17 +00001040};
1041} // end anonymous namespace.
1042
Chris Lattner9fd73612008-04-21 18:56:49 +00001043namespace {
Eli Friedmanbe727fe2008-08-20 07:44:10 +00001044class ARMTargetInfo : public TargetInfo {
Mike Stumpf90a29f2009-04-08 02:07:04 +00001045 enum {
1046 Armv4t,
1047 Armv5,
1048 Armv6,
1049 XScale
1050 } ArmArch;
Chris Lattner9fd73612008-04-21 18:56:49 +00001051public:
Eli Friedmanbe727fe2008-08-20 07:44:10 +00001052 ARMTargetInfo(const std::string& triple) : TargetInfo(triple) {
1053 // FIXME: Are the defaults correct for ARM?
Eli Friedman2b161652008-08-21 00:13:15 +00001054 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1055 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:64";
Chris Lattner433d9722009-04-23 04:22:04 +00001056 if (triple.find("arm-") == 0 || triple.find("armv6-") == 0)
Mike Stumpf90a29f2009-04-08 02:07:04 +00001057 ArmArch = Armv6;
Chris Lattner433d9722009-04-23 04:22:04 +00001058 else if (triple.find("armv5-") == 0)
Mike Stumpf90a29f2009-04-08 02:07:04 +00001059 ArmArch = Armv5;
Chris Lattner433d9722009-04-23 04:22:04 +00001060 else if (triple.find("armv4t-") == 0)
Mike Stumpf90a29f2009-04-08 02:07:04 +00001061 ArmArch = Armv4t;
Chris Lattner433d9722009-04-23 04:22:04 +00001062 else if (triple.find("xscale-") == 0)
Mike Stumpf90a29f2009-04-08 02:07:04 +00001063 ArmArch = XScale;
Chris Lattner433d9722009-04-23 04:22:04 +00001064 else if (triple.find("armv") == 0) {
1065 // FIXME: fuzzy match for other random weird arm triples. This is useful
1066 // for the static analyzer and other clients, but probably should be
1067 // re-evaluated when codegen is brought up.
1068 ArmArch = Armv6;
1069 }
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001070 }
Chris Lattner79682402009-03-20 15:52:06 +00001071 virtual void getTargetDefines(const LangOptions &Opts,
1072 std::vector<char> &Defs) const {
Chris Lattnerbef1d722009-03-02 22:27:17 +00001073 // Target identification.
1074 Define(Defs, "__arm");
1075 Define(Defs, "__arm__");
Anton Korobeynikove7772382009-05-03 13:42:53 +00001076
Chris Lattnerbef1d722009-03-02 22:27:17 +00001077 // Target properties.
1078 Define(Defs, "__LITTLE_ENDIAN__");
Anton Korobeynikove7772382009-05-03 13:42:53 +00001079
Mike Stumpf90a29f2009-04-08 02:07:04 +00001080 // Subtarget options.
1081 if (ArmArch == Armv6) {
1082 Define(Defs, "__ARM_ARCH_6K__");
1083 Define(Defs, "__THUMB_INTERWORK__");
1084 } else if (ArmArch == Armv5) {
1085 Define(Defs, "__ARM_ARCH_5TEJ__");
1086 Define(Defs, "__THUMB_INTERWORK__");
1087 Define(Defs, "__SOFTFP__");
1088 } else if (ArmArch == Armv4t) {
1089 Define(Defs, "__ARM_ARCH_4T__");
1090 Define(Defs, "__SOFTFP__");
1091 } else if (ArmArch == XScale) {
1092 Define(Defs, "__ARM_ARCH_5TE__");
1093 Define(Defs, "__XSCALE__");
1094 Define(Defs, "__SOFTFP__");
1095 }
Chris Lattnerbef1d722009-03-02 22:27:17 +00001096 Define(Defs, "__ARMEL__");
Chris Lattner9fd73612008-04-21 18:56:49 +00001097 }
1098 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1099 unsigned &NumRecords) const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +00001100 // FIXME: Implement.
1101 Records = 0;
Chris Lattner9fd73612008-04-21 18:56:49 +00001102 NumRecords = 0;
1103 }
1104 virtual const char *getVAListDeclaration() const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +00001105 return "typedef char* __builtin_va_list;";
Chris Lattner9fd73612008-04-21 18:56:49 +00001106 }
1107 virtual const char *getTargetPrefix() const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +00001108 return "arm";
Chris Lattner9fd73612008-04-21 18:56:49 +00001109 }
Anton Korobeynikove7772382009-05-03 13:42:53 +00001110 virtual void getGCCRegNames(const char * const *&Names,
Chris Lattner9fd73612008-04-21 18:56:49 +00001111 unsigned &NumNames) const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +00001112 // FIXME: Implement.
1113 Names = 0;
Chris Lattner9fd73612008-04-21 18:56:49 +00001114 NumNames = 0;
1115 }
Anton Korobeynikove7772382009-05-03 13:42:53 +00001116 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattner9fd73612008-04-21 18:56:49 +00001117 unsigned &NumAliases) const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +00001118 // FIXME: Implement.
1119 Aliases = 0;
Chris Lattner9fd73612008-04-21 18:56:49 +00001120 NumAliases = 0;
1121 }
Anders Carlsson36834a72009-02-28 17:11:49 +00001122 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattnerc49cc1a2009-04-26 07:16:29 +00001123 TargetInfo::ConstraintInfo &Info) const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +00001124 // FIXME: Check if this is complete
Anders Carlsson36834a72009-02-28 17:11:49 +00001125 switch (*Name) {
Eli Friedmanbe727fe2008-08-20 07:44:10 +00001126 default:
Nate Begeman222823a2008-04-22 05:03:19 +00001127 case 'l': // r0-r7
1128 case 'h': // r8-r15
1129 case 'w': // VFP Floating point register single precision
1130 case 'P': // VFP Floating point register double precision
Chris Lattnerc49cc1a2009-04-26 07:16:29 +00001131 Info.setAllowsRegister();
Nate Begeman222823a2008-04-22 05:03:19 +00001132 return true;
1133 }
Chris Lattner9fd73612008-04-21 18:56:49 +00001134 return false;
1135 }
1136 virtual const char *getClobbers() const {
Eli Friedmanbe727fe2008-08-20 07:44:10 +00001137 // FIXME: Is this really right?
Chris Lattner9fd73612008-04-21 18:56:49 +00001138 return "";
1139 }
1140};
1141} // end anonymous namespace.
1142
Eli Friedmanbe727fe2008-08-20 07:44:10 +00001143
1144namespace {
1145class DarwinARMTargetInfo : public ARMTargetInfo {
1146public:
Eli Friedman8f575172009-04-19 21:38:35 +00001147 DarwinARMTargetInfo(const std::string& triple) : ARMTargetInfo(triple) {
1148 TLSSupported = false;
1149 }
Eli Friedmanbe727fe2008-08-20 07:44:10 +00001150
Chris Lattner79682402009-03-20 15:52:06 +00001151 virtual void getTargetDefines(const LangOptions &Opts,
1152 std::vector<char> &Defines) const {
1153 ARMTargetInfo::getTargetDefines(Opts, Defines);
Daniel Dunbar93f64532009-04-10 19:52:24 +00001154 getDarwinDefines(Defines, Opts);
1155 getDarwinIPhoneOSDefines(Defines, getTargetTriple());
Eli Friedmanbe727fe2008-08-20 07:44:10 +00001156 }
1157};
1158} // end anonymous namespace.
1159
Chris Lattner4b009652007-07-25 00:24:17 +00001160namespace {
Daniel Dunbar88fd9942009-03-23 16:09:04 +00001161// arm FreeBSD target
1162class FreeBSDARMTargetInfo : public ARMTargetInfo {
1163public:
1164 FreeBSDARMTargetInfo(const std::string& triple) : ARMTargetInfo(triple) {}
1165 virtual void getTargetDefines(const LangOptions &Opts,
1166 std::vector<char> &Defines) const {
1167 ARMTargetInfo::getTargetDefines(Opts, Defines);
1168 getFreeBSDDefines(Opts, 0, getTargetTriple(), Defines);
1169 }
1170};
1171} // end anonymous namespace
1172
1173namespace {
Eli Friedmanff158dd2008-08-20 07:28:14 +00001174class SparcV8TargetInfo : public TargetInfo {
Chris Lattnerff7c53d2009-01-27 01:58:38 +00001175 static const TargetInfo::GCCRegAlias GCCRegAliases[];
1176 static const char * const GCCRegNames[];
Gabor Greif8a3ff0d2008-02-21 16:29:08 +00001177public:
Eli Friedmanff158dd2008-08-20 07:28:14 +00001178 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
1179 // FIXME: Support Sparc quad-precision long double?
Eli Friedman2b161652008-08-21 00:13:15 +00001180 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1181 "i64:64:64-f32:32:32-f64:64:64-v64:64:64";
Eli Friedmanff158dd2008-08-20 07:28:14 +00001182 }
Chris Lattner79682402009-03-20 15:52:06 +00001183 virtual void getTargetDefines(const LangOptions &Opts,
1184 std::vector<char> &Defines) const {
Eli Friedmanff158dd2008-08-20 07:28:14 +00001185 // FIXME: This is missing a lot of important defines; some of the
1186 // missing stuff is likely to break system headers.
Gabor Greif8a3ff0d2008-02-21 16:29:08 +00001187 Define(Defines, "__sparc");
Eli Friedman1dee5c52008-05-25 05:26:09 +00001188 Define(Defines, "__sparc__");
Gabor Greif8a3ff0d2008-02-21 16:29:08 +00001189 Define(Defines, "__sparcv8");
1190 }
1191 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1192 unsigned &NumRecords) const {
Eli Friedmanff158dd2008-08-20 07:28:14 +00001193 // FIXME: Implement!
Gabor Greif8a3ff0d2008-02-21 16:29:08 +00001194 }
1195 virtual const char *getVAListDeclaration() const {
Eli Friedmanff158dd2008-08-20 07:28:14 +00001196 return "typedef void* __builtin_va_list;";
Gabor Greif8a3ff0d2008-02-21 16:29:08 +00001197 }
1198 virtual const char *getTargetPrefix() const {
Eli Friedmanff158dd2008-08-20 07:28:14 +00001199 return "sparc";
Gabor Greif8a3ff0d2008-02-21 16:29:08 +00001200 }
Anton Korobeynikove7772382009-05-03 13:42:53 +00001201 virtual void getGCCRegNames(const char * const *&Names,
Chris Lattnerff7c53d2009-01-27 01:58:38 +00001202 unsigned &NumNames) const;
Anton Korobeynikove7772382009-05-03 13:42:53 +00001203 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattnerff7c53d2009-01-27 01:58:38 +00001204 unsigned &NumAliases) const;
Anders Carlsson36834a72009-02-28 17:11:49 +00001205 virtual bool validateAsmConstraint(const char *&Name,
Gabor Greif8a3ff0d2008-02-21 16:29:08 +00001206 TargetInfo::ConstraintInfo &info) const {
Eli Friedmanff158dd2008-08-20 07:28:14 +00001207 // FIXME: Implement!
1208 return false;
Gabor Greif8a3ff0d2008-02-21 16:29:08 +00001209 }
1210 virtual const char *getClobbers() const {
Eli Friedmanff158dd2008-08-20 07:28:14 +00001211 // FIXME: Implement!
1212 return "";
Gabor Greif8a3ff0d2008-02-21 16:29:08 +00001213 }
1214};
1215
Chris Lattnerff7c53d2009-01-27 01:58:38 +00001216const char * const SparcV8TargetInfo::GCCRegNames[] = {
1217 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1218 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
1219 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
1220 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
1221};
1222
Anton Korobeynikove7772382009-05-03 13:42:53 +00001223void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names,
Chris Lattnerff7c53d2009-01-27 01:58:38 +00001224 unsigned &NumNames) const {
1225 Names = GCCRegNames;
1226 NumNames = llvm::array_lengthof(GCCRegNames);
1227}
1228
1229const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = {
Anton Korobeynikove7772382009-05-03 13:42:53 +00001230 { { "g0" }, "r0" },
1231 { { "g1" }, "r1" },
1232 { { "g2" }, "r2" },
1233 { { "g3" }, "r3" },
1234 { { "g4" }, "r4" },
1235 { { "g5" }, "r5" },
1236 { { "g6" }, "r6" },
1237 { { "g7" }, "r7" },
1238 { { "o0" }, "r8" },
1239 { { "o1" }, "r9" },
1240 { { "o2" }, "r10" },
1241 { { "o3" }, "r11" },
1242 { { "o4" }, "r12" },
1243 { { "o5" }, "r13" },
1244 { { "o6", "sp" }, "r14" },
1245 { { "o7" }, "r15" },
1246 { { "l0" }, "r16" },
1247 { { "l1" }, "r17" },
1248 { { "l2" }, "r18" },
1249 { { "l3" }, "r19" },
1250 { { "l4" }, "r20" },
1251 { { "l5" }, "r21" },
1252 { { "l6" }, "r22" },
1253 { { "l7" }, "r23" },
1254 { { "i0" }, "r24" },
1255 { { "i1" }, "r25" },
1256 { { "i2" }, "r26" },
1257 { { "i3" }, "r27" },
1258 { { "i4" }, "r28" },
1259 { { "i5" }, "r29" },
1260 { { "i6", "fp" }, "r30" },
1261 { { "i7" }, "r31" },
Chris Lattnerff7c53d2009-01-27 01:58:38 +00001262};
1263
Anton Korobeynikove7772382009-05-03 13:42:53 +00001264void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattnerff7c53d2009-01-27 01:58:38 +00001265 unsigned &NumAliases) const {
1266 Aliases = GCCRegAliases;
1267 NumAliases = llvm::array_lengthof(GCCRegAliases);
1268}
Gabor Greif8a3ff0d2008-02-21 16:29:08 +00001269} // end anonymous namespace.
1270
Eli Friedmanff158dd2008-08-20 07:28:14 +00001271namespace {
1272class SolarisSparcV8TargetInfo : public SparcV8TargetInfo {
1273public:
1274 SolarisSparcV8TargetInfo(const std::string& triple) :
Eli Friedman7cca0982008-11-02 02:43:55 +00001275 SparcV8TargetInfo(triple) {
1276 SizeType = UnsignedInt;
1277 PtrDiffType = SignedInt;
1278 }
Eli Friedmanff158dd2008-08-20 07:28:14 +00001279
Chris Lattner79682402009-03-20 15:52:06 +00001280 virtual void getTargetDefines(const LangOptions &Opts,
1281 std::vector<char> &Defines) const {
1282 SparcV8TargetInfo::getTargetDefines(Opts, Defines);
Douglas Gregor5415abd2009-05-21 23:51:30 +00001283 getSolarisDefines(Opts, Defines);
Eli Friedmanff158dd2008-08-20 07:28:14 +00001284 }
1285};
1286} // end anonymous namespace.
Chris Lattner4b009652007-07-25 00:24:17 +00001287
Chris Lattner85970f32008-05-08 05:58:21 +00001288namespace {
1289 class PIC16TargetInfo : public TargetInfo{
1290 public:
1291 PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) {
Eli Friedman8f575172009-04-19 21:38:35 +00001292 TLSSupported = false;
Sanjiv Guptafa451432008-10-31 09:52:39 +00001293 IntWidth = 16;
1294 LongWidth = LongLongWidth = 32;
Eli Friedman78a2f412009-05-16 23:30:57 +00001295 IntMaxTWidth = 32;
Sanjiv Guptafa451432008-10-31 09:52:39 +00001296 PointerWidth = 16;
1297 IntAlign = 8;
1298 LongAlign = LongLongAlign = 8;
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001299 PointerAlign = 8;
Sanjiv Guptafa451432008-10-31 09:52:39 +00001300 SizeType = UnsignedInt;
1301 IntMaxType = SignedLong;
1302 UIntMaxType = UnsignedLong;
Chris Lattnerd9ef7242009-02-13 22:28:55 +00001303 IntPtrType = SignedShort;
Eli Friedman7cca0982008-11-02 02:43:55 +00001304 PtrDiffType = SignedInt;
Sanjiv Guptaebd8f0f2008-08-18 10:05:22 +00001305 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8";
Chris Lattner85970f32008-05-08 05:58:21 +00001306 }
Chris Lattner727b3c42008-05-09 06:08:39 +00001307 virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; }
1308 virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; }
Chris Lattner79682402009-03-20 15:52:06 +00001309 virtual void getTargetDefines(const LangOptions &Opts,
1310 std::vector<char> &Defines) const {
Chris Lattner85970f32008-05-08 05:58:21 +00001311 Define(Defines, "__pic16");
1312 }
1313 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1314 unsigned &NumRecords) const {}
1315 virtual const char *getVAListDeclaration() const { return "";}
1316 virtual const char *getClobbers() const {return "";}
Sanjiv Gupta88b4e512009-04-21 06:01:16 +00001317 virtual const char *getTargetPrefix() const {return "pic16";}
Anton Korobeynikove7772382009-05-03 13:42:53 +00001318 virtual void getGCCRegNames(const char * const *&Names,
1319 unsigned &NumNames) const {}
1320 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattner85970f32008-05-08 05:58:21 +00001321 TargetInfo::ConstraintInfo &info) const {
1322 return true;
1323 }
Anton Korobeynikove7772382009-05-03 13:42:53 +00001324 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattner85970f32008-05-08 05:58:21 +00001325 unsigned &NumAliases) const {}
1326 virtual bool useGlobalsForAutomaticVariables() const {return true;}
1327 };
1328}
1329
Anton Korobeynikov954bd3f2009-05-03 13:43:08 +00001330namespace {
1331 class MSP430TargetInfo : public TargetInfo {
1332 static const char * const GCCRegNames[];
1333 public:
1334 MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) {
1335 TLSSupported = false;
1336 IntWidth = 16;
1337 LongWidth = LongLongWidth = 32;
Eli Friedman78a2f412009-05-16 23:30:57 +00001338 IntMaxTWidth = 32;
Anton Korobeynikov954bd3f2009-05-03 13:43:08 +00001339 PointerWidth = 16;
1340 IntAlign = 8;
1341 LongAlign = LongLongAlign = 8;
1342 PointerAlign = 8;
1343 SizeType = UnsignedInt;
1344 IntMaxType = SignedLong;
1345 UIntMaxType = UnsignedLong;
1346 IntPtrType = SignedShort;
1347 PtrDiffType = SignedInt;
1348 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8";
1349 }
1350 virtual void getTargetDefines(const LangOptions &Opts,
1351 std::vector<char> &Defines) const {
1352 Define(Defines, "MSP430");
1353 Define(Defines, "__MSP430__");
1354 // FIXME: defines for different 'flavours' of MCU
1355 }
1356 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1357 unsigned &NumRecords) const {
1358 // FIXME: Implement.
1359 Records = 0;
1360 NumRecords = 0;
1361 }
1362 virtual const char *getTargetPrefix() const {
1363 return "msp430";
1364 }
1365 virtual void getGCCRegNames(const char * const *&Names,
1366 unsigned &NumNames) const;
1367 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1368 unsigned &NumAliases) const {
1369 // No aliases.
1370 Aliases = 0;
1371 NumAliases = 0;
1372 }
1373 virtual bool validateAsmConstraint(const char *&Name,
1374 TargetInfo::ConstraintInfo &info) const {
1375 // FIXME: implement
1376 return true;
1377 }
1378 virtual const char *getClobbers() const {
1379 // FIXME: Is this really right?
1380 return "";
1381 }
1382 virtual const char *getVAListDeclaration() const {
1383 // FIXME: implement
Anton Korobeynikovf5955592009-05-08 18:24:57 +00001384 return "typedef char* __builtin_va_list;";
Anton Korobeynikov954bd3f2009-05-03 13:43:08 +00001385 }
1386 };
1387
1388 const char * const MSP430TargetInfo::GCCRegNames[] = {
1389 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1390 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1391 };
1392
1393 void MSP430TargetInfo::getGCCRegNames(const char * const *&Names,
1394 unsigned &NumNames) const {
1395 Names = GCCRegNames;
1396 NumNames = llvm::array_lengthof(GCCRegNames);
1397 }
1398}
1399
1400
Chris Lattner4b009652007-07-25 00:24:17 +00001401//===----------------------------------------------------------------------===//
1402// Driver code
1403//===----------------------------------------------------------------------===//
1404
Ted Kremenekb97d7672007-12-04 17:07:35 +00001405static inline bool IsX86(const std::string& TT) {
Ted Kremenek40499482007-12-03 22:06:55 +00001406 return (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' &&
1407 TT[4] == '-' && TT[1] - '3' < 6);
1408}
1409
Chris Lattnerfc457002008-03-05 01:18:20 +00001410/// CreateTargetInfo - Return the target info object for the specified target
1411/// triple.
1412TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
Eli Friedman2b161652008-08-21 00:13:15 +00001413 // OS detection; this isn't really anywhere near complete.
1414 // Additions and corrections are welcome.
1415 bool isDarwin = T.find("-darwin") != std::string::npos;
Chris Lattnerd4faca42008-08-23 18:23:14 +00001416 bool isDragonFly = T.find("-dragonfly") != std::string::npos;
Chris Lattner98cb2a22008-10-16 17:04:31 +00001417 bool isFreeBSD = T.find("-freebsd") != std::string::npos;
Eli Friedman2b161652008-08-21 00:13:15 +00001418 bool isSolaris = T.find("-solaris") != std::string::npos;
1419 bool isLinux = T.find("-linux") != std::string::npos;
1420 bool isWindows = T.find("-windows") != std::string::npos ||
1421 T.find("-win32") != std::string::npos ||
1422 T.find("-mingw") != std::string::npos;
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001423
Eli Friedman2b161652008-08-21 00:13:15 +00001424 if (T.find("ppc-") == 0 || T.find("powerpc-") == 0) {
1425 if (isDarwin)
1426 return new DarwinPPCTargetInfo(T);
1427 return new PPC32TargetInfo(T);
1428 }
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001429
Eli Friedman2b161652008-08-21 00:13:15 +00001430 if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0) {
1431 if (isDarwin)
1432 return new DarwinPPC64TargetInfo(T);
1433 return new PPC64TargetInfo(T);
1434 }
Chris Lattner9fd73612008-04-21 18:56:49 +00001435
Chris Lattner433d9722009-04-23 04:22:04 +00001436 if (T.find("armv") == 0 || T.find("arm-") == 0 || T.find("xscale") == 0) {
Eli Friedman2b161652008-08-21 00:13:15 +00001437 if (isDarwin)
1438 return new DarwinARMTargetInfo(T);
Daniel Dunbar88fd9942009-03-23 16:09:04 +00001439 if (isFreeBSD)
1440 return new FreeBSDARMTargetInfo(T);
Eli Friedman2b161652008-08-21 00:13:15 +00001441 return new ARMTargetInfo(T);
1442 }
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001443
Eli Friedman2b161652008-08-21 00:13:15 +00001444 if (T.find("sparc-") == 0) {
1445 if (isSolaris)
1446 return new SolarisSparcV8TargetInfo(T);
1447 return new SparcV8TargetInfo(T);
1448 }
1449
Chris Lattner273dce42009-02-20 17:04:14 +00001450 if (T.find("x86_64-") == 0 || T.find("amd64-") == 0) {
Eli Friedman2b161652008-08-21 00:13:15 +00001451 if (isDarwin)
1452 return new DarwinX86_64TargetInfo(T);
Daniel Dunbare5a80f22008-09-23 17:37:57 +00001453 if (isLinux)
1454 return new LinuxX86_64TargetInfo(T);
Chris Lattner98cb2a22008-10-16 17:04:31 +00001455 if (isFreeBSD)
1456 return new FreeBSDX86_64TargetInfo(T);
Douglas Gregor5415abd2009-05-21 23:51:30 +00001457 if (isSolaris)
1458 return new SolarisX86_64TargetInfo(T);
Eli Friedman2b161652008-08-21 00:13:15 +00001459 return new X86_64TargetInfo(T);
1460 }
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001461
Chris Lattner85970f32008-05-08 05:58:21 +00001462 if (T.find("pic16-") == 0)
1463 return new PIC16TargetInfo(T);
1464
Anton Korobeynikov954bd3f2009-05-03 13:43:08 +00001465 if (T.find("msp430-") == 0)
1466 return new MSP430TargetInfo(T);
1467
Eli Friedman2b161652008-08-21 00:13:15 +00001468 if (IsX86(T)) {
1469 if (isDarwin)
1470 return new DarwinI386TargetInfo(T);
Eli Friedman5fb0a022008-08-21 00:24:02 +00001471 if (isLinux)
1472 return new LinuxX86_32TargetInfo(T);
Chris Lattnerd4faca42008-08-23 18:23:14 +00001473 if (isDragonFly)
1474 return new DragonFlyX86_32TargetInfo(T);
Chris Lattner98cb2a22008-10-16 17:04:31 +00001475 if (isFreeBSD)
1476 return new FreeBSDX86_32TargetInfo(T);
Douglas Gregor5415abd2009-05-21 23:51:30 +00001477 if (isSolaris)
1478 return new SolarisX86_32TargetInfo(T);
Eli Friedman23cb7912008-08-21 01:40:19 +00001479 if (isWindows)
1480 return new WindowsX86_32TargetInfo(T);
Eli Friedman2b161652008-08-21 00:13:15 +00001481 return new X86_32TargetInfo(T);
1482 }
Eli Friedman0b7b1cb2008-05-20 14:21:01 +00001483
Chris Lattnerfc457002008-03-05 01:18:20 +00001484 return NULL;
Chris Lattner4b009652007-07-25 00:24:17 +00001485}