blob: f00eb8f482d1d8353bf529ee95fdb5e776ed7d66 [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//
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +000010// This file implements construction of a TargetInfo object from a
Ted Kremenek6f6ff372007-12-12 18:05:32 +000011// target triple.
Chris Lattner5ba61f02006-10-14 07:39:34 +000012//
13//===----------------------------------------------------------------------===//
14
Chris Lattner5ba61f02006-10-14 07:39:34 +000015#include "clang/Basic/TargetInfo.h"
Daniel Dunbarb9bbd542009-11-15 06:48:46 +000016#include "clang/Basic/Builtins.h"
17#include "clang/Basic/Diagnostic.h"
Chris Lattnerc7c6dd42008-12-04 22:54:33 +000018#include "clang/Basic/LangOptions.h"
Daniel Dunbarb9bbd542009-11-15 06:48:46 +000019#include "clang/Basic/TargetBuiltins.h"
20#include "clang/Basic/TargetOptions.h"
Eli Friedman7cef49e2008-05-20 14:27:34 +000021#include "llvm/ADT/APFloat.h"
Daniel Dunbarb9bbd542009-11-15 06:48:46 +000022#include "llvm/ADT/OwningPtr.h"
Daniel Dunbar979586e2009-11-11 09:38:56 +000023#include "llvm/ADT/STLExtras.h"
Chris Lattner1e1c0b92009-03-20 16:06:38 +000024#include "llvm/ADT/SmallString.h"
Daniel Dunbar58bc48c2009-08-19 20:04:03 +000025#include "llvm/ADT/StringRef.h"
Daniel Dunbar979586e2009-11-11 09:38:56 +000026#include "llvm/ADT/StringSwitch.h"
Chris Lattner859c37a2009-08-12 06:24:27 +000027#include "llvm/ADT/Triple.h"
Chris Lattner30ba6742009-08-10 19:03:04 +000028#include "llvm/MC/MCSectionMachO.h"
Chris Lattner5ba61f02006-10-14 07:39:34 +000029using namespace clang;
30
Chris Lattner5ba61f02006-10-14 07:39:34 +000031//===----------------------------------------------------------------------===//
Chris Lattner1f5ad112006-10-14 18:32:12 +000032// Common code shared among targets.
Chris Lattner5ba61f02006-10-14 07:39:34 +000033//===----------------------------------------------------------------------===//
34
Daniel Dunbar58bc48c2009-08-19 20:04:03 +000035static void Define(std::vector<char> &Buf, const llvm::StringRef &Macro,
36 const llvm::StringRef &Val = "1") {
Chris Lattnerb2d486a2007-10-06 06:57:34 +000037 const char *Def = "#define ";
38 Buf.insert(Buf.end(), Def, Def+strlen(Def));
Daniel Dunbar58bc48c2009-08-19 20:04:03 +000039 Buf.insert(Buf.end(), Macro.begin(), Macro.end());
Chris Lattnerb2d486a2007-10-06 06:57:34 +000040 Buf.push_back(' ');
Daniel Dunbar58bc48c2009-08-19 20:04:03 +000041 Buf.insert(Buf.end(), Val.begin(), Val.end());
Chris Lattnerb2d486a2007-10-06 06:57:34 +000042 Buf.push_back('\n');
43}
44
Chris Lattner1e1c0b92009-03-20 16:06:38 +000045/// DefineStd - Define a macro name and standard variants. For example if
46/// MacroName is "unix", then this will define "__unix", "__unix__", and "unix"
47/// when in GNU mode.
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +000048static void DefineStd(std::vector<char> &Buf, const char *MacroName,
Chris Lattner1e1c0b92009-03-20 16:06:38 +000049 const LangOptions &Opts) {
50 assert(MacroName[0] != '_' && "Identifier should be in the user's namespace");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +000051
Chris Lattner1e1c0b92009-03-20 16:06:38 +000052 // If in GNU mode (e.g. -std=gnu99 but not -std=c99) define the raw identifier
53 // in the user's namespace.
54 if (Opts.GNUMode)
55 Define(Buf, MacroName);
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +000056
Chris Lattner1e1c0b92009-03-20 16:06:38 +000057 // Define __unix.
58 llvm::SmallString<20> TmpStr;
59 TmpStr = "__";
60 TmpStr += MacroName;
Daniel Dunbar58bc48c2009-08-19 20:04:03 +000061 Define(Buf, TmpStr.str());
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +000062
Chris Lattner1e1c0b92009-03-20 16:06:38 +000063 // Define __unix__.
64 TmpStr += "__";
Daniel Dunbar58bc48c2009-08-19 20:04:03 +000065 Define(Buf, TmpStr.str());
Chris Lattner1e1c0b92009-03-20 16:06:38 +000066}
67
Chris Lattner09d98f52008-10-05 21:50:58 +000068//===----------------------------------------------------------------------===//
69// Defines specific to certain operating systems.
70//===----------------------------------------------------------------------===//
Chris Lattner30ba6742009-08-10 19:03:04 +000071
Torok Edwinb2b37c62009-06-30 17:10:35 +000072namespace {
Douglas Gregorc05d2a12009-07-01 15:12:53 +000073template<typename TgtInfo>
74class OSTargetInfo : public TgtInfo {
Torok Edwinb2b37c62009-06-30 17:10:35 +000075protected:
Daniel Dunbar40165182009-08-24 09:10:05 +000076 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Torok Edwinb2b37c62009-06-30 17:10:35 +000077 std::vector<char> &Defines) const=0;
78public:
Douglas Gregorc05d2a12009-07-01 15:12:53 +000079 OSTargetInfo(const std::string& triple) : TgtInfo(triple) {}
Torok Edwinb2b37c62009-06-30 17:10:35 +000080 virtual void getTargetDefines(const LangOptions &Opts,
81 std::vector<char> &Defines) const {
Douglas Gregorc05d2a12009-07-01 15:12:53 +000082 TgtInfo::getTargetDefines(Opts, Defines);
Daniel Dunbar40165182009-08-24 09:10:05 +000083 getOSDefines(Opts, TgtInfo::getTriple(), Defines);
Torok Edwin4e054162009-06-30 17:00:25 +000084 }
Torok Edwinb2b37c62009-06-30 17:10:35 +000085
86};
Chris Lattner859c37a2009-08-12 06:24:27 +000087} // end anonymous namespace
Torok Edwin4e054162009-06-30 17:00:25 +000088
Chris Lattner30ba6742009-08-10 19:03:04 +000089
Daniel Dunbar497ff132009-04-10 19:52:24 +000090static void getDarwinDefines(std::vector<char> &Defs, const LangOptions &Opts) {
Chris Lattner2fe5b262009-06-23 00:43:21 +000091 Define(Defs, "__APPLE_CC__", "5621");
Eli Friedman3fd920a2008-08-20 02:34:37 +000092 Define(Defs, "__APPLE__");
93 Define(Defs, "__MACH__");
Chris Lattner81813122009-02-05 07:19:24 +000094 Define(Defs, "OBJC_NEW_PROPERTIES");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +000095
Chris Lattner2a5c0a32009-04-07 16:50:40 +000096 // __weak is always defined, for use in blocks and with objc pointers.
97 Define(Defs, "__weak", "__attribute__((objc_gc(weak)))");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +000098
Chris Lattner2a5c0a32009-04-07 16:50:40 +000099 // Darwin defines __strong even in C mode (just to nothing).
100 if (!Opts.ObjC1 || Opts.getGCMode() == LangOptions::NonGC)
Chris Lattnerc2d14012009-04-07 04:48:21 +0000101 Define(Defs, "__strong", "");
Chris Lattner2a5c0a32009-04-07 16:50:40 +0000102 else
Chris Lattnerc2d14012009-04-07 04:48:21 +0000103 Define(Defs, "__strong", "__attribute__((objc_gc(strong)))");
Eli Friedmanfd4b1552009-06-04 23:00:29 +0000104
105 if (Opts.Static)
106 Define(Defs, "__STATIC__");
107 else
108 Define(Defs, "__DYNAMIC__");
Daniel Dunbara77eaeb2009-09-03 04:54:28 +0000109
110 if (Opts.POSIXThreads)
111 Define(Defs, "_REENTRANT", "1");
Daniel Dunbar497ff132009-04-10 19:52:24 +0000112}
113
Daniel Dunbar40165182009-08-24 09:10:05 +0000114static void getDarwinOSXDefines(std::vector<char> &Defs,
115 const llvm::Triple &Triple) {
116 if (Triple.getOS() != llvm::Triple::Darwin)
Chris Lattner859c37a2009-08-12 06:24:27 +0000117 return;
Mike Stump11289f42009-09-09 15:08:12 +0000118
Chris Lattnerb3793bb2008-09-30 01:00:25 +0000119 // Figure out which "darwin number" the target triple is. "darwin9" -> 10.5.
Daniel Dunbar497ff132009-04-10 19:52:24 +0000120 unsigned Maj, Min, Rev;
Daniel Dunbar40165182009-08-24 09:10:05 +0000121 Triple.getDarwinNumber(Maj, Min, Rev);
Mike Stump11289f42009-09-09 15:08:12 +0000122
Chris Lattner859c37a2009-08-12 06:24:27 +0000123 char MacOSXStr[] = "1000";
124 if (Maj >= 4 && Maj <= 13) { // 10.0-10.9
125 // darwin7 -> 1030, darwin8 -> 1040, darwin9 -> 1050, etc.
126 MacOSXStr[2] = '0' + Maj-4;
Daniel Dunbar497ff132009-04-10 19:52:24 +0000127 }
Chris Lattner859c37a2009-08-12 06:24:27 +0000128
129 // Handle minor version: 10.4.9 -> darwin8.9 -> "1049"
130 // Cap 10.4.11 -> darwin8.11 -> "1049"
131 MacOSXStr[3] = std::min(Min, 9U)+'0';
132 Define(Defs, "__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", MacOSXStr);
Daniel Dunbar497ff132009-04-10 19:52:24 +0000133}
134
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000135static void getDarwinIPhoneOSDefines(std::vector<char> &Defs,
Daniel Dunbar40165182009-08-24 09:10:05 +0000136 const llvm::Triple &Triple) {
137 if (Triple.getOS() != llvm::Triple::Darwin)
Chris Lattner859c37a2009-08-12 06:24:27 +0000138 return;
Mike Stump11289f42009-09-09 15:08:12 +0000139
Daniel Dunbar497ff132009-04-10 19:52:24 +0000140 // Figure out which "darwin number" the target triple is. "darwin9" -> 10.5.
141 unsigned Maj, Min, Rev;
Daniel Dunbar40165182009-08-24 09:10:05 +0000142 Triple.getDarwinNumber(Maj, Min, Rev);
Mike Stump11289f42009-09-09 15:08:12 +0000143
Chris Lattner859c37a2009-08-12 06:24:27 +0000144 // When targetting iPhone OS, interpret the minor version and
145 // revision as the iPhone OS version
146 char iPhoneOSStr[] = "10000";
147 if (Min >= 2 && Min <= 9) { // iPhone OS 2.0-9.0
148 // darwin9.2.0 -> 20000, darwin9.3.0 -> 30000, etc.
149 iPhoneOSStr[0] = '0' + Min;
Chris Lattnerb3793bb2008-09-30 01:00:25 +0000150 }
Chris Lattner859c37a2009-08-12 06:24:27 +0000151
152 // Handle minor version: 2.2 -> darwin9.2.2 -> 20200
153 iPhoneOSStr[2] = std::min(Rev, 9U)+'0';
154 Define(Defs, "__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__",
155 iPhoneOSStr);
Eli Friedman3fd920a2008-08-20 02:34:37 +0000156}
Chris Lattner5ba61f02006-10-14 07:39:34 +0000157
Chris Lattner2ca529c2008-12-04 23:20:07 +0000158/// GetDarwinLanguageOptions - Set the default language options for darwin.
159static void GetDarwinLanguageOptions(LangOptions &Opts,
Daniel Dunbar40165182009-08-24 09:10:05 +0000160 const llvm::Triple &Triple) {
Chris Lattner2ca529c2008-12-04 23:20:07 +0000161 Opts.NeXTRuntime = true;
Mike Stump11289f42009-09-09 15:08:12 +0000162
Daniel Dunbar40165182009-08-24 09:10:05 +0000163 if (Triple.getOS() != llvm::Triple::Darwin)
Chris Lattner2ca529c2008-12-04 23:20:07 +0000164 return;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000165
Daniel Dunbar40165182009-08-24 09:10:05 +0000166 unsigned MajorVersion = Triple.getDarwinMajorNumber();
Chris Lattner859c37a2009-08-12 06:24:27 +0000167
Bill Wendlingd63bbad2009-06-28 07:36:13 +0000168 // Blocks and stack protectors default to on for 10.6 (darwin10) and beyond.
Chris Lattner859c37a2009-08-12 06:24:27 +0000169 if (MajorVersion > 9) {
Chris Lattner2ca529c2008-12-04 23:20:07 +0000170 Opts.Blocks = 1;
Bill Wendling18351072009-06-28 23:01:01 +0000171 Opts.setStackProtectorMode(LangOptions::SSPOn);
Bill Wendlingd63bbad2009-06-28 07:36:13 +0000172 }
Fariborz Jahanian240f2b72009-02-24 23:34:44 +0000173
Bill Wendlingd63bbad2009-06-28 07:36:13 +0000174 // Non-fragile ABI (in 64-bit mode) default to on for 10.5 (darwin9) and
175 // beyond.
Chris Lattner859c37a2009-08-12 06:24:27 +0000176 if (MajorVersion >= 9 && Opts.ObjC1 &&
Daniel Dunbar40165182009-08-24 09:10:05 +0000177 Triple.getArch() == llvm::Triple::x86_64)
Fariborz Jahanian30b3ac52009-02-24 23:38:42 +0000178 Opts.ObjCNonFragileABI = 1;
Chris Lattner2ca529c2008-12-04 23:20:07 +0000179}
180
Chris Lattner30ba6742009-08-10 19:03:04 +0000181namespace {
Torok Edwinb2b37c62009-06-30 17:10:35 +0000182template<typename Target>
183class DarwinTargetInfo : public OSTargetInfo<Target> {
184protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000185 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Torok Edwinb2b37c62009-06-30 17:10:35 +0000186 std::vector<char> &Defines) const {
187 getDarwinDefines(Defines, Opts);
188 getDarwinOSXDefines(Defines, Triple);
189 }
Mike Stump11289f42009-09-09 15:08:12 +0000190
Torok Edwinb2b37c62009-06-30 17:10:35 +0000191 /// getDefaultLangOptions - Allow the target to specify default settings for
192 /// various language options. These may be overridden by command line
193 /// options.
194 virtual void getDefaultLangOptions(LangOptions &Opts) {
195 TargetInfo::getDefaultLangOptions(Opts);
Daniel Dunbar40165182009-08-24 09:10:05 +0000196 GetDarwinLanguageOptions(Opts, TargetInfo::getTriple());
Torok Edwinb2b37c62009-06-30 17:10:35 +0000197 }
198public:
199 DarwinTargetInfo(const std::string& triple) :
200 OSTargetInfo<Target>(triple) {
201 this->TLSSupported = false;
202 }
203
Torok Edwinb2b37c62009-06-30 17:10:35 +0000204 virtual const char *getUnicodeStringSection() const {
205 return "__TEXT,__ustring";
206 }
Mike Stump11289f42009-09-09 15:08:12 +0000207
Chris Lattner30ba6742009-08-10 19:03:04 +0000208 virtual std::string isValidSectionSpecifier(const llvm::StringRef &SR) const {
209 // Let MCSectionMachO validate this.
210 llvm::StringRef Segment, Section;
211 unsigned TAA, StubSize;
212 return llvm::MCSectionMachO::ParseSectionSpecifier(SR, Segment, Section,
213 TAA, StubSize);
214 }
Torok Edwinb2b37c62009-06-30 17:10:35 +0000215};
216
Chris Lattner30ba6742009-08-10 19:03:04 +0000217
Torok Edwinb2b37c62009-06-30 17:10:35 +0000218// DragonFlyBSD Target
219template<typename Target>
220class DragonFlyBSDTargetInfo : public OSTargetInfo<Target> {
221protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000222 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Torok Edwinb2b37c62009-06-30 17:10:35 +0000223 std::vector<char> &Defs) const {
224 // DragonFly defines; list based off of gcc output
225 Define(Defs, "__DragonFly__");
226 Define(Defs, "__DragonFly_cc_version", "100001");
227 Define(Defs, "__ELF__");
228 Define(Defs, "__KPRINTF_ATTRIBUTE__");
229 Define(Defs, "__tune_i386__");
230 DefineStd(Defs, "unix", Opts);
231 }
232public:
Mike Stump11289f42009-09-09 15:08:12 +0000233 DragonFlyBSDTargetInfo(const std::string &triple)
Torok Edwinb2b37c62009-06-30 17:10:35 +0000234 : OSTargetInfo<Target>(triple) {}
235};
236
237// FreeBSD Target
238template<typename Target>
239class FreeBSDTargetInfo : public OSTargetInfo<Target> {
240protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000241 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Torok Edwinb2b37c62009-06-30 17:10:35 +0000242 std::vector<char> &Defs) const {
243 // FreeBSD defines; list based off of gcc output
244
Daniel Dunbar40165182009-08-24 09:10:05 +0000245 // FIXME: Move version number handling to llvm::Triple.
246 const char *FreeBSD = strstr(Triple.getTriple().c_str(),
247 "-freebsd");
Torok Edwinb2b37c62009-06-30 17:10:35 +0000248 FreeBSD += strlen("-freebsd");
249 char release[] = "X";
250 release[0] = FreeBSD[0];
251 char version[] = "X00001";
252 version[0] = FreeBSD[0];
253
254 Define(Defs, "__FreeBSD__", release);
255 Define(Defs, "__FreeBSD_cc_version", version);
256 Define(Defs, "__KPRINTF_ATTRIBUTE__");
257 DefineStd(Defs, "unix", Opts);
258 Define(Defs, "__ELF__", "1");
259 }
260public:
Mike Stump11289f42009-09-09 15:08:12 +0000261 FreeBSDTargetInfo(const std::string &triple)
Duncan Sands9cb27e92009-07-08 13:55:08 +0000262 : OSTargetInfo<Target>(triple) {
263 this->UserLabelPrefix = "";
264 }
Torok Edwinb2b37c62009-06-30 17:10:35 +0000265};
266
267// Linux target
268template<typename Target>
269class LinuxTargetInfo : public OSTargetInfo<Target> {
270protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000271 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Torok Edwinb2b37c62009-06-30 17:10:35 +0000272 std::vector<char> &Defs) const {
273 // Linux defines; list based off of gcc output
274 DefineStd(Defs, "unix", Opts);
275 DefineStd(Defs, "linux", Opts);
276 Define(Defs, "__gnu_linux__");
277 Define(Defs, "__ELF__", "1");
Daniel Dunbara77eaeb2009-09-03 04:54:28 +0000278 if (Opts.POSIXThreads)
279 Define(Defs, "_REENTRANT", "1");
Torok Edwinb2b37c62009-06-30 17:10:35 +0000280 }
281public:
Mike Stump11289f42009-09-09 15:08:12 +0000282 LinuxTargetInfo(const std::string& triple)
Torok Edwinb2b37c62009-06-30 17:10:35 +0000283 : OSTargetInfo<Target>(triple) {
284 this->UserLabelPrefix = "";
285 }
286};
287
Chris Lattnerd1d820ed2009-07-13 20:29:08 +0000288// NetBSD Target
289template<typename Target>
290class NetBSDTargetInfo : public OSTargetInfo<Target> {
291protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000292 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Chris Lattnerd1d820ed2009-07-13 20:29:08 +0000293 std::vector<char> &Defs) const {
294 // NetBSD defines; list based off of gcc output
295 Define(Defs, "__NetBSD__", "1");
296 Define(Defs, "__unix__", "1");
297 Define(Defs, "__ELF__", "1");
Daniel Dunbara77eaeb2009-09-03 04:54:28 +0000298 if (Opts.POSIXThreads)
299 Define(Defs, "_POSIX_THREADS", "1");
Chris Lattnerd1d820ed2009-07-13 20:29:08 +0000300 }
301public:
Mike Stump11289f42009-09-09 15:08:12 +0000302 NetBSDTargetInfo(const std::string &triple)
Chris Lattnerd1d820ed2009-07-13 20:29:08 +0000303 : OSTargetInfo<Target>(triple) {
304 this->UserLabelPrefix = "";
305 }
306};
307
Torok Edwinb2b37c62009-06-30 17:10:35 +0000308// OpenBSD Target
309template<typename Target>
310class OpenBSDTargetInfo : public OSTargetInfo<Target> {
311protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000312 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Torok Edwinb2b37c62009-06-30 17:10:35 +0000313 std::vector<char> &Defs) const {
314 // OpenBSD defines; list based off of gcc output
315
316 Define(Defs, "__OpenBSD__", "1");
317 DefineStd(Defs, "unix", Opts);
318 Define(Defs, "__ELF__", "1");
Daniel Dunbara77eaeb2009-09-03 04:54:28 +0000319 if (Opts.POSIXThreads)
320 Define(Defs, "_POSIX_THREADS", "1");
Torok Edwinb2b37c62009-06-30 17:10:35 +0000321 }
322public:
Mike Stump11289f42009-09-09 15:08:12 +0000323 OpenBSDTargetInfo(const std::string &triple)
Torok Edwinb2b37c62009-06-30 17:10:35 +0000324 : OSTargetInfo<Target>(triple) {}
325};
326
Edward O'Callaghan9dda8e982009-10-18 13:33:59 +0000327// AuroraUX target
328template<typename Target>
329class AuroraUXTargetInfo : public OSTargetInfo<Target> {
330protected:
331 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
332 std::vector<char> &Defs) const {
333 DefineStd(Defs, "sun", Opts);
334 DefineStd(Defs, "unix", Opts);
335 Define(Defs, "__ELF__");
336 Define(Defs, "__svr4__");
337 Define(Defs, "__SVR4");
338 }
339public:
340 AuroraUXTargetInfo(const std::string& triple)
341 : OSTargetInfo<Target>(triple) {
342 this->UserLabelPrefix = "";
343 this->WCharType = this->SignedLong;
344 // FIXME: WIntType should be SignedLong
345 }
346};
347
Torok Edwinb2b37c62009-06-30 17:10:35 +0000348// Solaris target
349template<typename Target>
350class SolarisTargetInfo : public OSTargetInfo<Target> {
351protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000352 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Torok Edwinb2b37c62009-06-30 17:10:35 +0000353 std::vector<char> &Defs) const {
354 DefineStd(Defs, "sun", Opts);
355 DefineStd(Defs, "unix", Opts);
356 Define(Defs, "__ELF__");
357 Define(Defs, "__svr4__");
358 Define(Defs, "__SVR4");
359 }
360public:
Mike Stump11289f42009-09-09 15:08:12 +0000361 SolarisTargetInfo(const std::string& triple)
Torok Edwinb2b37c62009-06-30 17:10:35 +0000362 : OSTargetInfo<Target>(triple) {
363 this->UserLabelPrefix = "";
364 this->WCharType = this->SignedLong;
365 // FIXME: WIntType should be SignedLong
366 }
367};
Mike Stump11289f42009-09-09 15:08:12 +0000368} // end anonymous namespace.
Torok Edwinb2b37c62009-06-30 17:10:35 +0000369
Chris Lattner09d98f52008-10-05 21:50:58 +0000370//===----------------------------------------------------------------------===//
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000371// Specific target implementations.
372//===----------------------------------------------------------------------===//
Anders Carlssona7408e72007-10-13 00:45:48 +0000373
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000374namespace {
375// PPC abstract base class
376class PPCTargetInfo : public TargetInfo {
377 static const Builtin::Info BuiltinInfo[];
378 static const char * const GCCRegNames[];
379 static const TargetInfo::GCCRegAlias GCCRegAliases[];
380
381public:
Eli Friedman9ffd4a92009-06-05 07:05:05 +0000382 PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {}
383
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000384 virtual void getTargetBuiltins(const Builtin::Info *&Records,
385 unsigned &NumRecords) const {
Chris Lattner10a5b382007-01-29 05:24:35 +0000386 Records = BuiltinInfo;
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000387 NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner10a5b382007-01-29 05:24:35 +0000388 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000389
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000390 virtual void getTargetDefines(const LangOptions &Opts,
391 std::vector<char> &Defines) const;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000392
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000393 virtual const char *getVAListDeclaration() const {
Chris Lattner69f9bc22008-10-27 01:11:29 +0000394 return "typedef char* __builtin_va_list;";
395 // This is the right definition for ABI/V4: System V.4/eabi.
396 /*return "typedef struct __va_list_tag {"
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000397 " unsigned char gpr;"
398 " unsigned char fpr;"
399 " unsigned short reserved;"
400 " void* overflow_arg_area;"
401 " void* reg_save_area;"
Chris Lattner69f9bc22008-10-27 01:11:29 +0000402 "} __builtin_va_list[1];";*/
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000403 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000404 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000405 unsigned &NumNames) const;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000406 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000407 unsigned &NumAliases) const;
Anders Carlsson58436352009-02-28 17:11:49 +0000408 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattnerd9725f72009-04-26 07:16:29 +0000409 TargetInfo::ConstraintInfo &Info) const {
Anders Carlsson58436352009-02-28 17:11:49 +0000410 switch (*Name) {
Anders Carlssonf511f642007-11-27 04:11:28 +0000411 default: return false;
412 case 'O': // Zero
413 return true;
414 case 'b': // Base register
415 case 'f': // Floating point register
Chris Lattnerd9725f72009-04-26 07:16:29 +0000416 Info.setAllowsRegister();
Anders Carlssonf511f642007-11-27 04:11:28 +0000417 return true;
418 }
419 }
Eli Friedman9ffd4a92009-06-05 07:05:05 +0000420 virtual void getDefaultLangOptions(LangOptions &Opts) {
421 TargetInfo::getDefaultLangOptions(Opts);
422 Opts.CharIsSigned = false;
423 }
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000424 virtual const char *getClobbers() const {
425 return "";
Anders Carlssonf511f642007-11-27 04:11:28 +0000426 }
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000427};
Anders Carlssonf511f642007-11-27 04:11:28 +0000428
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000429const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
Douglas Gregor9eebd972009-02-16 21:58:21 +0000430#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
431#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
Chris Lattner5abdec72009-06-14 01:05:48 +0000432#include "clang/Basic/BuiltinsPPC.def"
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000433};
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000434
435
Chris Lattnerecd49032009-03-02 22:27:17 +0000436/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
437/// #defines that are not tied to a specific subtarget.
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000438void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
439 std::vector<char> &Defs) const {
Chris Lattnerecd49032009-03-02 22:27:17 +0000440 // Target identification.
441 Define(Defs, "__ppc__");
442 Define(Defs, "_ARCH_PPC");
443 Define(Defs, "__POWERPC__");
444 if (PointerWidth == 64) {
445 Define(Defs, "_ARCH_PPC64");
446 Define(Defs, "_LP64");
447 Define(Defs, "__LP64__");
448 Define(Defs, "__ppc64__");
449 } else {
450 Define(Defs, "__ppc__");
451 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000452
Chris Lattnerecd49032009-03-02 22:27:17 +0000453 // Target properties.
454 Define(Defs, "_BIG_ENDIAN");
455 Define(Defs, "__BIG_ENDIAN__");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000456
Chris Lattnerecd49032009-03-02 22:27:17 +0000457 // Subtarget options.
458 Define(Defs, "__NATURAL_ALIGNMENT__");
459 Define(Defs, "__REGISTER_PREFIX__", "");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000460
Chris Lattnerecd49032009-03-02 22:27:17 +0000461 // FIXME: Should be controlled by command line option.
462 Define(Defs, "__LONG_DOUBLE_128__");
463}
464
Chris Lattner17df24e2008-04-21 18:56:49 +0000465
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000466const char * const PPCTargetInfo::GCCRegNames[] = {
Chris Lattnerf7ff53d2009-09-16 05:05:27 +0000467 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
468 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
469 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
470 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
471 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
472 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
473 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
474 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000475 "mq", "lr", "ctr", "ap",
Chris Lattnerf7ff53d2009-09-16 05:05:27 +0000476 "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000477 "xer",
Chris Lattnerf7ff53d2009-09-16 05:05:27 +0000478 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
479 "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
480 "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
481 "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000482 "vrsave", "vscr",
483 "spe_acc", "spefscr",
484 "sfp"
485};
Chris Lattner10a5b382007-01-29 05:24:35 +0000486
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000487void PPCTargetInfo::getGCCRegNames(const char * const *&Names,
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000488 unsigned &NumNames) const {
489 Names = GCCRegNames;
490 NumNames = llvm::array_lengthof(GCCRegNames);
491}
Chris Lattner5ba61f02006-10-14 07:39:34 +0000492
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000493const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
494 // While some of these aliases do map to different registers
495 // they still share the same register name.
Daniel Dunbar1da76c42009-09-17 07:03:19 +0000496 { { "0" }, "r0" },
497 { { "1"}, "r1" },
498 { { "2" }, "r2" },
499 { { "3" }, "r3" },
500 { { "4" }, "r4" },
501 { { "5" }, "r5" },
502 { { "6" }, "r6" },
503 { { "7" }, "r7" },
504 { { "8" }, "r8" },
505 { { "9" }, "r9" },
506 { { "10" }, "r10" },
507 { { "11" }, "r11" },
508 { { "12" }, "r12" },
509 { { "13" }, "r13" },
510 { { "14" }, "r14" },
511 { { "15" }, "r15" },
512 { { "16" }, "r16" },
513 { { "17" }, "r17" },
514 { { "18" }, "r18" },
515 { { "19" }, "r19" },
516 { { "20" }, "r20" },
517 { { "21" }, "r21" },
518 { { "22" }, "r22" },
519 { { "23" }, "r23" },
520 { { "24" }, "r24" },
521 { { "25" }, "r25" },
522 { { "26" }, "r26" },
523 { { "27" }, "r27" },
524 { { "28" }, "r28" },
525 { { "29" }, "r29" },
526 { { "30" }, "r30" },
527 { { "31" }, "r31" },
528 { { "fr0" }, "f0" },
529 { { "fr1" }, "f1" },
530 { { "fr2" }, "f2" },
531 { { "fr3" }, "f3" },
532 { { "fr4" }, "f4" },
533 { { "fr5" }, "f5" },
534 { { "fr6" }, "f6" },
535 { { "fr7" }, "f7" },
536 { { "fr8" }, "f8" },
537 { { "fr9" }, "f9" },
Mike Stumpfaacf012009-09-17 21:15:00 +0000538 { { "fr10" }, "f10" },
Daniel Dunbar1da76c42009-09-17 07:03:19 +0000539 { { "fr11" }, "f11" },
540 { { "fr12" }, "f12" },
541 { { "fr13" }, "f13" },
542 { { "fr14" }, "f14" },
543 { { "fr15" }, "f15" },
544 { { "fr16" }, "f16" },
545 { { "fr17" }, "f17" },
546 { { "fr18" }, "f18" },
547 { { "fr19" }, "f19" },
548 { { "fr20" }, "f20" },
549 { { "fr21" }, "f21" },
550 { { "fr22" }, "f22" },
551 { { "fr23" }, "f23" },
552 { { "fr24" }, "f24" },
553 { { "fr25" }, "f25" },
554 { { "fr26" }, "f26" },
555 { { "fr27" }, "f27" },
556 { { "fr28" }, "f28" },
557 { { "fr29" }, "f29" },
558 { { "fr30" }, "f30" },
559 { { "fr31" }, "f31" },
560 { { "cc" }, "cr0" },
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000561};
562
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000563void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000564 unsigned &NumAliases) const {
565 Aliases = GCCRegAliases;
566 NumAliases = llvm::array_lengthof(GCCRegAliases);
567}
568} // end anonymous namespace.
Chris Lattner02dffbd2006-10-14 07:50:21 +0000569
Chris Lattner5ba61f02006-10-14 07:39:34 +0000570namespace {
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000571class PPC32TargetInfo : public PPCTargetInfo {
Chris Lattner5ba61f02006-10-14 07:39:34 +0000572public:
Eli Friedman873f65a2008-08-21 00:13:15 +0000573 PPC32TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
574 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
Chris Lattner5c67237f2009-11-07 18:59:41 +0000575 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";
Eli Friedman873f65a2008-08-21 00:13:15 +0000576 }
Chris Lattner5ba61f02006-10-14 07:39:34 +0000577};
578} // end anonymous namespace.
579
580namespace {
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000581class PPC64TargetInfo : public PPCTargetInfo {
Chris Lattner5ba61f02006-10-14 07:39:34 +0000582public:
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000583 PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
Chris Lattnerba7a6c12008-05-09 06:17:04 +0000584 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedman2857ccb2009-07-01 03:36:11 +0000585 IntMaxType = SignedLong;
586 UIntMaxType = UnsignedLong;
587 Int64Type = SignedLong;
Eli Friedman873f65a2008-08-21 00:13:15 +0000588 DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
Chris Lattner5c67237f2009-11-07 18:59:41 +0000589 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64";
Chris Lattnerba7a6c12008-05-09 06:17:04 +0000590 }
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000591};
592} // end anonymous namespace.
593
Chris Lattner5ba61f02006-10-14 07:39:34 +0000594namespace {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000595// Namespace for x86 abstract base class
596const Builtin::Info BuiltinInfo[] = {
Douglas Gregor9eebd972009-02-16 21:58:21 +0000597#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
598#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
Chris Lattner5abdec72009-06-14 01:05:48 +0000599#include "clang/Basic/BuiltinsX86.def"
Eli Friedman3fd920a2008-08-20 02:34:37 +0000600};
Eli Friedmanb5366062008-05-20 14:21:01 +0000601
Eli Friedman3fd920a2008-08-20 02:34:37 +0000602const char *GCCRegNames[] = {
603 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
604 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
605 "argp", "flags", "fspr", "dirflag", "frame",
606 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
607 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
608 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
609 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
610};
611
612const TargetInfo::GCCRegAlias GCCRegAliases[] = {
613 { { "al", "ah", "eax", "rax" }, "ax" },
614 { { "bl", "bh", "ebx", "rbx" }, "bx" },
615 { { "cl", "ch", "ecx", "rcx" }, "cx" },
616 { { "dl", "dh", "edx", "rdx" }, "dx" },
617 { { "esi", "rsi" }, "si" },
618 { { "edi", "rdi" }, "di" },
619 { { "esp", "rsp" }, "sp" },
620 { { "ebp", "rbp" }, "bp" },
621};
622
623// X86 target abstract base class; x86-32 and x86-64 are very close, so
624// most of the implementation can be shared.
625class X86TargetInfo : public TargetInfo {
Chris Lattner96e43572009-03-02 22:40:39 +0000626 enum X86SSEEnum {
627 NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42
628 } SSELevel;
Eli Friedman3fd920a2008-08-20 02:34:37 +0000629public:
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000630 X86TargetInfo(const std::string& triple)
Daniel Dunbar4dbaaa62009-05-06 03:16:41 +0000631 : TargetInfo(triple), SSELevel(NoMMXSSE) {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000632 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
Chris Lattner1f5ad112006-10-14 18:32:12 +0000633 }
Chris Lattner10a5b382007-01-29 05:24:35 +0000634 virtual void getTargetBuiltins(const Builtin::Info *&Records,
635 unsigned &NumRecords) const {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000636 Records = BuiltinInfo;
637 NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner10a5b382007-01-29 05:24:35 +0000638 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000639 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedman3fd920a2008-08-20 02:34:37 +0000640 unsigned &NumNames) const {
641 Names = GCCRegNames;
642 NumNames = llvm::array_lengthof(GCCRegNames);
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000643 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000644 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000645 unsigned &NumAliases) const {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000646 Aliases = GCCRegAliases;
647 NumAliases = llvm::array_lengthof(GCCRegAliases);
Anders Carlssona7408e72007-10-13 00:45:48 +0000648 }
Anders Carlsson58436352009-02-28 17:11:49 +0000649 virtual bool validateAsmConstraint(const char *&Name,
Eli Friedman3fd920a2008-08-20 02:34:37 +0000650 TargetInfo::ConstraintInfo &info) const;
651 virtual std::string convertConstraint(const char Constraint) const;
Anders Carlssonf511f642007-11-27 04:11:28 +0000652 virtual const char *getClobbers() const {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000653 return "~{dirflag},~{fpsr},~{flags}";
654 }
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000655 virtual void getTargetDefines(const LangOptions &Opts,
656 std::vector<char> &Defines) const;
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000657 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
658 const std::string &Name,
659 bool Enabled) const;
Mike Stump11289f42009-09-09 15:08:12 +0000660 virtual void getDefaultFeatures(const std::string &CPU,
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000661 llvm::StringMap<bool> &Features) const;
Daniel Dunbar979586e2009-11-11 09:38:56 +0000662 virtual void HandleTargetFeatures(const std::vector<std::string> &Features);
Chris Lattner5ba61f02006-10-14 07:39:34 +0000663};
Chris Lattnerc25d8a72009-03-02 22:20:04 +0000664
Mike Stump11289f42009-09-09 15:08:12 +0000665void X86TargetInfo::getDefaultFeatures(const std::string &CPU,
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000666 llvm::StringMap<bool> &Features) const {
Daniel Dunbar4dbaaa62009-05-06 03:16:41 +0000667 // FIXME: This should not be here.
668 Features["3dnow"] = false;
669 Features["3dnowa"] = false;
670 Features["mmx"] = false;
671 Features["sse"] = false;
672 Features["sse2"] = false;
673 Features["sse3"] = false;
674 Features["ssse3"] = false;
675 Features["sse41"] = false;
676 Features["sse42"] = false;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000677
Daniel Dunbar4dbaaa62009-05-06 03:16:41 +0000678 // LLVM does not currently recognize this.
679 // Features["sse4a"] = false;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000680
Daniel Dunbar4dbaaa62009-05-06 03:16:41 +0000681 // FIXME: This *really* should not be here.
682
683 // X86_64 always has SSE2.
684 if (PointerWidth == 64)
685 Features["sse2"] = Features["sse"] = Features["mmx"] = true;
686
Daniel Dunbarf9d90272009-05-06 21:56:32 +0000687 if (CPU == "generic" || CPU == "i386" || CPU == "i486" || CPU == "i586" ||
688 CPU == "pentium" || CPU == "i686" || CPU == "pentiumpro")
689 ;
690 else if (CPU == "pentium-mmx" || CPU == "pentium2")
691 setFeatureEnabled(Features, "mmx", true);
692 else if (CPU == "pentium3")
693 setFeatureEnabled(Features, "sse", true);
694 else if (CPU == "pentium-m" || CPU == "pentium4" || CPU == "x86-64")
695 setFeatureEnabled(Features, "sse2", true);
696 else if (CPU == "yonah" || CPU == "prescott" || CPU == "nocona")
697 setFeatureEnabled(Features, "sse3", true);
698 else if (CPU == "core2")
699 setFeatureEnabled(Features, "ssse3", true);
700 else if (CPU == "penryn") {
701 setFeatureEnabled(Features, "sse4", true);
702 Features["sse42"] = false;
703 } else if (CPU == "atom")
704 setFeatureEnabled(Features, "sse3", true);
705 else if (CPU == "corei7")
706 setFeatureEnabled(Features, "sse4", true);
707 else if (CPU == "k6" || CPU == "winchip-c6")
708 setFeatureEnabled(Features, "mmx", true);
Mike Stump11289f42009-09-09 15:08:12 +0000709 else if (CPU == "k6-2" || CPU == "k6-3" || CPU == "athlon" ||
Daniel Dunbarf9d90272009-05-06 21:56:32 +0000710 CPU == "athlon-tbird" || CPU == "winchip2" || CPU == "c3") {
711 setFeatureEnabled(Features, "mmx", true);
712 setFeatureEnabled(Features, "3dnow", true);
713 } else if (CPU == "athlon-4" || CPU == "athlon-xp" || CPU == "athlon-mp") {
714 setFeatureEnabled(Features, "sse", true);
715 setFeatureEnabled(Features, "3dnowa", true);
716 } else if (CPU == "k8" || CPU == "opteron" || CPU == "athlon64" ||
717 CPU == "athlon-fx") {
Mike Stump11289f42009-09-09 15:08:12 +0000718 setFeatureEnabled(Features, "sse2", true);
Daniel Dunbarf9d90272009-05-06 21:56:32 +0000719 setFeatureEnabled(Features, "3dnowa", true);
720 } else if (CPU == "c3-2")
721 setFeatureEnabled(Features, "sse", true);
Daniel Dunbar4dbaaa62009-05-06 03:16:41 +0000722}
723
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000724bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
Mike Stump11289f42009-09-09 15:08:12 +0000725 const std::string &Name,
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000726 bool Enabled) const {
727 // FIXME: This *really* should not be here.
728 if (!Features.count(Name) && Name != "sse4")
729 return false;
730
731 if (Enabled) {
732 if (Name == "mmx")
733 Features["mmx"] = true;
734 else if (Name == "sse")
735 Features["mmx"] = Features["sse"] = true;
736 else if (Name == "sse2")
737 Features["mmx"] = Features["sse"] = Features["sse2"] = true;
738 else if (Name == "sse3")
Mike Stump11289f42009-09-09 15:08:12 +0000739 Features["mmx"] = Features["sse"] = Features["sse2"] =
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000740 Features["sse3"] = true;
741 else if (Name == "ssse3")
Mike Stump11289f42009-09-09 15:08:12 +0000742 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000743 Features["ssse3"] = true;
744 else if (Name == "sse4")
Mike Stump11289f42009-09-09 15:08:12 +0000745 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000746 Features["ssse3"] = Features["sse41"] = Features["sse42"] = true;
747 else if (Name == "3dnow")
748 Features["3dnowa"] = true;
749 else if (Name == "3dnowa")
750 Features["3dnow"] = Features["3dnowa"] = true;
751 } else {
752 if (Name == "mmx")
Mike Stump11289f42009-09-09 15:08:12 +0000753 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000754 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
755 else if (Name == "sse")
Mike Stump11289f42009-09-09 15:08:12 +0000756 Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000757 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
758 else if (Name == "sse2")
Mike Stump11289f42009-09-09 15:08:12 +0000759 Features["sse2"] = Features["sse3"] = Features["ssse3"] =
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000760 Features["sse41"] = Features["sse42"] = false;
761 else if (Name == "sse3")
Mike Stump11289f42009-09-09 15:08:12 +0000762 Features["sse3"] = Features["ssse3"] = Features["sse41"] =
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000763 Features["sse42"] = false;
764 else if (Name == "ssse3")
765 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
766 else if (Name == "sse4")
767 Features["sse41"] = Features["sse42"] = false;
768 else if (Name == "3dnow")
769 Features["3dnow"] = Features["3dnowa"] = false;
770 else if (Name == "3dnowa")
771 Features["3dnowa"] = false;
772 }
773
774 return true;
775}
776
Daniel Dunbar4dbaaa62009-05-06 03:16:41 +0000777/// HandleTargetOptions - Perform initialization based on the user
778/// configured set of features.
Daniel Dunbar979586e2009-11-11 09:38:56 +0000779void
780X86TargetInfo::HandleTargetFeatures(const std::vector<std::string> &Features) {
781 // Remember the maximum enabled sselevel.
782 for (unsigned i = 0, e = Features.size(); i !=e; ++i) {
783 // Ignore disabled features.
784 if (Features[i][0] == '-')
785 continue;
786
787 assert(Features[i][0] == '+' && "Invalid target feature!");
788 X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Features[i].substr(1))
789 .Case("sse42", SSE42)
790 .Case("sse41", SSE41)
791 .Case("ssse3", SSSE3)
792 .Case("sse2", SSE2)
793 .Case("sse", SSE1)
794 .Case("mmx", MMX)
795 .Default(NoMMXSSE);
796 SSELevel = std::max(SSELevel, Level);
797 }
Chris Lattnerc25d8a72009-03-02 22:20:04 +0000798}
Chris Lattnerecd49032009-03-02 22:27:17 +0000799
800/// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines
801/// that are not tied to a specific subtarget.
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000802void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
803 std::vector<char> &Defs) const {
Chris Lattnerecd49032009-03-02 22:27:17 +0000804 // Target identification.
805 if (PointerWidth == 64) {
806 Define(Defs, "_LP64");
807 Define(Defs, "__LP64__");
808 Define(Defs, "__amd64__");
809 Define(Defs, "__amd64");
810 Define(Defs, "__x86_64");
811 Define(Defs, "__x86_64__");
Chris Lattnerecd49032009-03-02 22:27:17 +0000812 } else {
Chris Lattner1e1c0b92009-03-20 16:06:38 +0000813 DefineStd(Defs, "i386", Opts);
Chris Lattnerecd49032009-03-02 22:27:17 +0000814 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000815
Chris Lattnerecd49032009-03-02 22:27:17 +0000816 // Target properties.
817 Define(Defs, "__LITTLE_ENDIAN__");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000818
Chris Lattnerecd49032009-03-02 22:27:17 +0000819 // Subtarget options.
820 Define(Defs, "__nocona");
821 Define(Defs, "__nocona__");
822 Define(Defs, "__tune_nocona__");
Chris Lattnerecd49032009-03-02 22:27:17 +0000823 Define(Defs, "__REGISTER_PREFIX__", "");
Chris Lattner96e43572009-03-02 22:40:39 +0000824
Chris Lattner6df41af2009-04-19 17:32:33 +0000825 // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline
826 // functions in glibc header files that use FP Stack inline asm which the
827 // backend can't deal with (PR879).
828 Define(Defs, "__NO_MATH_INLINES");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000829
Chris Lattner96e43572009-03-02 22:40:39 +0000830 // Each case falls through to the previous one here.
831 switch (SSELevel) {
832 case SSE42:
833 Define(Defs, "__SSE4_2__");
834 case SSE41:
835 Define(Defs, "__SSE4_1__");
836 case SSSE3:
837 Define(Defs, "__SSSE3__");
838 case SSE3:
839 Define(Defs, "__SSE3__");
840 case SSE2:
841 Define(Defs, "__SSE2__");
842 Define(Defs, "__SSE2_MATH__"); // -mfp-math=sse always implied.
843 case SSE1:
844 Define(Defs, "__SSE__");
845 Define(Defs, "__SSE_MATH__"); // -mfp-math=sse always implied.
846 case MMX:
847 Define(Defs, "__MMX__");
848 case NoMMXSSE:
849 break;
850 }
Chris Lattnerecd49032009-03-02 22:27:17 +0000851}
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000852
853
Eli Friedman3fd920a2008-08-20 02:34:37 +0000854bool
Anders Carlsson58436352009-02-28 17:11:49 +0000855X86TargetInfo::validateAsmConstraint(const char *&Name,
Chris Lattnerd9725f72009-04-26 07:16:29 +0000856 TargetInfo::ConstraintInfo &Info) const {
Anders Carlsson58436352009-02-28 17:11:49 +0000857 switch (*Name) {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000858 default: return false;
859 case 'a': // eax.
860 case 'b': // ebx.
861 case 'c': // ecx.
862 case 'd': // edx.
863 case 'S': // esi.
864 case 'D': // edi.
865 case 'A': // edx:eax.
866 case 't': // top of floating point stack.
867 case 'u': // second from top of floating point stack.
868 case 'q': // Any register accessible as [r]l: a, b, c, and d.
Anders Carlsson83661ac2008-10-06 00:41:45 +0000869 case 'y': // Any MMX register.
Anders Carlsson5f7ee682008-10-06 19:17:39 +0000870 case 'x': // Any SSE register.
Eli Friedman3fd920a2008-08-20 02:34:37 +0000871 case 'Q': // Any register accessible as [r]h: a, b, c, and d.
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000872 case 'e': // 32-bit signed integer constant for use with zero-extending
Anders Carlssona0b89212009-01-24 18:03:09 +0000873 // x86_64 instructions.
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000874 case 'Z': // 32-bit unsigned integer constant for use with zero-extending
Anders Carlssona0b89212009-01-24 18:03:09 +0000875 // x86_64 instructions.
Eli Friedman3fd920a2008-08-20 02:34:37 +0000876 case 'N': // unsigned 8-bit integer constant for use with in and out
877 // instructions.
Eli Friedmancf432d32009-06-08 20:45:44 +0000878 case 'R': // "legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
Chris Lattnerd9725f72009-04-26 07:16:29 +0000879 Info.setAllowsRegister();
Eli Friedman3fd920a2008-08-20 02:34:37 +0000880 return true;
881 }
882}
883
884std::string
885X86TargetInfo::convertConstraint(const char Constraint) const {
886 switch (Constraint) {
887 case 'a': return std::string("{ax}");
888 case 'b': return std::string("{bx}");
889 case 'c': return std::string("{cx}");
890 case 'd': return std::string("{dx}");
891 case 'S': return std::string("{si}");
892 case 'D': return std::string("{di}");
893 case 't': // top of floating point stack.
894 return std::string("{st}");
895 case 'u': // second from top of floating point stack.
896 return std::string("{st(1)}"); // second from top of floating point stack.
897 default:
898 return std::string(1, Constraint);
899 }
900}
Eli Friedman3fd920a2008-08-20 02:34:37 +0000901} // end anonymous namespace
Chris Lattner5ba61f02006-10-14 07:39:34 +0000902
903namespace {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000904// X86-32 generic target
905class X86_32TargetInfo : public X86TargetInfo {
Chris Lattner5ba61f02006-10-14 07:39:34 +0000906public:
Eli Friedman3fd920a2008-08-20 02:34:37 +0000907 X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
908 DoubleAlign = LongLongAlign = 32;
909 LongDoubleWidth = 96;
910 LongDoubleAlign = 32;
Eli Friedman873f65a2008-08-21 00:13:15 +0000911 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
912 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
Chris Lattner5c67237f2009-11-07 18:59:41 +0000913 "a0:0:64-f80:32:32-n8:16:32";
Eli Friedman32ca82a2009-03-29 20:31:09 +0000914 SizeType = UnsignedInt;
915 PtrDiffType = SignedInt;
916 IntPtrType = SignedInt;
Anton Korobeynikov6953ef22009-04-03 23:38:25 +0000917 RegParmMax = 3;
Eli Friedman3fd920a2008-08-20 02:34:37 +0000918 }
919 virtual const char *getVAListDeclaration() const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +0000920 return "typedef char* __builtin_va_list;";
Eli Friedman3fd920a2008-08-20 02:34:37 +0000921 }
Chris Lattnerd545ad12009-09-23 06:06:36 +0000922
923 int getEHDataRegisterNumber(unsigned RegNo) const {
924 if (RegNo == 0) return 0;
925 if (RegNo == 1) return 2;
926 return -1;
927 }
Eli Friedman3fd920a2008-08-20 02:34:37 +0000928};
929} // end anonymous namespace
930
931namespace {
Eli Friedmane3aa4542009-07-05 18:47:56 +0000932class OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> {
933public:
934 OpenBSDI386TargetInfo(const std::string& triple) :
935 OpenBSDTargetInfo<X86_32TargetInfo>(triple) {
936 SizeType = UnsignedLong;
937 IntPtrType = SignedLong;
Eli Friedman245f2292009-07-05 22:31:18 +0000938 PtrDiffType = SignedLong;
Eli Friedmane3aa4542009-07-05 18:47:56 +0000939 }
940};
941} // end anonymous namespace
942
943namespace {
Torok Edwinb2b37c62009-06-30 17:10:35 +0000944class DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000945public:
Torok Edwinb2b37c62009-06-30 17:10:35 +0000946 DarwinI386TargetInfo(const std::string& triple) :
947 DarwinTargetInfo<X86_32TargetInfo>(triple) {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000948 LongDoubleWidth = 128;
949 LongDoubleAlign = 128;
Eli Friedman32ca82a2009-03-29 20:31:09 +0000950 SizeType = UnsignedLong;
951 IntPtrType = SignedLong;
Eli Friedman873f65a2008-08-21 00:13:15 +0000952 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
953 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
Chris Lattner5c67237f2009-11-07 18:59:41 +0000954 "a0:0:64-f80:128:128-n8:16:32";
Torok Edwin4e054162009-06-30 17:00:25 +0000955 }
956
Eli Friedman3fd920a2008-08-20 02:34:37 +0000957};
Daniel Dunbar10de9e62009-06-29 20:52:51 +0000958} // end anonymous namespace
959
960namespace {
Eli Friedmanc968a6a2008-08-21 01:40:19 +0000961// x86-32 Windows target
962class WindowsX86_32TargetInfo : public X86_32TargetInfo {
963public:
964 WindowsX86_32TargetInfo(const std::string& triple)
965 : X86_32TargetInfo(triple) {
Eli Friedmand88c8a12009-04-19 21:38:35 +0000966 TLSSupported = false;
Chris Lattner46be2e12009-06-24 17:12:15 +0000967 WCharType = UnsignedShort;
Eli Friedmanebb9e4d2009-06-08 21:16:17 +0000968 DoubleAlign = LongLongAlign = 64;
969 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
970 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
Chris Lattner5c67237f2009-11-07 18:59:41 +0000971 "a0:0:64-f80:32:32-n8:16:32";
Eli Friedmanc968a6a2008-08-21 01:40:19 +0000972 }
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000973 virtual void getTargetDefines(const LangOptions &Opts,
974 std::vector<char> &Defines) const {
975 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Eli Friedmanc968a6a2008-08-21 01:40:19 +0000976 // This list is based off of the the list of things MingW defines
Eli Friedmanc968a6a2008-08-21 01:40:19 +0000977 Define(Defines, "_WIN32");
Chris Lattner1e1c0b92009-03-20 16:06:38 +0000978 DefineStd(Defines, "WIN32", Opts);
979 DefineStd(Defines, "WINNT", Opts);
Eli Friedmanc968a6a2008-08-21 01:40:19 +0000980 Define(Defines, "_X86_");
Eli Friedmanc968a6a2008-08-21 01:40:19 +0000981 }
Daniel Dunbar3e7a7232009-09-23 07:31:35 +0000982};
983} // end anonymous namespace
Eli Friedmanaa27a872009-06-08 06:11:14 +0000984
Daniel Dunbar3e7a7232009-09-23 07:31:35 +0000985namespace {
986
987/// GetWindowsVisualStudioLanguageOptions - Set the default language options for Windows.
988static void GetWindowsVisualStudioLanguageOptions(LangOptions &Opts) {
989 Opts.Microsoft = true;
990}
991
992// x86-32 Windows Visual Studio target
993class VisualStudioWindowsX86_32TargetInfo : public WindowsX86_32TargetInfo {
994public:
995 VisualStudioWindowsX86_32TargetInfo(const std::string& triple)
996 : WindowsX86_32TargetInfo(triple) {
997 }
998 virtual void getTargetDefines(const LangOptions &Opts,
999 std::vector<char> &Defines) const {
1000 WindowsX86_32TargetInfo::getTargetDefines(Opts, Defines);
1001 // The value of the following reflects processor type.
1002 // 300=386, 400=486, 500=Pentium, 600=Blend (default)
1003 // We lost the original triple, so we use the default.
1004 Define(Defines, "_M_IX86", "600");
1005 }
Eli Friedmanaa27a872009-06-08 06:11:14 +00001006 virtual void getDefaultLangOptions(LangOptions &Opts) {
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001007 WindowsX86_32TargetInfo::getDefaultLangOptions(Opts);
1008 GetWindowsVisualStudioLanguageOptions(Opts);
1009 }
1010};
1011} // end anonymous namespace
1012
1013namespace {
1014// x86-32 MinGW target
1015class MinGWX86_32TargetInfo : public WindowsX86_32TargetInfo {
1016public:
1017 MinGWX86_32TargetInfo(const std::string& triple)
1018 : WindowsX86_32TargetInfo(triple) {
1019 }
1020 virtual void getTargetDefines(const LangOptions &Opts,
1021 std::vector<char> &Defines) const {
1022 WindowsX86_32TargetInfo::getTargetDefines(Opts, Defines);
1023 Define(Defines, "__MSVCRT__");
1024 Define(Defines, "__MINGW32__");
Cedric Venetbc8d0de2009-09-27 10:09:11 +00001025 Define(Defines, "__declspec", "__declspec");
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001026 }
1027};
1028} // end anonymous namespace
1029
1030namespace {
1031// x86-32 Cygwin target
1032class CygwinX86_32TargetInfo : public X86_32TargetInfo {
1033public:
1034 CygwinX86_32TargetInfo(const std::string& triple)
1035 : X86_32TargetInfo(triple) {
1036 TLSSupported = false;
1037 WCharType = UnsignedShort;
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001038 DoubleAlign = LongLongAlign = 64;
1039 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1040 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
Chris Lattner5c67237f2009-11-07 18:59:41 +00001041 "a0:0:64-f80:32:32-n8:16:32";
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001042 }
1043 virtual void getTargetDefines(const LangOptions &Opts,
1044 std::vector<char> &Defines) const {
1045 X86_32TargetInfo::getTargetDefines(Opts, Defines);
1046 Define(Defines, "__CYGWIN__");
1047 Define(Defines, "__CYGWIN32__");
1048 DefineStd(Defines, "unix", Opts);
Eli Friedmanaa27a872009-06-08 06:11:14 +00001049 }
Eli Friedmanc968a6a2008-08-21 01:40:19 +00001050};
1051} // end anonymous namespace
1052
1053namespace {
Eli Friedman3fd920a2008-08-20 02:34:37 +00001054// x86-64 generic target
1055class X86_64TargetInfo : public X86TargetInfo {
1056public:
Chris Lattner4ba73aa02009-03-20 15:52:06 +00001057 X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) {
Chris Lattnerba7a6c12008-05-09 06:17:04 +00001058 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedmanb5366062008-05-20 14:21:01 +00001059 LongDoubleWidth = 128;
1060 LongDoubleAlign = 128;
Chris Lattnerd0a79b22009-02-05 07:32:46 +00001061 IntMaxType = SignedLong;
1062 UIntMaxType = UnsignedLong;
Eli Friedman2857ccb2009-07-01 03:36:11 +00001063 Int64Type = SignedLong;
Anton Korobeynikov6953ef22009-04-03 23:38:25 +00001064 RegParmMax = 6;
Chris Lattnerd0a79b22009-02-05 07:32:46 +00001065
Eli Friedman873f65a2008-08-21 00:13:15 +00001066 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1067 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
Chris Lattner5c67237f2009-11-07 18:59:41 +00001068 "a0:0:64-s0:64:64-f80:128:128-n8:16:32:64";
Chris Lattner10a5b382007-01-29 05:24:35 +00001069 }
Anders Carlssona7408e72007-10-13 00:45:48 +00001070 virtual const char *getVAListDeclaration() const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001071 return "typedef struct __va_list_tag {"
1072 " unsigned gp_offset;"
1073 " unsigned fp_offset;"
1074 " void* overflow_arg_area;"
1075 " void* reg_save_area;"
Eli Friedmanfb36b022009-07-03 00:45:06 +00001076 "} __va_list_tag;"
1077 "typedef __va_list_tag __builtin_va_list[1];";
Anders Carlsson5fa3f342007-11-24 23:38:12 +00001078 }
Chris Lattnerd545ad12009-09-23 06:06:36 +00001079
1080 int getEHDataRegisterNumber(unsigned RegNo) const {
1081 if (RegNo == 0) return 0;
1082 if (RegNo == 1) return 1;
1083 return -1;
1084 }
Eli Friedman3fd920a2008-08-20 02:34:37 +00001085};
1086} // end anonymous namespace
1087
1088namespace {
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001089// x86-64 Windows target
1090class WindowsX86_64TargetInfo : public X86_64TargetInfo {
1091public:
1092 WindowsX86_64TargetInfo(const std::string& triple)
1093 : X86_64TargetInfo(triple) {
1094 TLSSupported = false;
1095 WCharType = UnsignedShort;
Mike Stumpaf9afe92009-10-08 23:00:00 +00001096 LongWidth = LongAlign = 32;
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001097 DoubleAlign = LongLongAlign = 64;
1098 }
1099 virtual void getTargetDefines(const LangOptions &Opts,
1100 std::vector<char> &Defines) const {
1101 X86_64TargetInfo::getTargetDefines(Opts, Defines);
1102 Define(Defines, "_WIN64");
1103 DefineStd(Defines, "WIN64", Opts);
1104 }
1105};
1106} // end anonymous namespace
1107
1108namespace {
1109// x86-64 Windows Visual Studio target
1110class VisualStudioWindowsX86_64TargetInfo : public WindowsX86_64TargetInfo {
1111public:
1112 VisualStudioWindowsX86_64TargetInfo(const std::string& triple)
1113 : WindowsX86_64TargetInfo(triple) {
1114 }
1115 virtual void getTargetDefines(const LangOptions &Opts,
1116 std::vector<char> &Defines) const {
1117 WindowsX86_64TargetInfo::getTargetDefines(Opts, Defines);
1118 Define(Defines, "_M_X64");
1119 }
1120 virtual const char *getVAListDeclaration() const {
1121 return "typedef char* va_list;";
1122 }
1123};
1124} // end anonymous namespace
1125
1126namespace {
1127// x86-64 MinGW target
1128class MinGWX86_64TargetInfo : public WindowsX86_64TargetInfo {
1129public:
1130 MinGWX86_64TargetInfo(const std::string& triple)
1131 : WindowsX86_64TargetInfo(triple) {
1132 }
1133 virtual void getTargetDefines(const LangOptions &Opts,
1134 std::vector<char> &Defines) const {
1135 WindowsX86_64TargetInfo::getTargetDefines(Opts, Defines);
1136 Define(Defines, "__MSVCRT__");
1137 Define(Defines, "__MINGW64__");
1138 Define(Defines, "__declspec");
1139 }
1140};
1141} // end anonymous namespace
1142
1143namespace {
Eli Friedman2857ccb2009-07-01 03:36:11 +00001144class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> {
1145public:
Mike Stump11289f42009-09-09 15:08:12 +00001146 DarwinX86_64TargetInfo(const std::string& triple)
Eli Friedman2857ccb2009-07-01 03:36:11 +00001147 : DarwinTargetInfo<X86_64TargetInfo>(triple) {
1148 Int64Type = SignedLongLong;
1149 }
1150};
1151} // end anonymous namespace
1152
1153namespace {
Eli Friedman245f2292009-07-05 22:31:18 +00001154class OpenBSDX86_64TargetInfo : public OpenBSDTargetInfo<X86_64TargetInfo> {
1155public:
Mike Stump11289f42009-09-09 15:08:12 +00001156 OpenBSDX86_64TargetInfo(const std::string& triple)
Eli Friedman245f2292009-07-05 22:31:18 +00001157 : OpenBSDTargetInfo<X86_64TargetInfo>(triple) {
1158 IntMaxType = SignedLongLong;
1159 UIntMaxType = UnsignedLongLong;
1160 Int64Type = SignedLongLong;
1161 }
1162};
1163} // end anonymous namespace
1164
1165namespace {
Eli Friedmanf05b7722008-08-20 07:44:10 +00001166class ARMTargetInfo : public TargetInfo {
Mike Stump9d54bd72009-04-08 02:07:04 +00001167 enum {
1168 Armv4t,
1169 Armv5,
1170 Armv6,
Mike Stumpb0dd95d2009-08-04 19:48:52 +00001171 Armv7a,
Mike Stump9d54bd72009-04-08 02:07:04 +00001172 XScale
1173 } ArmArch;
Daniel Dunbarb4091a92009-09-14 00:35:03 +00001174
Daniel Dunbar1da76c42009-09-17 07:03:19 +00001175 static const TargetInfo::GCCRegAlias GCCRegAliases[];
1176 static const char * const GCCRegNames[];
1177
Daniel Dunbarb4091a92009-09-14 00:35:03 +00001178 std::string ABI;
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001179 bool IsThumb;
Daniel Dunbarb4091a92009-09-14 00:35:03 +00001180
Chris Lattner17df24e2008-04-21 18:56:49 +00001181public:
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001182 ARMTargetInfo(const std::string &TripleStr)
1183 : TargetInfo(TripleStr), ABI("aapcs-linux"), IsThumb(false)
Daniel Dunbarb4091a92009-09-14 00:35:03 +00001184 {
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001185 llvm::Triple Triple(TripleStr);
1186
Daniel Dunbar125f8fb2009-09-14 00:02:24 +00001187 SizeType = UnsignedInt;
1188 PtrDiffType = SignedInt;
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001189
1190 // FIXME: This shouldn't be done this way, we should use features to
1191 // indicate the arch. See lib/Driver/Tools.cpp.
1192 llvm::StringRef Version(""), Arch = Triple.getArchName();
1193 if (Arch.startswith("arm"))
1194 Version = Arch.substr(3);
1195 else if (Arch.startswith("thumb"))
1196 Version = Arch.substr(5);
1197 if (Version == "v7")
Mike Stumpb0dd95d2009-08-04 19:48:52 +00001198 ArmArch = Armv7a;
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001199 else if (Version.empty() || Version == "v6" || Version == "v6t2")
Mike Stump9d54bd72009-04-08 02:07:04 +00001200 ArmArch = Armv6;
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001201 else if (Version == "v5")
Mike Stump9d54bd72009-04-08 02:07:04 +00001202 ArmArch = Armv5;
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001203 else if (Version == "v4t")
Mike Stump9d54bd72009-04-08 02:07:04 +00001204 ArmArch = Armv4t;
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001205 else if (Arch == "xscale" || Arch == "thumbv5e")
Mike Stump9d54bd72009-04-08 02:07:04 +00001206 ArmArch = XScale;
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001207 else
Chris Lattner0dc10262009-04-23 04:22:04 +00001208 ArmArch = Armv6;
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001209
1210 if (Arch.startswith("thumb"))
1211 IsThumb = true;
Daniel Dunbar03184792009-09-22 21:44:58 +00001212
1213 if (IsThumb) {
1214 DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
1215 "i64:64:64-f32:32:32-f64:64:64-"
Chris Lattner5c67237f2009-11-07 18:59:41 +00001216 "v64:64:64-v128:128:128-a0:0:32-n32");
Daniel Dunbar03184792009-09-22 21:44:58 +00001217 } else {
1218 DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1219 "i64:64:64-f32:32:32-f64:64:64-"
Chris Lattner5c67237f2009-11-07 18:59:41 +00001220 "v64:64:64-v128:128:128-a0:0:64-n32");
Daniel Dunbar03184792009-09-22 21:44:58 +00001221 }
Eli Friedmanb5366062008-05-20 14:21:01 +00001222 }
Daniel Dunbarb4091a92009-09-14 00:35:03 +00001223 virtual const char *getABI() const { return ABI.c_str(); }
Daniel Dunbar125f8fb2009-09-14 00:02:24 +00001224 virtual bool setABI(const std::string &Name) {
Daniel Dunbarb4091a92009-09-14 00:35:03 +00001225 ABI = Name;
1226
Daniel Dunbar125f8fb2009-09-14 00:02:24 +00001227 // The defaults (above) are for AAPCS, check if we need to change them.
1228 //
1229 // FIXME: We need support for -meabi... we could just mangle it into the
1230 // name.
1231 if (Name == "apcs-gnu") {
1232 DoubleAlign = LongLongAlign = 32;
1233 SizeType = UnsignedLong;
1234
Daniel Dunbar03184792009-09-22 21:44:58 +00001235 if (IsThumb) {
1236 DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
1237 "i64:32:32-f32:32:32-f64:32:32-"
Chris Lattner5c67237f2009-11-07 18:59:41 +00001238 "v64:64:64-v128:128:128-a0:0:32-n32");
Daniel Dunbar03184792009-09-22 21:44:58 +00001239 } else {
1240 DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1241 "i64:32:32-f32:32:32-f64:32:32-"
Chris Lattner5c67237f2009-11-07 18:59:41 +00001242 "v64:64:64-v128:128:128-a0:0:64-n32");
Daniel Dunbar03184792009-09-22 21:44:58 +00001243 }
1244
Daniel Dunbar125f8fb2009-09-14 00:02:24 +00001245 // FIXME: Override "preferred align" for double and long long.
1246 } else if (Name == "aapcs") {
1247 // FIXME: Enumerated types are variable width in straight AAPCS.
1248 } else if (Name == "aapcs-linux") {
1249 ;
1250 } else
1251 return false;
1252
1253 return true;
1254 }
Chris Lattner4ba73aa02009-03-20 15:52:06 +00001255 virtual void getTargetDefines(const LangOptions &Opts,
1256 std::vector<char> &Defs) const {
Chris Lattnerecd49032009-03-02 22:27:17 +00001257 // Target identification.
1258 Define(Defs, "__arm");
1259 Define(Defs, "__arm__");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001260
Chris Lattnerecd49032009-03-02 22:27:17 +00001261 // Target properties.
1262 Define(Defs, "__LITTLE_ENDIAN__");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001263
Mike Stump9d54bd72009-04-08 02:07:04 +00001264 // Subtarget options.
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001265 //
1266 // FIXME: Neither THUMB_INTERWORK nor SOFTFP is not being set correctly
1267 // here.
Mike Stumpb0dd95d2009-08-04 19:48:52 +00001268 if (ArmArch == Armv7a) {
1269 Define(Defs, "__ARM_ARCH_7A__");
1270 Define(Defs, "__THUMB_INTERWORK__");
1271 } else if (ArmArch == Armv6) {
Mike Stump9d54bd72009-04-08 02:07:04 +00001272 Define(Defs, "__ARM_ARCH_6K__");
1273 Define(Defs, "__THUMB_INTERWORK__");
1274 } else if (ArmArch == Armv5) {
1275 Define(Defs, "__ARM_ARCH_5TEJ__");
1276 Define(Defs, "__THUMB_INTERWORK__");
1277 Define(Defs, "__SOFTFP__");
1278 } else if (ArmArch == Armv4t) {
1279 Define(Defs, "__ARM_ARCH_4T__");
1280 Define(Defs, "__SOFTFP__");
1281 } else if (ArmArch == XScale) {
1282 Define(Defs, "__ARM_ARCH_5TE__");
1283 Define(Defs, "__XSCALE__");
1284 Define(Defs, "__SOFTFP__");
1285 }
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001286
Chris Lattnerecd49032009-03-02 22:27:17 +00001287 Define(Defs, "__ARMEL__");
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001288
1289 if (IsThumb) {
1290 Define(Defs, "__THUMBEL__");
1291 Define(Defs, "__thumb__");
1292 if (ArmArch == Armv7a)
1293 Define(Defs, "__thumb2__");
1294 }
1295
1296 // Note, this is always on in gcc, even though it doesn't make sense.
Eli Friedman20da71e2009-05-29 19:00:15 +00001297 Define(Defs, "__APCS_32__");
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001298 // FIXME: This should be conditional on VFP instruction support.
Eli Friedman20da71e2009-05-29 19:00:15 +00001299 Define(Defs, "__VFP_FP__");
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001300
1301 Define(Defs, "__USING_SJLJ_EXCEPTIONS__");
Chris Lattner17df24e2008-04-21 18:56:49 +00001302 }
1303 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1304 unsigned &NumRecords) const {
Eli Friedmanf05b7722008-08-20 07:44:10 +00001305 // FIXME: Implement.
1306 Records = 0;
Chris Lattner17df24e2008-04-21 18:56:49 +00001307 NumRecords = 0;
1308 }
1309 virtual const char *getVAListDeclaration() const {
Eli Friedmanf05b7722008-08-20 07:44:10 +00001310 return "typedef char* __builtin_va_list;";
Chris Lattner17df24e2008-04-21 18:56:49 +00001311 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001312 virtual void getGCCRegNames(const char * const *&Names,
Daniel Dunbar1da76c42009-09-17 07:03:19 +00001313 unsigned &NumNames) const;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001314 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Daniel Dunbar1da76c42009-09-17 07:03:19 +00001315 unsigned &NumAliases) const;
Anders Carlsson58436352009-02-28 17:11:49 +00001316 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattnerd9725f72009-04-26 07:16:29 +00001317 TargetInfo::ConstraintInfo &Info) const {
Eli Friedmanf05b7722008-08-20 07:44:10 +00001318 // FIXME: Check if this is complete
Anders Carlsson58436352009-02-28 17:11:49 +00001319 switch (*Name) {
Eli Friedmanf05b7722008-08-20 07:44:10 +00001320 default:
Nate Begeman2908fa02008-04-22 05:03:19 +00001321 case 'l': // r0-r7
1322 case 'h': // r8-r15
1323 case 'w': // VFP Floating point register single precision
1324 case 'P': // VFP Floating point register double precision
Chris Lattnerd9725f72009-04-26 07:16:29 +00001325 Info.setAllowsRegister();
Nate Begeman2908fa02008-04-22 05:03:19 +00001326 return true;
1327 }
Chris Lattner17df24e2008-04-21 18:56:49 +00001328 return false;
1329 }
1330 virtual const char *getClobbers() const {
Eli Friedmanf05b7722008-08-20 07:44:10 +00001331 // FIXME: Is this really right?
Chris Lattner17df24e2008-04-21 18:56:49 +00001332 return "";
1333 }
1334};
Daniel Dunbar1da76c42009-09-17 07:03:19 +00001335
1336const char * const ARMTargetInfo::GCCRegNames[] = {
1337 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1338 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1339};
1340
1341void ARMTargetInfo::getGCCRegNames(const char * const *&Names,
1342 unsigned &NumNames) const {
1343 Names = GCCRegNames;
1344 NumNames = llvm::array_lengthof(GCCRegNames);
1345}
1346
1347const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
1348
1349 { { "a1" }, "r0" },
1350 { { "a2" }, "r1" },
1351 { { "a3" }, "r2" },
1352 { { "a4" }, "r3" },
1353 { { "v1" }, "r4" },
1354 { { "v2" }, "r5" },
1355 { { "v3" }, "r6" },
1356 { { "v4" }, "r7" },
1357 { { "v5" }, "r8" },
1358 { { "v6", "rfp" }, "r9" },
1359 { { "sl" }, "r10" },
1360 { { "fp" }, "r11" },
1361 { { "ip" }, "r12" },
1362 { { "sp" }, "r13" },
1363 { { "lr" }, "r14" },
1364 { { "pc" }, "r15" },
1365};
1366
1367void ARMTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
1368 unsigned &NumAliases) const {
1369 Aliases = GCCRegAliases;
1370 NumAliases = llvm::array_lengthof(GCCRegAliases);
1371}
Chris Lattner17df24e2008-04-21 18:56:49 +00001372} // end anonymous namespace.
1373
Eli Friedmanf05b7722008-08-20 07:44:10 +00001374
1375namespace {
Mike Stump11289f42009-09-09 15:08:12 +00001376class DarwinARMTargetInfo :
Torok Edwinb2b37c62009-06-30 17:10:35 +00001377 public DarwinTargetInfo<ARMTargetInfo> {
1378protected:
Daniel Dunbar40165182009-08-24 09:10:05 +00001379 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Torok Edwinb2b37c62009-06-30 17:10:35 +00001380 std::vector<char> &Defines) const {
1381 getDarwinDefines(Defines, Opts);
1382 getDarwinIPhoneOSDefines(Defines, Triple);
Eli Friedmand88c8a12009-04-19 21:38:35 +00001383 }
Eli Friedmanf05b7722008-08-20 07:44:10 +00001384
Torok Edwinb2b37c62009-06-30 17:10:35 +00001385public:
Mike Stump11289f42009-09-09 15:08:12 +00001386 DarwinARMTargetInfo(const std::string& triple)
Torok Edwinb2b37c62009-06-30 17:10:35 +00001387 : DarwinTargetInfo<ARMTargetInfo>(triple) {}
Eli Friedmanf05b7722008-08-20 07:44:10 +00001388};
1389} // end anonymous namespace.
1390
Chris Lattner5ba61f02006-10-14 07:39:34 +00001391namespace {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001392class SparcV8TargetInfo : public TargetInfo {
Chris Lattner9b415d62009-01-27 01:58:38 +00001393 static const TargetInfo::GCCRegAlias GCCRegAliases[];
1394 static const char * const GCCRegNames[];
Gabor Greif49991682008-02-21 16:29:08 +00001395public:
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001396 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
1397 // FIXME: Support Sparc quad-precision long double?
Eli Friedman873f65a2008-08-21 00:13:15 +00001398 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
Chris Lattner5c67237f2009-11-07 18:59:41 +00001399 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001400 }
Chris Lattner4ba73aa02009-03-20 15:52:06 +00001401 virtual void getTargetDefines(const LangOptions &Opts,
1402 std::vector<char> &Defines) const {
Eli Friedman79426742009-05-22 01:12:57 +00001403 DefineStd(Defines, "sparc", Opts);
Gabor Greif49991682008-02-21 16:29:08 +00001404 Define(Defines, "__sparcv8");
Eli Friedman79426742009-05-22 01:12:57 +00001405 Define(Defines, "__REGISTER_PREFIX__", "");
Gabor Greif49991682008-02-21 16:29:08 +00001406 }
1407 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1408 unsigned &NumRecords) const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001409 // FIXME: Implement!
Gabor Greif49991682008-02-21 16:29:08 +00001410 }
1411 virtual const char *getVAListDeclaration() const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001412 return "typedef void* __builtin_va_list;";
Gabor Greif49991682008-02-21 16:29:08 +00001413 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001414 virtual void getGCCRegNames(const char * const *&Names,
Chris Lattner9b415d62009-01-27 01:58:38 +00001415 unsigned &NumNames) const;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001416 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattner9b415d62009-01-27 01:58:38 +00001417 unsigned &NumAliases) const;
Anders Carlsson58436352009-02-28 17:11:49 +00001418 virtual bool validateAsmConstraint(const char *&Name,
Gabor Greif49991682008-02-21 16:29:08 +00001419 TargetInfo::ConstraintInfo &info) const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001420 // FIXME: Implement!
1421 return false;
Gabor Greif49991682008-02-21 16:29:08 +00001422 }
1423 virtual const char *getClobbers() const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001424 // FIXME: Implement!
1425 return "";
Gabor Greif49991682008-02-21 16:29:08 +00001426 }
1427};
1428
Chris Lattner9b415d62009-01-27 01:58:38 +00001429const char * const SparcV8TargetInfo::GCCRegNames[] = {
1430 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1431 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
1432 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
1433 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
1434};
1435
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001436void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names,
Chris Lattner9b415d62009-01-27 01:58:38 +00001437 unsigned &NumNames) const {
1438 Names = GCCRegNames;
1439 NumNames = llvm::array_lengthof(GCCRegNames);
1440}
1441
1442const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = {
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001443 { { "g0" }, "r0" },
1444 { { "g1" }, "r1" },
1445 { { "g2" }, "r2" },
1446 { { "g3" }, "r3" },
1447 { { "g4" }, "r4" },
1448 { { "g5" }, "r5" },
1449 { { "g6" }, "r6" },
1450 { { "g7" }, "r7" },
1451 { { "o0" }, "r8" },
1452 { { "o1" }, "r9" },
1453 { { "o2" }, "r10" },
1454 { { "o3" }, "r11" },
1455 { { "o4" }, "r12" },
1456 { { "o5" }, "r13" },
1457 { { "o6", "sp" }, "r14" },
1458 { { "o7" }, "r15" },
1459 { { "l0" }, "r16" },
1460 { { "l1" }, "r17" },
1461 { { "l2" }, "r18" },
1462 { { "l3" }, "r19" },
1463 { { "l4" }, "r20" },
1464 { { "l5" }, "r21" },
1465 { { "l6" }, "r22" },
1466 { { "l7" }, "r23" },
1467 { { "i0" }, "r24" },
1468 { { "i1" }, "r25" },
1469 { { "i2" }, "r26" },
1470 { { "i3" }, "r27" },
1471 { { "i4" }, "r28" },
1472 { { "i5" }, "r29" },
1473 { { "i6", "fp" }, "r30" },
1474 { { "i7" }, "r31" },
Chris Lattner9b415d62009-01-27 01:58:38 +00001475};
1476
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001477void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattner9b415d62009-01-27 01:58:38 +00001478 unsigned &NumAliases) const {
1479 Aliases = GCCRegAliases;
1480 NumAliases = llvm::array_lengthof(GCCRegAliases);
1481}
Gabor Greif49991682008-02-21 16:29:08 +00001482} // end anonymous namespace.
1483
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001484namespace {
Edward O'Callaghan9dda8e982009-10-18 13:33:59 +00001485class AuroraUXSparcV8TargetInfo : public AuroraUXTargetInfo<SparcV8TargetInfo> {
1486public:
1487 AuroraUXSparcV8TargetInfo(const std::string& triple) :
1488 AuroraUXTargetInfo<SparcV8TargetInfo>(triple) {
1489 SizeType = UnsignedInt;
1490 PtrDiffType = SignedInt;
1491 }
1492};
Torok Edwinb2b37c62009-06-30 17:10:35 +00001493class SolarisSparcV8TargetInfo : public SolarisTargetInfo<SparcV8TargetInfo> {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001494public:
1495 SolarisSparcV8TargetInfo(const std::string& triple) :
Torok Edwinb2b37c62009-06-30 17:10:35 +00001496 SolarisTargetInfo<SparcV8TargetInfo>(triple) {
Eli Friedmand50881c2008-11-02 02:43:55 +00001497 SizeType = UnsignedInt;
1498 PtrDiffType = SignedInt;
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001499 }
1500};
1501} // end anonymous namespace.
Chris Lattner5ba61f02006-10-14 07:39:34 +00001502
Chris Lattnerb781dc792008-05-08 05:58:21 +00001503namespace {
1504 class PIC16TargetInfo : public TargetInfo{
1505 public:
1506 PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) {
Eli Friedmand88c8a12009-04-19 21:38:35 +00001507 TLSSupported = false;
Sanjiv Guptad7959242008-10-31 09:52:39 +00001508 IntWidth = 16;
1509 LongWidth = LongLongWidth = 32;
1510 PointerWidth = 16;
1511 IntAlign = 8;
1512 LongAlign = LongLongAlign = 8;
Eli Friedmanb5366062008-05-20 14:21:01 +00001513 PointerAlign = 8;
Sanjiv Guptad7959242008-10-31 09:52:39 +00001514 SizeType = UnsignedInt;
1515 IntMaxType = SignedLong;
1516 UIntMaxType = UnsignedLong;
Chris Lattner7e4c81c2009-02-13 22:28:55 +00001517 IntPtrType = SignedShort;
Eli Friedmand50881c2008-11-02 02:43:55 +00001518 PtrDiffType = SignedInt;
Sanjiv Gupta7c720072009-06-02 04:43:46 +00001519 FloatWidth = 32;
1520 FloatAlign = 32;
1521 DoubleWidth = 32;
1522 DoubleAlign = 32;
1523 LongDoubleWidth = 32;
1524 LongDoubleAlign = 32;
1525 FloatFormat = &llvm::APFloat::IEEEsingle;
1526 DoubleFormat = &llvm::APFloat::IEEEsingle;
1527 LongDoubleFormat = &llvm::APFloat::IEEEsingle;
Chris Lattner5c67237f2009-11-07 18:59:41 +00001528 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-f32:32:32-n8";
Sanjiv Gupta7c720072009-06-02 04:43:46 +00001529
Chris Lattnerb781dc792008-05-08 05:58:21 +00001530 }
Chris Lattner5e2ef0c2008-05-09 06:08:39 +00001531 virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; }
1532 virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; }
Chris Lattner4ba73aa02009-03-20 15:52:06 +00001533 virtual void getTargetDefines(const LangOptions &Opts,
1534 std::vector<char> &Defines) const {
Chris Lattnerb781dc792008-05-08 05:58:21 +00001535 Define(Defines, "__pic16");
Sanjiv Gupta30f95ec2009-07-07 04:42:23 +00001536 Define(Defines, "rom", "__attribute__((address_space(1)))");
1537 Define(Defines, "ram", "__attribute__((address_space(0)))");
Mike Stump11289f42009-09-09 15:08:12 +00001538 Define(Defines, "_section(SectName)",
Sanjiv Guptab841d1b2009-08-20 17:48:52 +00001539 "__attribute__((section(SectName)))");
Sanjiv Gupta84f0f772009-10-24 18:08:20 +00001540 Define(Defines, "near",
1541 "__attribute__((section(\"Address=NEAR\")))");
Sanjiv Guptab841d1b2009-08-20 17:48:52 +00001542 Define(Defines, "_address(Addr)",
1543 "__attribute__((section(\"Address=\"#Addr)))");
Sanjiv Gupta30f95ec2009-07-07 04:42:23 +00001544 Define(Defines, "_CONFIG(conf)", "asm(\"CONFIG \"#conf)");
Sanjiv Guptab841d1b2009-08-20 17:48:52 +00001545 Define(Defines, "_interrupt",
1546 "__attribute__((section(\"interrupt=0x4\"))) \
1547 __attribute__((used))");
Chris Lattnerb781dc792008-05-08 05:58:21 +00001548 }
1549 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1550 unsigned &NumRecords) const {}
Mike Stump11289f42009-09-09 15:08:12 +00001551 virtual const char *getVAListDeclaration() const {
Daniel Dunbar576d90d2009-08-24 09:54:37 +00001552 return "";
1553 }
1554 virtual const char *getClobbers() const {
1555 return "";
1556 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001557 virtual void getGCCRegNames(const char * const *&Names,
1558 unsigned &NumNames) const {}
1559 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattnerb781dc792008-05-08 05:58:21 +00001560 TargetInfo::ConstraintInfo &info) const {
1561 return true;
1562 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001563 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattnerb781dc792008-05-08 05:58:21 +00001564 unsigned &NumAliases) const {}
1565 virtual bool useGlobalsForAutomaticVariables() const {return true;}
1566 };
1567}
1568
Anton Korobeynikova0f54372009-05-03 13:43:08 +00001569namespace {
1570 class MSP430TargetInfo : public TargetInfo {
1571 static const char * const GCCRegNames[];
1572 public:
1573 MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) {
1574 TLSSupported = false;
1575 IntWidth = 16;
1576 LongWidth = LongLongWidth = 32;
1577 PointerWidth = 16;
1578 IntAlign = 8;
1579 LongAlign = LongLongAlign = 8;
1580 PointerAlign = 8;
1581 SizeType = UnsignedInt;
1582 IntMaxType = SignedLong;
1583 UIntMaxType = UnsignedLong;
1584 IntPtrType = SignedShort;
1585 PtrDiffType = SignedInt;
Chris Lattner5c67237f2009-11-07 18:59:41 +00001586 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-n8:16";
Anton Korobeynikova0f54372009-05-03 13:43:08 +00001587 }
1588 virtual void getTargetDefines(const LangOptions &Opts,
1589 std::vector<char> &Defines) const {
1590 Define(Defines, "MSP430");
1591 Define(Defines, "__MSP430__");
1592 // FIXME: defines for different 'flavours' of MCU
1593 }
1594 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1595 unsigned &NumRecords) const {
1596 // FIXME: Implement.
1597 Records = 0;
1598 NumRecords = 0;
1599 }
Anton Korobeynikova0f54372009-05-03 13:43:08 +00001600 virtual void getGCCRegNames(const char * const *&Names,
1601 unsigned &NumNames) const;
1602 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1603 unsigned &NumAliases) const {
1604 // No aliases.
1605 Aliases = 0;
1606 NumAliases = 0;
1607 }
1608 virtual bool validateAsmConstraint(const char *&Name,
1609 TargetInfo::ConstraintInfo &info) const {
Anton Korobeynikov051913b2009-10-15 23:17:13 +00001610 // No target constraints for now.
1611 return false;
Anton Korobeynikova0f54372009-05-03 13:43:08 +00001612 }
1613 virtual const char *getClobbers() const {
1614 // FIXME: Is this really right?
1615 return "";
1616 }
1617 virtual const char *getVAListDeclaration() const {
1618 // FIXME: implement
Anton Korobeynikov2f910822009-05-08 18:24:57 +00001619 return "typedef char* __builtin_va_list;";
Anton Korobeynikova0f54372009-05-03 13:43:08 +00001620 }
1621 };
1622
1623 const char * const MSP430TargetInfo::GCCRegNames[] = {
1624 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1625 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1626 };
1627
1628 void MSP430TargetInfo::getGCCRegNames(const char * const *&Names,
1629 unsigned &NumNames) const {
1630 Names = GCCRegNames;
1631 NumNames = llvm::array_lengthof(GCCRegNames);
1632 }
1633}
1634
1635
Anton Korobeynikovb5b703b2009-07-16 20:09:57 +00001636namespace {
1637 class SystemZTargetInfo : public TargetInfo {
1638 static const char * const GCCRegNames[];
1639 public:
1640 SystemZTargetInfo(const std::string& triple) : TargetInfo(triple) {
1641 TLSSupported = false;
1642 IntWidth = IntAlign = 32;
1643 LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64;
1644 PointerWidth = PointerAlign = 64;
Chris Lattner5c67237f2009-11-07 18:59:41 +00001645 DescriptionString = "E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-"
1646 "i64:64:64-f32:32:32-f64:64:64-f128:128:128-a0:16:16-n32:64";
Anton Korobeynikovb5b703b2009-07-16 20:09:57 +00001647 }
1648 virtual void getTargetDefines(const LangOptions &Opts,
1649 std::vector<char> &Defines) const {
1650 Define(Defines, "__s390__");
1651 Define(Defines, "__s390x__");
1652 }
1653 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1654 unsigned &NumRecords) const {
1655 // FIXME: Implement.
1656 Records = 0;
1657 NumRecords = 0;
1658 }
Anton Korobeynikovb5b703b2009-07-16 20:09:57 +00001659
1660 virtual void getDefaultLangOptions(LangOptions &Opts) {
1661 TargetInfo::getDefaultLangOptions(Opts);
1662 Opts.CharIsSigned = false;
1663 }
1664
1665 virtual void getGCCRegNames(const char * const *&Names,
1666 unsigned &NumNames) const;
1667 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1668 unsigned &NumAliases) const {
1669 // No aliases.
1670 Aliases = 0;
1671 NumAliases = 0;
1672 }
1673 virtual bool validateAsmConstraint(const char *&Name,
1674 TargetInfo::ConstraintInfo &info) const {
1675 // FIXME: implement
1676 return true;
1677 }
1678 virtual const char *getClobbers() const {
1679 // FIXME: Is this really right?
1680 return "";
1681 }
1682 virtual const char *getVAListDeclaration() const {
1683 // FIXME: implement
1684 return "typedef char* __builtin_va_list;";
1685 }
1686 };
1687
1688 const char * const SystemZTargetInfo::GCCRegNames[] = {
1689 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1690 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1691 };
1692
1693 void SystemZTargetInfo::getGCCRegNames(const char * const *&Names,
1694 unsigned &NumNames) const {
1695 Names = GCCRegNames;
1696 NumNames = llvm::array_lengthof(GCCRegNames);
1697 }
1698}
1699
Jakob Stoklund Olesen0de52f92009-08-17 20:08:44 +00001700namespace {
1701 class BlackfinTargetInfo : public TargetInfo {
1702 static const char * const GCCRegNames[];
1703 public:
1704 BlackfinTargetInfo(const std::string& triple) : TargetInfo(triple) {
1705 TLSSupported = false;
1706 DoubleAlign = 32;
1707 LongLongAlign = 32;
1708 LongDoubleAlign = 32;
Chris Lattner5c67237f2009-11-07 18:59:41 +00001709 DescriptionString = "e-p:32:32-i64:32-f64:32-n32";
Jakob Stoklund Olesen0de52f92009-08-17 20:08:44 +00001710 }
1711
1712 virtual void getTargetDefines(const LangOptions &Opts,
1713 std::vector<char> &Defines) const {
1714 DefineStd(Defines, "bfin", Opts);
1715 DefineStd(Defines, "BFIN", Opts);
1716 Define(Defines, "__ADSPBLACKFIN__");
1717 // FIXME: This one is really dependent on -mcpu
1718 Define(Defines, "__ADSPLPBLACKFIN__");
1719 // FIXME: Add cpu-dependent defines and __SILICON_REVISION__
1720 }
1721
1722 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1723 unsigned &NumRecords) const {
1724 // FIXME: Implement.
1725 Records = 0;
1726 NumRecords = 0;
1727 }
1728
Jakob Stoklund Olesen0de52f92009-08-17 20:08:44 +00001729 virtual void getGCCRegNames(const char * const *&Names,
1730 unsigned &NumNames) const;
1731
1732 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1733 unsigned &NumAliases) const {
1734 // No aliases.
1735 Aliases = 0;
1736 NumAliases = 0;
1737 }
1738
1739 virtual bool validateAsmConstraint(const char *&Name,
1740 TargetInfo::ConstraintInfo &Info) const {
1741 if (strchr("adzDWeABbvfcCtukxywZY", Name[0])) {
1742 Info.setAllowsRegister();
1743 return true;
1744 }
1745 return false;
1746 }
1747
1748 virtual const char *getClobbers() const {
1749 return "";
1750 }
1751
1752 virtual const char *getVAListDeclaration() const {
1753 return "typedef char* __builtin_va_list;";
1754 }
1755 };
1756
1757 const char * const BlackfinTargetInfo::GCCRegNames[] = {
1758 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1759 "p0", "p1", "p2", "p3", "p4", "p5", "sp", "fp",
1760 "i0", "i1", "i2", "i3", "b0", "b1", "b2", "b3",
1761 "l0", "l1", "l2", "l3", "m0", "m1", "m2", "m3",
1762 "a0", "a1", "cc",
1763 "rets", "reti", "retx", "retn", "rete", "astat", "seqstat", "usp",
1764 "argp", "lt0", "lt1", "lc0", "lc1", "lb0", "lb1"
1765 };
1766
1767 void BlackfinTargetInfo::getGCCRegNames(const char * const *&Names,
1768 unsigned &NumNames) const {
1769 Names = GCCRegNames;
1770 NumNames = llvm::array_lengthof(GCCRegNames);
1771 }
1772}
1773
Eli Friedmana9c3d712009-08-19 20:47:07 +00001774namespace {
1775
Mike Stump11289f42009-09-09 15:08:12 +00001776 // LLVM and Clang cannot be used directly to output native binaries for
1777 // target, but is used to compile C code to llvm bitcode with correct
Eli Friedmana9c3d712009-08-19 20:47:07 +00001778 // type and alignment information.
Mike Stump11289f42009-09-09 15:08:12 +00001779 //
1780 // TCE uses the llvm bitcode as input and uses it for generating customized
1781 // target processor and program binary. TCE co-design environment is
Eli Friedmana9c3d712009-08-19 20:47:07 +00001782 // publicly available in http://tce.cs.tut.fi
1783
1784 class TCETargetInfo : public TargetInfo{
1785 public:
1786 TCETargetInfo(const std::string& triple) : TargetInfo(triple) {
1787 TLSSupported = false;
1788 IntWidth = 32;
1789 LongWidth = LongLongWidth = 32;
Eli Friedmana9c3d712009-08-19 20:47:07 +00001790 PointerWidth = 32;
1791 IntAlign = 32;
1792 LongAlign = LongLongAlign = 32;
1793 PointerAlign = 32;
1794 SizeType = UnsignedInt;
1795 IntMaxType = SignedLong;
1796 UIntMaxType = UnsignedLong;
1797 IntPtrType = SignedInt;
1798 PtrDiffType = SignedInt;
1799 FloatWidth = 32;
1800 FloatAlign = 32;
1801 DoubleWidth = 32;
1802 DoubleAlign = 32;
1803 LongDoubleWidth = 32;
1804 LongDoubleAlign = 32;
1805 FloatFormat = &llvm::APFloat::IEEEsingle;
1806 DoubleFormat = &llvm::APFloat::IEEEsingle;
1807 LongDoubleFormat = &llvm::APFloat::IEEEsingle;
1808 DescriptionString = "E-p:32:32:32-a0:32:32"
1809 "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64"
Chris Lattner5c67237f2009-11-07 18:59:41 +00001810 "-f32:32:32-f64:32:64-n32";
Eli Friedmana9c3d712009-08-19 20:47:07 +00001811 }
1812
1813 virtual void getTargetDefines(const LangOptions &Opts,
1814 std::vector<char> &Defines) const {
1815 DefineStd(Defines, "tce", Opts);
1816 Define(Defines, "__TCE__");
1817 Define(Defines, "__TCE_V1__");
1818 }
1819 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1820 unsigned &NumRecords) const {}
Daniel Dunbar576d90d2009-08-24 09:54:37 +00001821 virtual const char *getClobbers() const {
1822 return "";
1823 }
Eli Friedmana9c3d712009-08-19 20:47:07 +00001824 virtual const char *getVAListDeclaration() const {
1825 return "typedef void* __builtin_va_list;";
1826 }
Eli Friedmana9c3d712009-08-19 20:47:07 +00001827 virtual void getGCCRegNames(const char * const *&Names,
1828 unsigned &NumNames) const {}
1829 virtual bool validateAsmConstraint(const char *&Name,
1830 TargetInfo::ConstraintInfo &info) const {
1831 return true;
1832 }
1833 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1834 unsigned &NumAliases) const {}
1835 };
1836}
1837
Chris Lattner5ba61f02006-10-14 07:39:34 +00001838//===----------------------------------------------------------------------===//
1839// Driver code
1840//===----------------------------------------------------------------------===//
1841
Daniel Dunbarb9bbd542009-11-15 06:48:46 +00001842static TargetInfo *AllocateTarget(const std::string &T) {
Daniel Dunbar52322032009-08-18 05:47:58 +00001843 llvm::Triple Triple(T);
1844 llvm::Triple::OSType os = Triple.getOS();
Eli Friedmanb5366062008-05-20 14:21:01 +00001845
Daniel Dunbar52322032009-08-18 05:47:58 +00001846 switch (Triple.getArch()) {
1847 default:
1848 return NULL;
Eli Friedmanb5366062008-05-20 14:21:01 +00001849
Daniel Dunbar52322032009-08-18 05:47:58 +00001850 case llvm::Triple::arm:
Daniel Dunbar33a004e2009-09-11 01:14:50 +00001851 case llvm::Triple::thumb:
Daniel Dunbar52322032009-08-18 05:47:58 +00001852 switch (os) {
1853 case llvm::Triple::Darwin:
Eli Friedman873f65a2008-08-21 00:13:15 +00001854 return new DarwinARMTargetInfo(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00001855 case llvm::Triple::FreeBSD:
Torok Edwinb2b37c62009-06-30 17:10:35 +00001856 return new FreeBSDTargetInfo<ARMTargetInfo>(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00001857 default:
1858 return new ARMTargetInfo(T);
1859 }
Eli Friedmanb5366062008-05-20 14:21:01 +00001860
Daniel Dunbar52322032009-08-18 05:47:58 +00001861 case llvm::Triple::bfin:
Jakob Stoklund Olesen0de52f92009-08-17 20:08:44 +00001862 return new BlackfinTargetInfo(T);
1863
Daniel Dunbar52322032009-08-18 05:47:58 +00001864 case llvm::Triple::msp430:
1865 return new MSP430TargetInfo(T);
Eli Friedmanb5366062008-05-20 14:21:01 +00001866
Daniel Dunbar52322032009-08-18 05:47:58 +00001867 case llvm::Triple::pic16:
1868 return new PIC16TargetInfo(T);
1869
1870 case llvm::Triple::ppc:
1871 if (os == llvm::Triple::Darwin)
1872 return new DarwinTargetInfo<PPCTargetInfo>(T);
1873 return new PPC32TargetInfo(T);
1874
1875 case llvm::Triple::ppc64:
1876 if (os == llvm::Triple::Darwin)
1877 return new DarwinTargetInfo<PPC64TargetInfo>(T);
1878 return new PPC64TargetInfo(T);
1879
1880 case llvm::Triple::sparc:
Edward O'Callaghan9dda8e982009-10-18 13:33:59 +00001881 if (os == llvm::Triple::AuroraUX)
1882 return new AuroraUXSparcV8TargetInfo(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00001883 if (os == llvm::Triple::Solaris)
1884 return new SolarisSparcV8TargetInfo(T);
1885 return new SparcV8TargetInfo(T);
1886
1887 case llvm::Triple::systemz:
1888 return new SystemZTargetInfo(T);
1889
Eli Friedmana9c3d712009-08-19 20:47:07 +00001890 case llvm::Triple::tce:
1891 return new TCETargetInfo(T);
1892
Daniel Dunbar52322032009-08-18 05:47:58 +00001893 case llvm::Triple::x86:
1894 switch (os) {
Edward O'Callaghan9dda8e982009-10-18 13:33:59 +00001895 case llvm::Triple::AuroraUX:
1896 return new AuroraUXTargetInfo<X86_32TargetInfo>(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00001897 case llvm::Triple::Darwin:
1898 return new DarwinI386TargetInfo(T);
1899 case llvm::Triple::Linux:
1900 return new LinuxTargetInfo<X86_32TargetInfo>(T);
1901 case llvm::Triple::DragonFly:
1902 return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(T);
1903 case llvm::Triple::NetBSD:
1904 return new NetBSDTargetInfo<X86_32TargetInfo>(T);
1905 case llvm::Triple::OpenBSD:
1906 return new OpenBSDI386TargetInfo(T);
1907 case llvm::Triple::FreeBSD:
1908 return new FreeBSDTargetInfo<X86_32TargetInfo>(T);
1909 case llvm::Triple::Solaris:
1910 return new SolarisTargetInfo<X86_32TargetInfo>(T);
1911 case llvm::Triple::Cygwin:
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001912 return new CygwinX86_32TargetInfo(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00001913 case llvm::Triple::MinGW32:
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001914 return new MinGWX86_32TargetInfo(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00001915 case llvm::Triple::Win32:
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001916 return new VisualStudioWindowsX86_32TargetInfo(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00001917 default:
1918 return new X86_32TargetInfo(T);
1919 }
1920
1921 case llvm::Triple::x86_64:
1922 switch (os) {
Edward O'Callaghan9dda8e982009-10-18 13:33:59 +00001923 case llvm::Triple::AuroraUX:
1924 return new AuroraUXTargetInfo<X86_64TargetInfo>(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00001925 case llvm::Triple::Darwin:
1926 return new DarwinX86_64TargetInfo(T);
1927 case llvm::Triple::Linux:
1928 return new LinuxTargetInfo<X86_64TargetInfo>(T);
1929 case llvm::Triple::NetBSD:
1930 return new NetBSDTargetInfo<X86_64TargetInfo>(T);
1931 case llvm::Triple::OpenBSD:
1932 return new OpenBSDX86_64TargetInfo(T);
1933 case llvm::Triple::FreeBSD:
1934 return new FreeBSDTargetInfo<X86_64TargetInfo>(T);
1935 case llvm::Triple::Solaris:
1936 return new SolarisTargetInfo<X86_64TargetInfo>(T);
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001937 case llvm::Triple::MinGW64:
1938 return new MinGWX86_64TargetInfo(T);
1939 case llvm::Triple::Win32: // This is what Triple.h supports now.
1940 return new VisualStudioWindowsX86_64TargetInfo(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00001941 default:
1942 return new X86_64TargetInfo(T);
1943 }
1944 }
Chris Lattner5ba61f02006-10-14 07:39:34 +00001945}
Daniel Dunbarb9bbd542009-11-15 06:48:46 +00001946
1947/// CreateTargetInfo - Return the target info object for the specified target
1948/// triple.
1949TargetInfo *TargetInfo::CreateTargetInfo(Diagnostic &Diags,
1950 const TargetOptions &Opts) {
1951 llvm::Triple Triple(Opts.Triple);
1952
1953 // Construct the target
1954 llvm::OwningPtr<TargetInfo> Target(AllocateTarget(Triple.str()));
1955 if (!Target) {
1956 Diags.Report(diag::err_target_unknown_triple) << Triple.str();
1957 return 0;
1958 }
1959
1960 // Set the target ABI if specified.
1961 if (!Opts.ABI.empty() && !Target->setABI(Opts.ABI)) {
1962 Diags.Report(diag::err_target_unknown_abi) << Opts.ABI;
1963 return 0;
1964 }
1965
1966 // Compute the default target features, we need the target to handle this
1967 // because features may have dependencies on one another.
1968 llvm::StringMap<bool> Features;
1969 Target->getDefaultFeatures(Opts.CPU, Features);
1970
1971 // Apply the user specified deltas.
1972 for (std::vector<std::string>::const_iterator it = Opts.Features.begin(),
1973 ie = Opts.Features.end(); it != ie; ++it) {
1974 const char *Name = it->c_str();
1975
1976 // Apply the feature via the target.
1977 if ((Name[0] != '-' && Name[0] != '+') ||
1978 !Target->setFeatureEnabled(Features, Name + 1, (Name[0] == '+'))) {
1979 Diags.Report(diag::err_target_invalid_feature) << Name;
1980 return 0;
1981 }
1982 }
1983
1984 // Add the features to the compile options.
1985 //
1986 // FIXME: If we are completely confident that we have the right set, we only
1987 // need to pass the minuses.
1988 std::vector<std::string> StrFeatures;
1989 for (llvm::StringMap<bool>::const_iterator it = Features.begin(),
1990 ie = Features.end(); it != ie; ++it)
1991 StrFeatures.push_back(std::string(it->second ? "+" : "-") + it->first());
1992 Target->HandleTargetFeatures(StrFeatures);
1993
1994 return Target.take();
1995}