blob: 91ecf475e6efb236e28ee7216d0bc7d3ace345c4 [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'Callaghane9a58b12009-11-15 10:22:07 +0000327// PSP Target
328template<typename Target>
329class PSPTargetInfo : public OSTargetInfo<Target> {
330protected:
331 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
332 std::vector<char> &Defs) const {
333 // PSP defines; list based on the output of the pspdev gcc toolchain.
334 Define(Defs, "PSP", "1");
335 Define(Defs, "_PSP", "1");
336 Define(Defs, "__psp__", "1");
337 Define(Defs, "__ELF__", "1");
338 }
339public:
340 PSPTargetInfo(const std::string& triple)
341 : OSTargetInfo<Target>(triple) {
342 this->UserLabelPrefix = "";
343 }
344};
345
Edward O'Callaghan9dda8e982009-10-18 13:33:59 +0000346// AuroraUX target
347template<typename Target>
348class AuroraUXTargetInfo : public OSTargetInfo<Target> {
349protected:
350 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
351 std::vector<char> &Defs) const {
352 DefineStd(Defs, "sun", Opts);
353 DefineStd(Defs, "unix", Opts);
354 Define(Defs, "__ELF__");
355 Define(Defs, "__svr4__");
356 Define(Defs, "__SVR4");
357 }
358public:
359 AuroraUXTargetInfo(const std::string& triple)
360 : OSTargetInfo<Target>(triple) {
361 this->UserLabelPrefix = "";
362 this->WCharType = this->SignedLong;
363 // FIXME: WIntType should be SignedLong
364 }
365};
366
Torok Edwinb2b37c62009-06-30 17:10:35 +0000367// Solaris target
368template<typename Target>
369class SolarisTargetInfo : public OSTargetInfo<Target> {
370protected:
Daniel Dunbar40165182009-08-24 09:10:05 +0000371 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Torok Edwinb2b37c62009-06-30 17:10:35 +0000372 std::vector<char> &Defs) const {
373 DefineStd(Defs, "sun", Opts);
374 DefineStd(Defs, "unix", Opts);
375 Define(Defs, "__ELF__");
376 Define(Defs, "__svr4__");
377 Define(Defs, "__SVR4");
378 }
379public:
Mike Stump11289f42009-09-09 15:08:12 +0000380 SolarisTargetInfo(const std::string& triple)
Torok Edwinb2b37c62009-06-30 17:10:35 +0000381 : OSTargetInfo<Target>(triple) {
382 this->UserLabelPrefix = "";
383 this->WCharType = this->SignedLong;
384 // FIXME: WIntType should be SignedLong
385 }
386};
Mike Stump11289f42009-09-09 15:08:12 +0000387} // end anonymous namespace.
Torok Edwinb2b37c62009-06-30 17:10:35 +0000388
Chris Lattner09d98f52008-10-05 21:50:58 +0000389//===----------------------------------------------------------------------===//
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000390// Specific target implementations.
391//===----------------------------------------------------------------------===//
Anders Carlssona7408e72007-10-13 00:45:48 +0000392
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000393namespace {
394// PPC abstract base class
395class PPCTargetInfo : public TargetInfo {
396 static const Builtin::Info BuiltinInfo[];
397 static const char * const GCCRegNames[];
398 static const TargetInfo::GCCRegAlias GCCRegAliases[];
399
400public:
Eli Friedman9ffd4a92009-06-05 07:05:05 +0000401 PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {}
402
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000403 virtual void getTargetBuiltins(const Builtin::Info *&Records,
404 unsigned &NumRecords) const {
Chris Lattner10a5b382007-01-29 05:24:35 +0000405 Records = BuiltinInfo;
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000406 NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner10a5b382007-01-29 05:24:35 +0000407 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000408
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000409 virtual void getTargetDefines(const LangOptions &Opts,
410 std::vector<char> &Defines) const;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000411
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000412 virtual const char *getVAListDeclaration() const {
Chris Lattner69f9bc22008-10-27 01:11:29 +0000413 return "typedef char* __builtin_va_list;";
414 // This is the right definition for ABI/V4: System V.4/eabi.
415 /*return "typedef struct __va_list_tag {"
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000416 " unsigned char gpr;"
417 " unsigned char fpr;"
418 " unsigned short reserved;"
419 " void* overflow_arg_area;"
420 " void* reg_save_area;"
Chris Lattner69f9bc22008-10-27 01:11:29 +0000421 "} __builtin_va_list[1];";*/
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000422 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000423 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000424 unsigned &NumNames) const;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000425 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000426 unsigned &NumAliases) const;
Anders Carlsson58436352009-02-28 17:11:49 +0000427 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattnerd9725f72009-04-26 07:16:29 +0000428 TargetInfo::ConstraintInfo &Info) const {
Anders Carlsson58436352009-02-28 17:11:49 +0000429 switch (*Name) {
Anders Carlssonf511f642007-11-27 04:11:28 +0000430 default: return false;
431 case 'O': // Zero
432 return true;
433 case 'b': // Base register
434 case 'f': // Floating point register
Chris Lattnerd9725f72009-04-26 07:16:29 +0000435 Info.setAllowsRegister();
Anders Carlssonf511f642007-11-27 04:11:28 +0000436 return true;
437 }
438 }
Eli Friedman9ffd4a92009-06-05 07:05:05 +0000439 virtual void getDefaultLangOptions(LangOptions &Opts) {
440 TargetInfo::getDefaultLangOptions(Opts);
441 Opts.CharIsSigned = false;
442 }
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000443 virtual const char *getClobbers() const {
444 return "";
Anders Carlssonf511f642007-11-27 04:11:28 +0000445 }
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000446};
Anders Carlssonf511f642007-11-27 04:11:28 +0000447
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000448const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
Douglas Gregor9eebd972009-02-16 21:58:21 +0000449#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
450#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
Chris Lattner5abdec72009-06-14 01:05:48 +0000451#include "clang/Basic/BuiltinsPPC.def"
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000452};
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000453
454
Chris Lattnerecd49032009-03-02 22:27:17 +0000455/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
456/// #defines that are not tied to a specific subtarget.
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000457void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
458 std::vector<char> &Defs) const {
Chris Lattnerecd49032009-03-02 22:27:17 +0000459 // Target identification.
460 Define(Defs, "__ppc__");
461 Define(Defs, "_ARCH_PPC");
462 Define(Defs, "__POWERPC__");
463 if (PointerWidth == 64) {
464 Define(Defs, "_ARCH_PPC64");
465 Define(Defs, "_LP64");
466 Define(Defs, "__LP64__");
467 Define(Defs, "__ppc64__");
468 } else {
469 Define(Defs, "__ppc__");
470 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000471
Chris Lattnerecd49032009-03-02 22:27:17 +0000472 // Target properties.
473 Define(Defs, "_BIG_ENDIAN");
474 Define(Defs, "__BIG_ENDIAN__");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000475
Chris Lattnerecd49032009-03-02 22:27:17 +0000476 // Subtarget options.
477 Define(Defs, "__NATURAL_ALIGNMENT__");
478 Define(Defs, "__REGISTER_PREFIX__", "");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000479
Chris Lattnerecd49032009-03-02 22:27:17 +0000480 // FIXME: Should be controlled by command line option.
481 Define(Defs, "__LONG_DOUBLE_128__");
482}
483
Chris Lattner17df24e2008-04-21 18:56:49 +0000484
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000485const char * const PPCTargetInfo::GCCRegNames[] = {
Chris Lattnerf7ff53d2009-09-16 05:05:27 +0000486 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
487 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
488 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
489 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
490 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
491 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
492 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
493 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000494 "mq", "lr", "ctr", "ap",
Chris Lattnerf7ff53d2009-09-16 05:05:27 +0000495 "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000496 "xer",
Chris Lattnerf7ff53d2009-09-16 05:05:27 +0000497 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
498 "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
499 "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
500 "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000501 "vrsave", "vscr",
502 "spe_acc", "spefscr",
503 "sfp"
504};
Chris Lattner10a5b382007-01-29 05:24:35 +0000505
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000506void PPCTargetInfo::getGCCRegNames(const char * const *&Names,
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000507 unsigned &NumNames) const {
508 Names = GCCRegNames;
509 NumNames = llvm::array_lengthof(GCCRegNames);
510}
Chris Lattner5ba61f02006-10-14 07:39:34 +0000511
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000512const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
513 // While some of these aliases do map to different registers
514 // they still share the same register name.
Daniel Dunbar1da76c42009-09-17 07:03:19 +0000515 { { "0" }, "r0" },
516 { { "1"}, "r1" },
517 { { "2" }, "r2" },
518 { { "3" }, "r3" },
519 { { "4" }, "r4" },
520 { { "5" }, "r5" },
521 { { "6" }, "r6" },
522 { { "7" }, "r7" },
523 { { "8" }, "r8" },
524 { { "9" }, "r9" },
525 { { "10" }, "r10" },
526 { { "11" }, "r11" },
527 { { "12" }, "r12" },
528 { { "13" }, "r13" },
529 { { "14" }, "r14" },
530 { { "15" }, "r15" },
531 { { "16" }, "r16" },
532 { { "17" }, "r17" },
533 { { "18" }, "r18" },
534 { { "19" }, "r19" },
535 { { "20" }, "r20" },
536 { { "21" }, "r21" },
537 { { "22" }, "r22" },
538 { { "23" }, "r23" },
539 { { "24" }, "r24" },
540 { { "25" }, "r25" },
541 { { "26" }, "r26" },
542 { { "27" }, "r27" },
543 { { "28" }, "r28" },
544 { { "29" }, "r29" },
545 { { "30" }, "r30" },
546 { { "31" }, "r31" },
547 { { "fr0" }, "f0" },
548 { { "fr1" }, "f1" },
549 { { "fr2" }, "f2" },
550 { { "fr3" }, "f3" },
551 { { "fr4" }, "f4" },
552 { { "fr5" }, "f5" },
553 { { "fr6" }, "f6" },
554 { { "fr7" }, "f7" },
555 { { "fr8" }, "f8" },
556 { { "fr9" }, "f9" },
Mike Stumpfaacf012009-09-17 21:15:00 +0000557 { { "fr10" }, "f10" },
Daniel Dunbar1da76c42009-09-17 07:03:19 +0000558 { { "fr11" }, "f11" },
559 { { "fr12" }, "f12" },
560 { { "fr13" }, "f13" },
561 { { "fr14" }, "f14" },
562 { { "fr15" }, "f15" },
563 { { "fr16" }, "f16" },
564 { { "fr17" }, "f17" },
565 { { "fr18" }, "f18" },
566 { { "fr19" }, "f19" },
567 { { "fr20" }, "f20" },
568 { { "fr21" }, "f21" },
569 { { "fr22" }, "f22" },
570 { { "fr23" }, "f23" },
571 { { "fr24" }, "f24" },
572 { { "fr25" }, "f25" },
573 { { "fr26" }, "f26" },
574 { { "fr27" }, "f27" },
575 { { "fr28" }, "f28" },
576 { { "fr29" }, "f29" },
577 { { "fr30" }, "f30" },
578 { { "fr31" }, "f31" },
579 { { "cc" }, "cr0" },
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000580};
581
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000582void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000583 unsigned &NumAliases) const {
584 Aliases = GCCRegAliases;
585 NumAliases = llvm::array_lengthof(GCCRegAliases);
586}
587} // end anonymous namespace.
Chris Lattner02dffbd2006-10-14 07:50:21 +0000588
Chris Lattner5ba61f02006-10-14 07:39:34 +0000589namespace {
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000590class PPC32TargetInfo : public PPCTargetInfo {
Chris Lattner5ba61f02006-10-14 07:39:34 +0000591public:
Eli Friedman873f65a2008-08-21 00:13:15 +0000592 PPC32TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
593 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 +0000594 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";
Eli Friedman873f65a2008-08-21 00:13:15 +0000595 }
Chris Lattner5ba61f02006-10-14 07:39:34 +0000596};
597} // end anonymous namespace.
598
599namespace {
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000600class PPC64TargetInfo : public PPCTargetInfo {
Chris Lattner5ba61f02006-10-14 07:39:34 +0000601public:
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000602 PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
Chris Lattnerba7a6c12008-05-09 06:17:04 +0000603 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedman2857ccb2009-07-01 03:36:11 +0000604 IntMaxType = SignedLong;
605 UIntMaxType = UnsignedLong;
606 Int64Type = SignedLong;
Eli Friedman873f65a2008-08-21 00:13:15 +0000607 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 +0000608 "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64";
Chris Lattnerba7a6c12008-05-09 06:17:04 +0000609 }
Eli Friedmanb9e5bed2008-08-20 23:11:40 +0000610};
611} // end anonymous namespace.
612
Chris Lattner5ba61f02006-10-14 07:39:34 +0000613namespace {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000614// Namespace for x86 abstract base class
615const Builtin::Info BuiltinInfo[] = {
Douglas Gregor9eebd972009-02-16 21:58:21 +0000616#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
617#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER, false },
Chris Lattner5abdec72009-06-14 01:05:48 +0000618#include "clang/Basic/BuiltinsX86.def"
Eli Friedman3fd920a2008-08-20 02:34:37 +0000619};
Eli Friedmanb5366062008-05-20 14:21:01 +0000620
Eli Friedman3fd920a2008-08-20 02:34:37 +0000621const char *GCCRegNames[] = {
622 "ax", "dx", "cx", "bx", "si", "di", "bp", "sp",
623 "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
624 "argp", "flags", "fspr", "dirflag", "frame",
625 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
626 "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
627 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
628 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
629};
630
631const TargetInfo::GCCRegAlias GCCRegAliases[] = {
632 { { "al", "ah", "eax", "rax" }, "ax" },
633 { { "bl", "bh", "ebx", "rbx" }, "bx" },
634 { { "cl", "ch", "ecx", "rcx" }, "cx" },
635 { { "dl", "dh", "edx", "rdx" }, "dx" },
636 { { "esi", "rsi" }, "si" },
637 { { "edi", "rdi" }, "di" },
638 { { "esp", "rsp" }, "sp" },
639 { { "ebp", "rbp" }, "bp" },
640};
641
642// X86 target abstract base class; x86-32 and x86-64 are very close, so
643// most of the implementation can be shared.
644class X86TargetInfo : public TargetInfo {
Chris Lattner96e43572009-03-02 22:40:39 +0000645 enum X86SSEEnum {
646 NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42
647 } SSELevel;
Eli Friedman3fd920a2008-08-20 02:34:37 +0000648public:
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000649 X86TargetInfo(const std::string& triple)
Daniel Dunbar4dbaaa62009-05-06 03:16:41 +0000650 : TargetInfo(triple), SSELevel(NoMMXSSE) {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000651 LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
Chris Lattner1f5ad112006-10-14 18:32:12 +0000652 }
Chris Lattner10a5b382007-01-29 05:24:35 +0000653 virtual void getTargetBuiltins(const Builtin::Info *&Records,
654 unsigned &NumRecords) const {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000655 Records = BuiltinInfo;
656 NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
Chris Lattner10a5b382007-01-29 05:24:35 +0000657 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000658 virtual void getGCCRegNames(const char * const *&Names,
Eli Friedman3fd920a2008-08-20 02:34:37 +0000659 unsigned &NumNames) const {
660 Names = GCCRegNames;
661 NumNames = llvm::array_lengthof(GCCRegNames);
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000662 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000663 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Anders Carlsson5fa3f342007-11-24 23:38:12 +0000664 unsigned &NumAliases) const {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000665 Aliases = GCCRegAliases;
666 NumAliases = llvm::array_lengthof(GCCRegAliases);
Anders Carlssona7408e72007-10-13 00:45:48 +0000667 }
Anders Carlsson58436352009-02-28 17:11:49 +0000668 virtual bool validateAsmConstraint(const char *&Name,
Eli Friedman3fd920a2008-08-20 02:34:37 +0000669 TargetInfo::ConstraintInfo &info) const;
670 virtual std::string convertConstraint(const char Constraint) const;
Anders Carlssonf511f642007-11-27 04:11:28 +0000671 virtual const char *getClobbers() const {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000672 return "~{dirflag},~{fpsr},~{flags}";
673 }
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000674 virtual void getTargetDefines(const LangOptions &Opts,
675 std::vector<char> &Defines) const;
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000676 virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
677 const std::string &Name,
678 bool Enabled) const;
Mike Stump11289f42009-09-09 15:08:12 +0000679 virtual void getDefaultFeatures(const std::string &CPU,
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000680 llvm::StringMap<bool> &Features) const;
Daniel Dunbar979586e2009-11-11 09:38:56 +0000681 virtual void HandleTargetFeatures(const std::vector<std::string> &Features);
Chris Lattner5ba61f02006-10-14 07:39:34 +0000682};
Chris Lattnerc25d8a72009-03-02 22:20:04 +0000683
Mike Stump11289f42009-09-09 15:08:12 +0000684void X86TargetInfo::getDefaultFeatures(const std::string &CPU,
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000685 llvm::StringMap<bool> &Features) const {
Daniel Dunbar4dbaaa62009-05-06 03:16:41 +0000686 // FIXME: This should not be here.
687 Features["3dnow"] = false;
688 Features["3dnowa"] = false;
689 Features["mmx"] = false;
690 Features["sse"] = false;
691 Features["sse2"] = false;
692 Features["sse3"] = false;
693 Features["ssse3"] = false;
694 Features["sse41"] = false;
695 Features["sse42"] = false;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000696
Daniel Dunbar4dbaaa62009-05-06 03:16:41 +0000697 // LLVM does not currently recognize this.
698 // Features["sse4a"] = false;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000699
Daniel Dunbar4dbaaa62009-05-06 03:16:41 +0000700 // FIXME: This *really* should not be here.
701
702 // X86_64 always has SSE2.
703 if (PointerWidth == 64)
704 Features["sse2"] = Features["sse"] = Features["mmx"] = true;
705
Daniel Dunbarf9d90272009-05-06 21:56:32 +0000706 if (CPU == "generic" || CPU == "i386" || CPU == "i486" || CPU == "i586" ||
707 CPU == "pentium" || CPU == "i686" || CPU == "pentiumpro")
708 ;
709 else if (CPU == "pentium-mmx" || CPU == "pentium2")
710 setFeatureEnabled(Features, "mmx", true);
711 else if (CPU == "pentium3")
712 setFeatureEnabled(Features, "sse", true);
713 else if (CPU == "pentium-m" || CPU == "pentium4" || CPU == "x86-64")
714 setFeatureEnabled(Features, "sse2", true);
715 else if (CPU == "yonah" || CPU == "prescott" || CPU == "nocona")
716 setFeatureEnabled(Features, "sse3", true);
717 else if (CPU == "core2")
718 setFeatureEnabled(Features, "ssse3", true);
719 else if (CPU == "penryn") {
720 setFeatureEnabled(Features, "sse4", true);
721 Features["sse42"] = false;
722 } else if (CPU == "atom")
723 setFeatureEnabled(Features, "sse3", true);
724 else if (CPU == "corei7")
725 setFeatureEnabled(Features, "sse4", true);
726 else if (CPU == "k6" || CPU == "winchip-c6")
727 setFeatureEnabled(Features, "mmx", true);
Mike Stump11289f42009-09-09 15:08:12 +0000728 else if (CPU == "k6-2" || CPU == "k6-3" || CPU == "athlon" ||
Daniel Dunbarf9d90272009-05-06 21:56:32 +0000729 CPU == "athlon-tbird" || CPU == "winchip2" || CPU == "c3") {
730 setFeatureEnabled(Features, "mmx", true);
731 setFeatureEnabled(Features, "3dnow", true);
732 } else if (CPU == "athlon-4" || CPU == "athlon-xp" || CPU == "athlon-mp") {
733 setFeatureEnabled(Features, "sse", true);
734 setFeatureEnabled(Features, "3dnowa", true);
735 } else if (CPU == "k8" || CPU == "opteron" || CPU == "athlon64" ||
736 CPU == "athlon-fx") {
Mike Stump11289f42009-09-09 15:08:12 +0000737 setFeatureEnabled(Features, "sse2", true);
Daniel Dunbarf9d90272009-05-06 21:56:32 +0000738 setFeatureEnabled(Features, "3dnowa", true);
739 } else if (CPU == "c3-2")
740 setFeatureEnabled(Features, "sse", true);
Daniel Dunbar4dbaaa62009-05-06 03:16:41 +0000741}
742
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000743bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
Mike Stump11289f42009-09-09 15:08:12 +0000744 const std::string &Name,
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000745 bool Enabled) const {
746 // FIXME: This *really* should not be here.
747 if (!Features.count(Name) && Name != "sse4")
748 return false;
749
750 if (Enabled) {
751 if (Name == "mmx")
752 Features["mmx"] = true;
753 else if (Name == "sse")
754 Features["mmx"] = Features["sse"] = true;
755 else if (Name == "sse2")
756 Features["mmx"] = Features["sse"] = Features["sse2"] = true;
757 else if (Name == "sse3")
Mike Stump11289f42009-09-09 15:08:12 +0000758 Features["mmx"] = Features["sse"] = Features["sse2"] =
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000759 Features["sse3"] = true;
760 else if (Name == "ssse3")
Mike Stump11289f42009-09-09 15:08:12 +0000761 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000762 Features["ssse3"] = true;
763 else if (Name == "sse4")
Mike Stump11289f42009-09-09 15:08:12 +0000764 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000765 Features["ssse3"] = Features["sse41"] = Features["sse42"] = true;
766 else if (Name == "3dnow")
767 Features["3dnowa"] = true;
768 else if (Name == "3dnowa")
769 Features["3dnow"] = Features["3dnowa"] = true;
770 } else {
771 if (Name == "mmx")
Mike Stump11289f42009-09-09 15:08:12 +0000772 Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000773 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
774 else if (Name == "sse")
Mike Stump11289f42009-09-09 15:08:12 +0000775 Features["sse"] = Features["sse2"] = Features["sse3"] =
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000776 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
777 else if (Name == "sse2")
Mike Stump11289f42009-09-09 15:08:12 +0000778 Features["sse2"] = Features["sse3"] = Features["ssse3"] =
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000779 Features["sse41"] = Features["sse42"] = false;
780 else if (Name == "sse3")
Mike Stump11289f42009-09-09 15:08:12 +0000781 Features["sse3"] = Features["ssse3"] = Features["sse41"] =
Daniel Dunbarbb36aed2009-05-06 21:07:50 +0000782 Features["sse42"] = false;
783 else if (Name == "ssse3")
784 Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
785 else if (Name == "sse4")
786 Features["sse41"] = Features["sse42"] = false;
787 else if (Name == "3dnow")
788 Features["3dnow"] = Features["3dnowa"] = false;
789 else if (Name == "3dnowa")
790 Features["3dnowa"] = false;
791 }
792
793 return true;
794}
795
Daniel Dunbar4dbaaa62009-05-06 03:16:41 +0000796/// HandleTargetOptions - Perform initialization based on the user
797/// configured set of features.
Daniel Dunbar979586e2009-11-11 09:38:56 +0000798void
799X86TargetInfo::HandleTargetFeatures(const std::vector<std::string> &Features) {
800 // Remember the maximum enabled sselevel.
801 for (unsigned i = 0, e = Features.size(); i !=e; ++i) {
802 // Ignore disabled features.
803 if (Features[i][0] == '-')
804 continue;
805
806 assert(Features[i][0] == '+' && "Invalid target feature!");
807 X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Features[i].substr(1))
808 .Case("sse42", SSE42)
809 .Case("sse41", SSE41)
810 .Case("ssse3", SSSE3)
811 .Case("sse2", SSE2)
812 .Case("sse", SSE1)
813 .Case("mmx", MMX)
814 .Default(NoMMXSSE);
815 SSELevel = std::max(SSELevel, Level);
816 }
Chris Lattnerc25d8a72009-03-02 22:20:04 +0000817}
Chris Lattnerecd49032009-03-02 22:27:17 +0000818
819/// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines
820/// that are not tied to a specific subtarget.
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000821void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
822 std::vector<char> &Defs) const {
Chris Lattnerecd49032009-03-02 22:27:17 +0000823 // Target identification.
824 if (PointerWidth == 64) {
825 Define(Defs, "_LP64");
826 Define(Defs, "__LP64__");
827 Define(Defs, "__amd64__");
828 Define(Defs, "__amd64");
829 Define(Defs, "__x86_64");
830 Define(Defs, "__x86_64__");
Chris Lattnerecd49032009-03-02 22:27:17 +0000831 } else {
Chris Lattner1e1c0b92009-03-20 16:06:38 +0000832 DefineStd(Defs, "i386", Opts);
Chris Lattnerecd49032009-03-02 22:27:17 +0000833 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000834
Chris Lattnerecd49032009-03-02 22:27:17 +0000835 // Target properties.
836 Define(Defs, "__LITTLE_ENDIAN__");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000837
Chris Lattnerecd49032009-03-02 22:27:17 +0000838 // Subtarget options.
839 Define(Defs, "__nocona");
840 Define(Defs, "__nocona__");
841 Define(Defs, "__tune_nocona__");
Chris Lattnerecd49032009-03-02 22:27:17 +0000842 Define(Defs, "__REGISTER_PREFIX__", "");
Chris Lattner96e43572009-03-02 22:40:39 +0000843
Chris Lattner6df41af2009-04-19 17:32:33 +0000844 // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline
845 // functions in glibc header files that use FP Stack inline asm which the
846 // backend can't deal with (PR879).
847 Define(Defs, "__NO_MATH_INLINES");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000848
Chris Lattner96e43572009-03-02 22:40:39 +0000849 // Each case falls through to the previous one here.
850 switch (SSELevel) {
851 case SSE42:
852 Define(Defs, "__SSE4_2__");
853 case SSE41:
854 Define(Defs, "__SSE4_1__");
855 case SSSE3:
856 Define(Defs, "__SSSE3__");
857 case SSE3:
858 Define(Defs, "__SSE3__");
859 case SSE2:
860 Define(Defs, "__SSE2__");
861 Define(Defs, "__SSE2_MATH__"); // -mfp-math=sse always implied.
862 case SSE1:
863 Define(Defs, "__SSE__");
864 Define(Defs, "__SSE_MATH__"); // -mfp-math=sse always implied.
865 case MMX:
866 Define(Defs, "__MMX__");
867 case NoMMXSSE:
868 break;
869 }
Chris Lattnerecd49032009-03-02 22:27:17 +0000870}
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000871
872
Eli Friedman3fd920a2008-08-20 02:34:37 +0000873bool
Anders Carlsson58436352009-02-28 17:11:49 +0000874X86TargetInfo::validateAsmConstraint(const char *&Name,
Chris Lattnerd9725f72009-04-26 07:16:29 +0000875 TargetInfo::ConstraintInfo &Info) const {
Anders Carlsson58436352009-02-28 17:11:49 +0000876 switch (*Name) {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000877 default: return false;
878 case 'a': // eax.
879 case 'b': // ebx.
880 case 'c': // ecx.
881 case 'd': // edx.
882 case 'S': // esi.
883 case 'D': // edi.
884 case 'A': // edx:eax.
885 case 't': // top of floating point stack.
886 case 'u': // second from top of floating point stack.
887 case 'q': // Any register accessible as [r]l: a, b, c, and d.
Anders Carlsson83661ac2008-10-06 00:41:45 +0000888 case 'y': // Any MMX register.
Anders Carlsson5f7ee682008-10-06 19:17:39 +0000889 case 'x': // Any SSE register.
Eli Friedman3fd920a2008-08-20 02:34:37 +0000890 case 'Q': // Any register accessible as [r]h: a, b, c, and d.
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000891 case 'e': // 32-bit signed integer constant for use with zero-extending
Anders Carlssona0b89212009-01-24 18:03:09 +0000892 // x86_64 instructions.
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +0000893 case 'Z': // 32-bit unsigned integer constant for use with zero-extending
Anders Carlssona0b89212009-01-24 18:03:09 +0000894 // x86_64 instructions.
Eli Friedman3fd920a2008-08-20 02:34:37 +0000895 case 'N': // unsigned 8-bit integer constant for use with in and out
896 // instructions.
Eli Friedmancf432d32009-06-08 20:45:44 +0000897 case 'R': // "legacy" registers: ax, bx, cx, dx, di, si, sp, bp.
Chris Lattnerd9725f72009-04-26 07:16:29 +0000898 Info.setAllowsRegister();
Eli Friedman3fd920a2008-08-20 02:34:37 +0000899 return true;
900 }
901}
902
903std::string
904X86TargetInfo::convertConstraint(const char Constraint) const {
905 switch (Constraint) {
906 case 'a': return std::string("{ax}");
907 case 'b': return std::string("{bx}");
908 case 'c': return std::string("{cx}");
909 case 'd': return std::string("{dx}");
910 case 'S': return std::string("{si}");
911 case 'D': return std::string("{di}");
912 case 't': // top of floating point stack.
913 return std::string("{st}");
914 case 'u': // second from top of floating point stack.
915 return std::string("{st(1)}"); // second from top of floating point stack.
916 default:
917 return std::string(1, Constraint);
918 }
919}
Eli Friedman3fd920a2008-08-20 02:34:37 +0000920} // end anonymous namespace
Chris Lattner5ba61f02006-10-14 07:39:34 +0000921
922namespace {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000923// X86-32 generic target
924class X86_32TargetInfo : public X86TargetInfo {
Chris Lattner5ba61f02006-10-14 07:39:34 +0000925public:
Eli Friedman3fd920a2008-08-20 02:34:37 +0000926 X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
927 DoubleAlign = LongLongAlign = 32;
928 LongDoubleWidth = 96;
929 LongDoubleAlign = 32;
Eli Friedman873f65a2008-08-21 00:13:15 +0000930 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
931 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
Chris Lattner5c67237f2009-11-07 18:59:41 +0000932 "a0:0:64-f80:32:32-n8:16:32";
Eli Friedman32ca82a2009-03-29 20:31:09 +0000933 SizeType = UnsignedInt;
934 PtrDiffType = SignedInt;
935 IntPtrType = SignedInt;
Anton Korobeynikov6953ef22009-04-03 23:38:25 +0000936 RegParmMax = 3;
Eli Friedman3fd920a2008-08-20 02:34:37 +0000937 }
938 virtual const char *getVAListDeclaration() const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +0000939 return "typedef char* __builtin_va_list;";
Eli Friedman3fd920a2008-08-20 02:34:37 +0000940 }
Chris Lattnerd545ad12009-09-23 06:06:36 +0000941
942 int getEHDataRegisterNumber(unsigned RegNo) const {
943 if (RegNo == 0) return 0;
944 if (RegNo == 1) return 2;
945 return -1;
946 }
Eli Friedman3fd920a2008-08-20 02:34:37 +0000947};
948} // end anonymous namespace
949
950namespace {
Eli Friedmane3aa4542009-07-05 18:47:56 +0000951class OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> {
952public:
953 OpenBSDI386TargetInfo(const std::string& triple) :
954 OpenBSDTargetInfo<X86_32TargetInfo>(triple) {
955 SizeType = UnsignedLong;
956 IntPtrType = SignedLong;
Eli Friedman245f2292009-07-05 22:31:18 +0000957 PtrDiffType = SignedLong;
Eli Friedmane3aa4542009-07-05 18:47:56 +0000958 }
959};
960} // end anonymous namespace
961
962namespace {
Torok Edwinb2b37c62009-06-30 17:10:35 +0000963class DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000964public:
Torok Edwinb2b37c62009-06-30 17:10:35 +0000965 DarwinI386TargetInfo(const std::string& triple) :
966 DarwinTargetInfo<X86_32TargetInfo>(triple) {
Eli Friedman3fd920a2008-08-20 02:34:37 +0000967 LongDoubleWidth = 128;
968 LongDoubleAlign = 128;
Eli Friedman32ca82a2009-03-29 20:31:09 +0000969 SizeType = UnsignedLong;
970 IntPtrType = SignedLong;
Eli Friedman873f65a2008-08-21 00:13:15 +0000971 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
972 "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
Chris Lattner5c67237f2009-11-07 18:59:41 +0000973 "a0:0:64-f80:128:128-n8:16:32";
Torok Edwin4e054162009-06-30 17:00:25 +0000974 }
975
Eli Friedman3fd920a2008-08-20 02:34:37 +0000976};
Daniel Dunbar10de9e62009-06-29 20:52:51 +0000977} // end anonymous namespace
978
979namespace {
Eli Friedmanc968a6a2008-08-21 01:40:19 +0000980// x86-32 Windows target
981class WindowsX86_32TargetInfo : public X86_32TargetInfo {
982public:
983 WindowsX86_32TargetInfo(const std::string& triple)
984 : X86_32TargetInfo(triple) {
Eli Friedmand88c8a12009-04-19 21:38:35 +0000985 TLSSupported = false;
Chris Lattner46be2e12009-06-24 17:12:15 +0000986 WCharType = UnsignedShort;
Eli Friedmanebb9e4d2009-06-08 21:16:17 +0000987 DoubleAlign = LongLongAlign = 64;
988 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
989 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
Chris Lattner5c67237f2009-11-07 18:59:41 +0000990 "a0:0:64-f80:32:32-n8:16:32";
Eli Friedmanc968a6a2008-08-21 01:40:19 +0000991 }
Chris Lattner4ba73aa02009-03-20 15:52:06 +0000992 virtual void getTargetDefines(const LangOptions &Opts,
993 std::vector<char> &Defines) const {
994 X86_32TargetInfo::getTargetDefines(Opts, Defines);
Eli Friedmanc968a6a2008-08-21 01:40:19 +0000995 // This list is based off of the the list of things MingW defines
Eli Friedmanc968a6a2008-08-21 01:40:19 +0000996 Define(Defines, "_WIN32");
Chris Lattner1e1c0b92009-03-20 16:06:38 +0000997 DefineStd(Defines, "WIN32", Opts);
998 DefineStd(Defines, "WINNT", Opts);
Eli Friedmanc968a6a2008-08-21 01:40:19 +0000999 Define(Defines, "_X86_");
Eli Friedmanc968a6a2008-08-21 01:40:19 +00001000 }
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001001};
1002} // end anonymous namespace
Eli Friedmanaa27a872009-06-08 06:11:14 +00001003
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001004namespace {
1005
1006/// GetWindowsVisualStudioLanguageOptions - Set the default language options for Windows.
1007static void GetWindowsVisualStudioLanguageOptions(LangOptions &Opts) {
1008 Opts.Microsoft = true;
1009}
1010
1011// x86-32 Windows Visual Studio target
1012class VisualStudioWindowsX86_32TargetInfo : public WindowsX86_32TargetInfo {
1013public:
1014 VisualStudioWindowsX86_32TargetInfo(const std::string& triple)
1015 : WindowsX86_32TargetInfo(triple) {
1016 }
1017 virtual void getTargetDefines(const LangOptions &Opts,
1018 std::vector<char> &Defines) const {
1019 WindowsX86_32TargetInfo::getTargetDefines(Opts, Defines);
1020 // The value of the following reflects processor type.
1021 // 300=386, 400=486, 500=Pentium, 600=Blend (default)
1022 // We lost the original triple, so we use the default.
1023 Define(Defines, "_M_IX86", "600");
1024 }
Eli Friedmanaa27a872009-06-08 06:11:14 +00001025 virtual void getDefaultLangOptions(LangOptions &Opts) {
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001026 WindowsX86_32TargetInfo::getDefaultLangOptions(Opts);
1027 GetWindowsVisualStudioLanguageOptions(Opts);
1028 }
1029};
1030} // end anonymous namespace
1031
1032namespace {
1033// x86-32 MinGW target
1034class MinGWX86_32TargetInfo : public WindowsX86_32TargetInfo {
1035public:
1036 MinGWX86_32TargetInfo(const std::string& triple)
1037 : WindowsX86_32TargetInfo(triple) {
1038 }
1039 virtual void getTargetDefines(const LangOptions &Opts,
1040 std::vector<char> &Defines) const {
1041 WindowsX86_32TargetInfo::getTargetDefines(Opts, Defines);
1042 Define(Defines, "__MSVCRT__");
1043 Define(Defines, "__MINGW32__");
Cedric Venetbc8d0de2009-09-27 10:09:11 +00001044 Define(Defines, "__declspec", "__declspec");
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001045 }
1046};
1047} // end anonymous namespace
1048
1049namespace {
1050// x86-32 Cygwin target
1051class CygwinX86_32TargetInfo : public X86_32TargetInfo {
1052public:
1053 CygwinX86_32TargetInfo(const std::string& triple)
1054 : X86_32TargetInfo(triple) {
1055 TLSSupported = false;
1056 WCharType = UnsignedShort;
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001057 DoubleAlign = LongLongAlign = 64;
1058 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1059 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
Chris Lattner5c67237f2009-11-07 18:59:41 +00001060 "a0:0:64-f80:32:32-n8:16:32";
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001061 }
1062 virtual void getTargetDefines(const LangOptions &Opts,
1063 std::vector<char> &Defines) const {
1064 X86_32TargetInfo::getTargetDefines(Opts, Defines);
1065 Define(Defines, "__CYGWIN__");
1066 Define(Defines, "__CYGWIN32__");
1067 DefineStd(Defines, "unix", Opts);
Eli Friedmanaa27a872009-06-08 06:11:14 +00001068 }
Eli Friedmanc968a6a2008-08-21 01:40:19 +00001069};
1070} // end anonymous namespace
1071
1072namespace {
Eli Friedman3fd920a2008-08-20 02:34:37 +00001073// x86-64 generic target
1074class X86_64TargetInfo : public X86TargetInfo {
1075public:
Chris Lattner4ba73aa02009-03-20 15:52:06 +00001076 X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) {
Chris Lattnerba7a6c12008-05-09 06:17:04 +00001077 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
Eli Friedmanb5366062008-05-20 14:21:01 +00001078 LongDoubleWidth = 128;
1079 LongDoubleAlign = 128;
Chris Lattnerd0a79b22009-02-05 07:32:46 +00001080 IntMaxType = SignedLong;
1081 UIntMaxType = UnsignedLong;
Eli Friedman2857ccb2009-07-01 03:36:11 +00001082 Int64Type = SignedLong;
Anton Korobeynikov6953ef22009-04-03 23:38:25 +00001083 RegParmMax = 6;
Chris Lattnerd0a79b22009-02-05 07:32:46 +00001084
Eli Friedman873f65a2008-08-21 00:13:15 +00001085 DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1086 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
Chris Lattner5c67237f2009-11-07 18:59:41 +00001087 "a0:0:64-s0:64:64-f80:128:128-n8:16:32:64";
Chris Lattner10a5b382007-01-29 05:24:35 +00001088 }
Anders Carlssona7408e72007-10-13 00:45:48 +00001089 virtual const char *getVAListDeclaration() const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001090 return "typedef struct __va_list_tag {"
1091 " unsigned gp_offset;"
1092 " unsigned fp_offset;"
1093 " void* overflow_arg_area;"
1094 " void* reg_save_area;"
Eli Friedmanfb36b022009-07-03 00:45:06 +00001095 "} __va_list_tag;"
1096 "typedef __va_list_tag __builtin_va_list[1];";
Anders Carlsson5fa3f342007-11-24 23:38:12 +00001097 }
Chris Lattnerd545ad12009-09-23 06:06:36 +00001098
1099 int getEHDataRegisterNumber(unsigned RegNo) const {
1100 if (RegNo == 0) return 0;
1101 if (RegNo == 1) return 1;
1102 return -1;
1103 }
Eli Friedman3fd920a2008-08-20 02:34:37 +00001104};
1105} // end anonymous namespace
1106
1107namespace {
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001108// x86-64 Windows target
1109class WindowsX86_64TargetInfo : public X86_64TargetInfo {
1110public:
1111 WindowsX86_64TargetInfo(const std::string& triple)
1112 : X86_64TargetInfo(triple) {
1113 TLSSupported = false;
1114 WCharType = UnsignedShort;
Mike Stumpaf9afe92009-10-08 23:00:00 +00001115 LongWidth = LongAlign = 32;
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00001116 DoubleAlign = LongLongAlign = 64;
1117 }
1118 virtual void getTargetDefines(const LangOptions &Opts,
1119 std::vector<char> &Defines) const {
1120 X86_64TargetInfo::getTargetDefines(Opts, Defines);
1121 Define(Defines, "_WIN64");
1122 DefineStd(Defines, "WIN64", Opts);
1123 }
1124};
1125} // end anonymous namespace
1126
1127namespace {
1128// x86-64 Windows Visual Studio target
1129class VisualStudioWindowsX86_64TargetInfo : public WindowsX86_64TargetInfo {
1130public:
1131 VisualStudioWindowsX86_64TargetInfo(const std::string& triple)
1132 : WindowsX86_64TargetInfo(triple) {
1133 }
1134 virtual void getTargetDefines(const LangOptions &Opts,
1135 std::vector<char> &Defines) const {
1136 WindowsX86_64TargetInfo::getTargetDefines(Opts, Defines);
1137 Define(Defines, "_M_X64");
1138 }
1139 virtual const char *getVAListDeclaration() const {
1140 return "typedef char* va_list;";
1141 }
1142};
1143} // end anonymous namespace
1144
1145namespace {
1146// x86-64 MinGW target
1147class MinGWX86_64TargetInfo : public WindowsX86_64TargetInfo {
1148public:
1149 MinGWX86_64TargetInfo(const std::string& triple)
1150 : WindowsX86_64TargetInfo(triple) {
1151 }
1152 virtual void getTargetDefines(const LangOptions &Opts,
1153 std::vector<char> &Defines) const {
1154 WindowsX86_64TargetInfo::getTargetDefines(Opts, Defines);
1155 Define(Defines, "__MSVCRT__");
1156 Define(Defines, "__MINGW64__");
1157 Define(Defines, "__declspec");
1158 }
1159};
1160} // end anonymous namespace
1161
1162namespace {
Eli Friedman2857ccb2009-07-01 03:36:11 +00001163class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> {
1164public:
Mike Stump11289f42009-09-09 15:08:12 +00001165 DarwinX86_64TargetInfo(const std::string& triple)
Eli Friedman2857ccb2009-07-01 03:36:11 +00001166 : DarwinTargetInfo<X86_64TargetInfo>(triple) {
1167 Int64Type = SignedLongLong;
1168 }
1169};
1170} // end anonymous namespace
1171
1172namespace {
Eli Friedman245f2292009-07-05 22:31:18 +00001173class OpenBSDX86_64TargetInfo : public OpenBSDTargetInfo<X86_64TargetInfo> {
1174public:
Mike Stump11289f42009-09-09 15:08:12 +00001175 OpenBSDX86_64TargetInfo(const std::string& triple)
Eli Friedman245f2292009-07-05 22:31:18 +00001176 : OpenBSDTargetInfo<X86_64TargetInfo>(triple) {
1177 IntMaxType = SignedLongLong;
1178 UIntMaxType = UnsignedLongLong;
1179 Int64Type = SignedLongLong;
1180 }
1181};
1182} // end anonymous namespace
1183
1184namespace {
Eli Friedmanf05b7722008-08-20 07:44:10 +00001185class ARMTargetInfo : public TargetInfo {
Mike Stump9d54bd72009-04-08 02:07:04 +00001186 enum {
1187 Armv4t,
1188 Armv5,
1189 Armv6,
Mike Stumpb0dd95d2009-08-04 19:48:52 +00001190 Armv7a,
Mike Stump9d54bd72009-04-08 02:07:04 +00001191 XScale
1192 } ArmArch;
Daniel Dunbarb4091a92009-09-14 00:35:03 +00001193
Daniel Dunbar1da76c42009-09-17 07:03:19 +00001194 static const TargetInfo::GCCRegAlias GCCRegAliases[];
1195 static const char * const GCCRegNames[];
1196
Daniel Dunbarb4091a92009-09-14 00:35:03 +00001197 std::string ABI;
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001198 bool IsThumb;
Daniel Dunbarb4091a92009-09-14 00:35:03 +00001199
Chris Lattner17df24e2008-04-21 18:56:49 +00001200public:
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001201 ARMTargetInfo(const std::string &TripleStr)
1202 : TargetInfo(TripleStr), ABI("aapcs-linux"), IsThumb(false)
Daniel Dunbarb4091a92009-09-14 00:35:03 +00001203 {
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001204 llvm::Triple Triple(TripleStr);
1205
Daniel Dunbar125f8fb2009-09-14 00:02:24 +00001206 SizeType = UnsignedInt;
1207 PtrDiffType = SignedInt;
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001208
1209 // FIXME: This shouldn't be done this way, we should use features to
1210 // indicate the arch. See lib/Driver/Tools.cpp.
1211 llvm::StringRef Version(""), Arch = Triple.getArchName();
1212 if (Arch.startswith("arm"))
1213 Version = Arch.substr(3);
1214 else if (Arch.startswith("thumb"))
1215 Version = Arch.substr(5);
1216 if (Version == "v7")
Mike Stumpb0dd95d2009-08-04 19:48:52 +00001217 ArmArch = Armv7a;
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001218 else if (Version.empty() || Version == "v6" || Version == "v6t2")
Mike Stump9d54bd72009-04-08 02:07:04 +00001219 ArmArch = Armv6;
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001220 else if (Version == "v5")
Mike Stump9d54bd72009-04-08 02:07:04 +00001221 ArmArch = Armv5;
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001222 else if (Version == "v4t")
Mike Stump9d54bd72009-04-08 02:07:04 +00001223 ArmArch = Armv4t;
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001224 else if (Arch == "xscale" || Arch == "thumbv5e")
Mike Stump9d54bd72009-04-08 02:07:04 +00001225 ArmArch = XScale;
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001226 else
Chris Lattner0dc10262009-04-23 04:22:04 +00001227 ArmArch = Armv6;
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001228
1229 if (Arch.startswith("thumb"))
1230 IsThumb = true;
Daniel Dunbar03184792009-09-22 21:44:58 +00001231
1232 if (IsThumb) {
1233 DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
1234 "i64:64:64-f32:32:32-f64:64:64-"
Chris Lattner5c67237f2009-11-07 18:59:41 +00001235 "v64:64:64-v128:128:128-a0:0:32-n32");
Daniel Dunbar03184792009-09-22 21:44:58 +00001236 } else {
1237 DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1238 "i64:64:64-f32:32:32-f64:64:64-"
Chris Lattner5c67237f2009-11-07 18:59:41 +00001239 "v64:64:64-v128:128:128-a0:0:64-n32");
Daniel Dunbar03184792009-09-22 21:44:58 +00001240 }
Eli Friedmanb5366062008-05-20 14:21:01 +00001241 }
Daniel Dunbarb4091a92009-09-14 00:35:03 +00001242 virtual const char *getABI() const { return ABI.c_str(); }
Daniel Dunbar125f8fb2009-09-14 00:02:24 +00001243 virtual bool setABI(const std::string &Name) {
Daniel Dunbarb4091a92009-09-14 00:35:03 +00001244 ABI = Name;
1245
Daniel Dunbar125f8fb2009-09-14 00:02:24 +00001246 // The defaults (above) are for AAPCS, check if we need to change them.
1247 //
1248 // FIXME: We need support for -meabi... we could just mangle it into the
1249 // name.
1250 if (Name == "apcs-gnu") {
1251 DoubleAlign = LongLongAlign = 32;
1252 SizeType = UnsignedLong;
1253
Daniel Dunbar03184792009-09-22 21:44:58 +00001254 if (IsThumb) {
1255 DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
1256 "i64:32:32-f32:32:32-f64:32:32-"
Chris Lattner5c67237f2009-11-07 18:59:41 +00001257 "v64:64:64-v128:128:128-a0:0:32-n32");
Daniel Dunbar03184792009-09-22 21:44:58 +00001258 } else {
1259 DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
1260 "i64:32:32-f32:32:32-f64:32:32-"
Chris Lattner5c67237f2009-11-07 18:59:41 +00001261 "v64:64:64-v128:128:128-a0:0:64-n32");
Daniel Dunbar03184792009-09-22 21:44:58 +00001262 }
1263
Daniel Dunbar125f8fb2009-09-14 00:02:24 +00001264 // FIXME: Override "preferred align" for double and long long.
1265 } else if (Name == "aapcs") {
1266 // FIXME: Enumerated types are variable width in straight AAPCS.
1267 } else if (Name == "aapcs-linux") {
1268 ;
1269 } else
1270 return false;
1271
1272 return true;
1273 }
Chris Lattner4ba73aa02009-03-20 15:52:06 +00001274 virtual void getTargetDefines(const LangOptions &Opts,
1275 std::vector<char> &Defs) const {
Chris Lattnerecd49032009-03-02 22:27:17 +00001276 // Target identification.
1277 Define(Defs, "__arm");
1278 Define(Defs, "__arm__");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001279
Chris Lattnerecd49032009-03-02 22:27:17 +00001280 // Target properties.
1281 Define(Defs, "__LITTLE_ENDIAN__");
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001282
Mike Stump9d54bd72009-04-08 02:07:04 +00001283 // Subtarget options.
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001284 //
1285 // FIXME: Neither THUMB_INTERWORK nor SOFTFP is not being set correctly
1286 // here.
Mike Stumpb0dd95d2009-08-04 19:48:52 +00001287 if (ArmArch == Armv7a) {
1288 Define(Defs, "__ARM_ARCH_7A__");
1289 Define(Defs, "__THUMB_INTERWORK__");
1290 } else if (ArmArch == Armv6) {
Mike Stump9d54bd72009-04-08 02:07:04 +00001291 Define(Defs, "__ARM_ARCH_6K__");
1292 Define(Defs, "__THUMB_INTERWORK__");
1293 } else if (ArmArch == Armv5) {
1294 Define(Defs, "__ARM_ARCH_5TEJ__");
1295 Define(Defs, "__THUMB_INTERWORK__");
1296 Define(Defs, "__SOFTFP__");
1297 } else if (ArmArch == Armv4t) {
1298 Define(Defs, "__ARM_ARCH_4T__");
1299 Define(Defs, "__SOFTFP__");
1300 } else if (ArmArch == XScale) {
1301 Define(Defs, "__ARM_ARCH_5TE__");
1302 Define(Defs, "__XSCALE__");
1303 Define(Defs, "__SOFTFP__");
1304 }
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001305
Chris Lattnerecd49032009-03-02 22:27:17 +00001306 Define(Defs, "__ARMEL__");
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001307
1308 if (IsThumb) {
1309 Define(Defs, "__THUMBEL__");
1310 Define(Defs, "__thumb__");
1311 if (ArmArch == Armv7a)
1312 Define(Defs, "__thumb2__");
1313 }
1314
1315 // Note, this is always on in gcc, even though it doesn't make sense.
Eli Friedman20da71e2009-05-29 19:00:15 +00001316 Define(Defs, "__APCS_32__");
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001317 // FIXME: This should be conditional on VFP instruction support.
Eli Friedman20da71e2009-05-29 19:00:15 +00001318 Define(Defs, "__VFP_FP__");
Daniel Dunbar2f5c75e2009-09-17 16:21:10 +00001319
1320 Define(Defs, "__USING_SJLJ_EXCEPTIONS__");
Chris Lattner17df24e2008-04-21 18:56:49 +00001321 }
1322 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1323 unsigned &NumRecords) const {
Eli Friedmanf05b7722008-08-20 07:44:10 +00001324 // FIXME: Implement.
1325 Records = 0;
Chris Lattner17df24e2008-04-21 18:56:49 +00001326 NumRecords = 0;
1327 }
1328 virtual const char *getVAListDeclaration() const {
Eli Friedmanf05b7722008-08-20 07:44:10 +00001329 return "typedef char* __builtin_va_list;";
Chris Lattner17df24e2008-04-21 18:56:49 +00001330 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001331 virtual void getGCCRegNames(const char * const *&Names,
Daniel Dunbar1da76c42009-09-17 07:03:19 +00001332 unsigned &NumNames) const;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001333 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Daniel Dunbar1da76c42009-09-17 07:03:19 +00001334 unsigned &NumAliases) const;
Anders Carlsson58436352009-02-28 17:11:49 +00001335 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattnerd9725f72009-04-26 07:16:29 +00001336 TargetInfo::ConstraintInfo &Info) const {
Eli Friedmanf05b7722008-08-20 07:44:10 +00001337 // FIXME: Check if this is complete
Anders Carlsson58436352009-02-28 17:11:49 +00001338 switch (*Name) {
Eli Friedmanf05b7722008-08-20 07:44:10 +00001339 default:
Nate Begeman2908fa02008-04-22 05:03:19 +00001340 case 'l': // r0-r7
1341 case 'h': // r8-r15
1342 case 'w': // VFP Floating point register single precision
1343 case 'P': // VFP Floating point register double precision
Chris Lattnerd9725f72009-04-26 07:16:29 +00001344 Info.setAllowsRegister();
Nate Begeman2908fa02008-04-22 05:03:19 +00001345 return true;
1346 }
Chris Lattner17df24e2008-04-21 18:56:49 +00001347 return false;
1348 }
1349 virtual const char *getClobbers() const {
Eli Friedmanf05b7722008-08-20 07:44:10 +00001350 // FIXME: Is this really right?
Chris Lattner17df24e2008-04-21 18:56:49 +00001351 return "";
1352 }
1353};
Daniel Dunbar1da76c42009-09-17 07:03:19 +00001354
1355const char * const ARMTargetInfo::GCCRegNames[] = {
1356 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1357 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1358};
1359
1360void ARMTargetInfo::getGCCRegNames(const char * const *&Names,
1361 unsigned &NumNames) const {
1362 Names = GCCRegNames;
1363 NumNames = llvm::array_lengthof(GCCRegNames);
1364}
1365
1366const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
1367
1368 { { "a1" }, "r0" },
1369 { { "a2" }, "r1" },
1370 { { "a3" }, "r2" },
1371 { { "a4" }, "r3" },
1372 { { "v1" }, "r4" },
1373 { { "v2" }, "r5" },
1374 { { "v3" }, "r6" },
1375 { { "v4" }, "r7" },
1376 { { "v5" }, "r8" },
1377 { { "v6", "rfp" }, "r9" },
1378 { { "sl" }, "r10" },
1379 { { "fp" }, "r11" },
1380 { { "ip" }, "r12" },
1381 { { "sp" }, "r13" },
1382 { { "lr" }, "r14" },
1383 { { "pc" }, "r15" },
1384};
1385
1386void ARMTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
1387 unsigned &NumAliases) const {
1388 Aliases = GCCRegAliases;
1389 NumAliases = llvm::array_lengthof(GCCRegAliases);
1390}
Chris Lattner17df24e2008-04-21 18:56:49 +00001391} // end anonymous namespace.
1392
Eli Friedmanf05b7722008-08-20 07:44:10 +00001393
1394namespace {
Mike Stump11289f42009-09-09 15:08:12 +00001395class DarwinARMTargetInfo :
Torok Edwinb2b37c62009-06-30 17:10:35 +00001396 public DarwinTargetInfo<ARMTargetInfo> {
1397protected:
Daniel Dunbar40165182009-08-24 09:10:05 +00001398 virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
Torok Edwinb2b37c62009-06-30 17:10:35 +00001399 std::vector<char> &Defines) const {
1400 getDarwinDefines(Defines, Opts);
1401 getDarwinIPhoneOSDefines(Defines, Triple);
Eli Friedmand88c8a12009-04-19 21:38:35 +00001402 }
Eli Friedmanf05b7722008-08-20 07:44:10 +00001403
Torok Edwinb2b37c62009-06-30 17:10:35 +00001404public:
Mike Stump11289f42009-09-09 15:08:12 +00001405 DarwinARMTargetInfo(const std::string& triple)
Torok Edwinb2b37c62009-06-30 17:10:35 +00001406 : DarwinTargetInfo<ARMTargetInfo>(triple) {}
Eli Friedmanf05b7722008-08-20 07:44:10 +00001407};
1408} // end anonymous namespace.
1409
Chris Lattner5ba61f02006-10-14 07:39:34 +00001410namespace {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001411class SparcV8TargetInfo : public TargetInfo {
Chris Lattner9b415d62009-01-27 01:58:38 +00001412 static const TargetInfo::GCCRegAlias GCCRegAliases[];
1413 static const char * const GCCRegNames[];
Gabor Greif49991682008-02-21 16:29:08 +00001414public:
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001415 SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) {
1416 // FIXME: Support Sparc quad-precision long double?
Eli Friedman873f65a2008-08-21 00:13:15 +00001417 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 +00001418 "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001419 }
Chris Lattner4ba73aa02009-03-20 15:52:06 +00001420 virtual void getTargetDefines(const LangOptions &Opts,
1421 std::vector<char> &Defines) const {
Eli Friedman79426742009-05-22 01:12:57 +00001422 DefineStd(Defines, "sparc", Opts);
Gabor Greif49991682008-02-21 16:29:08 +00001423 Define(Defines, "__sparcv8");
Eli Friedman79426742009-05-22 01:12:57 +00001424 Define(Defines, "__REGISTER_PREFIX__", "");
Gabor Greif49991682008-02-21 16:29:08 +00001425 }
1426 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1427 unsigned &NumRecords) const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001428 // FIXME: Implement!
Gabor Greif49991682008-02-21 16:29:08 +00001429 }
1430 virtual const char *getVAListDeclaration() const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001431 return "typedef void* __builtin_va_list;";
Gabor Greif49991682008-02-21 16:29:08 +00001432 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001433 virtual void getGCCRegNames(const char * const *&Names,
Chris Lattner9b415d62009-01-27 01:58:38 +00001434 unsigned &NumNames) const;
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001435 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattner9b415d62009-01-27 01:58:38 +00001436 unsigned &NumAliases) const;
Anders Carlsson58436352009-02-28 17:11:49 +00001437 virtual bool validateAsmConstraint(const char *&Name,
Gabor Greif49991682008-02-21 16:29:08 +00001438 TargetInfo::ConstraintInfo &info) const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001439 // FIXME: Implement!
1440 return false;
Gabor Greif49991682008-02-21 16:29:08 +00001441 }
1442 virtual const char *getClobbers() const {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001443 // FIXME: Implement!
1444 return "";
Gabor Greif49991682008-02-21 16:29:08 +00001445 }
1446};
1447
Chris Lattner9b415d62009-01-27 01:58:38 +00001448const char * const SparcV8TargetInfo::GCCRegNames[] = {
1449 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1450 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
1451 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
1452 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
1453};
1454
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001455void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names,
Chris Lattner9b415d62009-01-27 01:58:38 +00001456 unsigned &NumNames) const {
1457 Names = GCCRegNames;
1458 NumNames = llvm::array_lengthof(GCCRegNames);
1459}
1460
1461const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = {
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001462 { { "g0" }, "r0" },
1463 { { "g1" }, "r1" },
1464 { { "g2" }, "r2" },
1465 { { "g3" }, "r3" },
1466 { { "g4" }, "r4" },
1467 { { "g5" }, "r5" },
1468 { { "g6" }, "r6" },
1469 { { "g7" }, "r7" },
1470 { { "o0" }, "r8" },
1471 { { "o1" }, "r9" },
1472 { { "o2" }, "r10" },
1473 { { "o3" }, "r11" },
1474 { { "o4" }, "r12" },
1475 { { "o5" }, "r13" },
1476 { { "o6", "sp" }, "r14" },
1477 { { "o7" }, "r15" },
1478 { { "l0" }, "r16" },
1479 { { "l1" }, "r17" },
1480 { { "l2" }, "r18" },
1481 { { "l3" }, "r19" },
1482 { { "l4" }, "r20" },
1483 { { "l5" }, "r21" },
1484 { { "l6" }, "r22" },
1485 { { "l7" }, "r23" },
1486 { { "i0" }, "r24" },
1487 { { "i1" }, "r25" },
1488 { { "i2" }, "r26" },
1489 { { "i3" }, "r27" },
1490 { { "i4" }, "r28" },
1491 { { "i5" }, "r29" },
1492 { { "i6", "fp" }, "r30" },
1493 { { "i7" }, "r31" },
Chris Lattner9b415d62009-01-27 01:58:38 +00001494};
1495
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001496void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattner9b415d62009-01-27 01:58:38 +00001497 unsigned &NumAliases) const {
1498 Aliases = GCCRegAliases;
1499 NumAliases = llvm::array_lengthof(GCCRegAliases);
1500}
Gabor Greif49991682008-02-21 16:29:08 +00001501} // end anonymous namespace.
1502
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001503namespace {
Edward O'Callaghan9dda8e982009-10-18 13:33:59 +00001504class AuroraUXSparcV8TargetInfo : public AuroraUXTargetInfo<SparcV8TargetInfo> {
1505public:
1506 AuroraUXSparcV8TargetInfo(const std::string& triple) :
1507 AuroraUXTargetInfo<SparcV8TargetInfo>(triple) {
1508 SizeType = UnsignedInt;
1509 PtrDiffType = SignedInt;
1510 }
1511};
Torok Edwinb2b37c62009-06-30 17:10:35 +00001512class SolarisSparcV8TargetInfo : public SolarisTargetInfo<SparcV8TargetInfo> {
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001513public:
1514 SolarisSparcV8TargetInfo(const std::string& triple) :
Torok Edwinb2b37c62009-06-30 17:10:35 +00001515 SolarisTargetInfo<SparcV8TargetInfo>(triple) {
Eli Friedmand50881c2008-11-02 02:43:55 +00001516 SizeType = UnsignedInt;
1517 PtrDiffType = SignedInt;
Eli Friedmanda8f5a92008-08-20 07:28:14 +00001518 }
1519};
1520} // end anonymous namespace.
Chris Lattner5ba61f02006-10-14 07:39:34 +00001521
Chris Lattnerb781dc792008-05-08 05:58:21 +00001522namespace {
1523 class PIC16TargetInfo : public TargetInfo{
1524 public:
1525 PIC16TargetInfo(const std::string& triple) : TargetInfo(triple) {
Eli Friedmand88c8a12009-04-19 21:38:35 +00001526 TLSSupported = false;
Sanjiv Guptad7959242008-10-31 09:52:39 +00001527 IntWidth = 16;
1528 LongWidth = LongLongWidth = 32;
1529 PointerWidth = 16;
1530 IntAlign = 8;
1531 LongAlign = LongLongAlign = 8;
Eli Friedmanb5366062008-05-20 14:21:01 +00001532 PointerAlign = 8;
Sanjiv Guptad7959242008-10-31 09:52:39 +00001533 SizeType = UnsignedInt;
1534 IntMaxType = SignedLong;
1535 UIntMaxType = UnsignedLong;
Chris Lattner7e4c81c2009-02-13 22:28:55 +00001536 IntPtrType = SignedShort;
Eli Friedmand50881c2008-11-02 02:43:55 +00001537 PtrDiffType = SignedInt;
Sanjiv Gupta7c720072009-06-02 04:43:46 +00001538 FloatWidth = 32;
1539 FloatAlign = 32;
1540 DoubleWidth = 32;
1541 DoubleAlign = 32;
1542 LongDoubleWidth = 32;
1543 LongDoubleAlign = 32;
1544 FloatFormat = &llvm::APFloat::IEEEsingle;
1545 DoubleFormat = &llvm::APFloat::IEEEsingle;
1546 LongDoubleFormat = &llvm::APFloat::IEEEsingle;
Chris Lattner5c67237f2009-11-07 18:59:41 +00001547 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 +00001548
Chris Lattnerb781dc792008-05-08 05:58:21 +00001549 }
Chris Lattner5e2ef0c2008-05-09 06:08:39 +00001550 virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return 16; }
1551 virtual uint64_t getPointerAlignV(unsigned AddrSpace) const { return 8; }
Chris Lattner4ba73aa02009-03-20 15:52:06 +00001552 virtual void getTargetDefines(const LangOptions &Opts,
1553 std::vector<char> &Defines) const {
Chris Lattnerb781dc792008-05-08 05:58:21 +00001554 Define(Defines, "__pic16");
Sanjiv Gupta30f95ec2009-07-07 04:42:23 +00001555 Define(Defines, "rom", "__attribute__((address_space(1)))");
1556 Define(Defines, "ram", "__attribute__((address_space(0)))");
Mike Stump11289f42009-09-09 15:08:12 +00001557 Define(Defines, "_section(SectName)",
Sanjiv Guptab841d1b2009-08-20 17:48:52 +00001558 "__attribute__((section(SectName)))");
Sanjiv Gupta84f0f772009-10-24 18:08:20 +00001559 Define(Defines, "near",
1560 "__attribute__((section(\"Address=NEAR\")))");
Sanjiv Guptab841d1b2009-08-20 17:48:52 +00001561 Define(Defines, "_address(Addr)",
1562 "__attribute__((section(\"Address=\"#Addr)))");
Sanjiv Gupta30f95ec2009-07-07 04:42:23 +00001563 Define(Defines, "_CONFIG(conf)", "asm(\"CONFIG \"#conf)");
Sanjiv Guptab841d1b2009-08-20 17:48:52 +00001564 Define(Defines, "_interrupt",
1565 "__attribute__((section(\"interrupt=0x4\"))) \
1566 __attribute__((used))");
Chris Lattnerb781dc792008-05-08 05:58:21 +00001567 }
1568 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1569 unsigned &NumRecords) const {}
Mike Stump11289f42009-09-09 15:08:12 +00001570 virtual const char *getVAListDeclaration() const {
Daniel Dunbar576d90d2009-08-24 09:54:37 +00001571 return "";
1572 }
1573 virtual const char *getClobbers() const {
1574 return "";
1575 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001576 virtual void getGCCRegNames(const char * const *&Names,
1577 unsigned &NumNames) const {}
1578 virtual bool validateAsmConstraint(const char *&Name,
Chris Lattnerb781dc792008-05-08 05:58:21 +00001579 TargetInfo::ConstraintInfo &info) const {
1580 return true;
1581 }
Anton Korobeynikov9d026dd2009-05-03 13:42:53 +00001582 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
Chris Lattnerb781dc792008-05-08 05:58:21 +00001583 unsigned &NumAliases) const {}
1584 virtual bool useGlobalsForAutomaticVariables() const {return true;}
1585 };
1586}
1587
Anton Korobeynikova0f54372009-05-03 13:43:08 +00001588namespace {
1589 class MSP430TargetInfo : public TargetInfo {
1590 static const char * const GCCRegNames[];
1591 public:
1592 MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) {
1593 TLSSupported = false;
1594 IntWidth = 16;
1595 LongWidth = LongLongWidth = 32;
1596 PointerWidth = 16;
1597 IntAlign = 8;
1598 LongAlign = LongLongAlign = 8;
1599 PointerAlign = 8;
1600 SizeType = UnsignedInt;
1601 IntMaxType = SignedLong;
1602 UIntMaxType = UnsignedLong;
1603 IntPtrType = SignedShort;
1604 PtrDiffType = SignedInt;
Chris Lattner5c67237f2009-11-07 18:59:41 +00001605 DescriptionString = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-n8:16";
Anton Korobeynikova0f54372009-05-03 13:43:08 +00001606 }
1607 virtual void getTargetDefines(const LangOptions &Opts,
1608 std::vector<char> &Defines) const {
1609 Define(Defines, "MSP430");
1610 Define(Defines, "__MSP430__");
1611 // FIXME: defines for different 'flavours' of MCU
1612 }
1613 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1614 unsigned &NumRecords) const {
1615 // FIXME: Implement.
1616 Records = 0;
1617 NumRecords = 0;
1618 }
Anton Korobeynikova0f54372009-05-03 13:43:08 +00001619 virtual void getGCCRegNames(const char * const *&Names,
1620 unsigned &NumNames) const;
1621 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1622 unsigned &NumAliases) const {
1623 // No aliases.
1624 Aliases = 0;
1625 NumAliases = 0;
1626 }
1627 virtual bool validateAsmConstraint(const char *&Name,
1628 TargetInfo::ConstraintInfo &info) const {
Anton Korobeynikov051913b2009-10-15 23:17:13 +00001629 // No target constraints for now.
1630 return false;
Anton Korobeynikova0f54372009-05-03 13:43:08 +00001631 }
1632 virtual const char *getClobbers() const {
1633 // FIXME: Is this really right?
1634 return "";
1635 }
1636 virtual const char *getVAListDeclaration() const {
1637 // FIXME: implement
Anton Korobeynikov2f910822009-05-08 18:24:57 +00001638 return "typedef char* __builtin_va_list;";
Anton Korobeynikova0f54372009-05-03 13:43:08 +00001639 }
1640 };
1641
1642 const char * const MSP430TargetInfo::GCCRegNames[] = {
1643 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1644 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1645 };
1646
1647 void MSP430TargetInfo::getGCCRegNames(const char * const *&Names,
1648 unsigned &NumNames) const {
1649 Names = GCCRegNames;
1650 NumNames = llvm::array_lengthof(GCCRegNames);
1651 }
1652}
1653
1654
Anton Korobeynikovb5b703b2009-07-16 20:09:57 +00001655namespace {
1656 class SystemZTargetInfo : public TargetInfo {
1657 static const char * const GCCRegNames[];
1658 public:
1659 SystemZTargetInfo(const std::string& triple) : TargetInfo(triple) {
1660 TLSSupported = false;
1661 IntWidth = IntAlign = 32;
1662 LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64;
1663 PointerWidth = PointerAlign = 64;
Chris Lattner5c67237f2009-11-07 18:59:41 +00001664 DescriptionString = "E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-"
1665 "i64:64:64-f32:32:32-f64:64:64-f128:128:128-a0:16:16-n32:64";
Anton Korobeynikovb5b703b2009-07-16 20:09:57 +00001666 }
1667 virtual void getTargetDefines(const LangOptions &Opts,
1668 std::vector<char> &Defines) const {
1669 Define(Defines, "__s390__");
1670 Define(Defines, "__s390x__");
1671 }
1672 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1673 unsigned &NumRecords) const {
1674 // FIXME: Implement.
1675 Records = 0;
1676 NumRecords = 0;
1677 }
Anton Korobeynikovb5b703b2009-07-16 20:09:57 +00001678
1679 virtual void getDefaultLangOptions(LangOptions &Opts) {
1680 TargetInfo::getDefaultLangOptions(Opts);
1681 Opts.CharIsSigned = false;
1682 }
1683
1684 virtual void getGCCRegNames(const char * const *&Names,
1685 unsigned &NumNames) const;
1686 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1687 unsigned &NumAliases) const {
1688 // No aliases.
1689 Aliases = 0;
1690 NumAliases = 0;
1691 }
1692 virtual bool validateAsmConstraint(const char *&Name,
1693 TargetInfo::ConstraintInfo &info) const {
1694 // FIXME: implement
1695 return true;
1696 }
1697 virtual const char *getClobbers() const {
1698 // FIXME: Is this really right?
1699 return "";
1700 }
1701 virtual const char *getVAListDeclaration() const {
1702 // FIXME: implement
1703 return "typedef char* __builtin_va_list;";
1704 }
1705 };
1706
1707 const char * const SystemZTargetInfo::GCCRegNames[] = {
1708 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1709 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1710 };
1711
1712 void SystemZTargetInfo::getGCCRegNames(const char * const *&Names,
1713 unsigned &NumNames) const {
1714 Names = GCCRegNames;
1715 NumNames = llvm::array_lengthof(GCCRegNames);
1716 }
1717}
1718
Jakob Stoklund Olesen0de52f92009-08-17 20:08:44 +00001719namespace {
1720 class BlackfinTargetInfo : public TargetInfo {
1721 static const char * const GCCRegNames[];
1722 public:
1723 BlackfinTargetInfo(const std::string& triple) : TargetInfo(triple) {
1724 TLSSupported = false;
1725 DoubleAlign = 32;
1726 LongLongAlign = 32;
1727 LongDoubleAlign = 32;
Chris Lattner5c67237f2009-11-07 18:59:41 +00001728 DescriptionString = "e-p:32:32-i64:32-f64:32-n32";
Jakob Stoklund Olesen0de52f92009-08-17 20:08:44 +00001729 }
1730
1731 virtual void getTargetDefines(const LangOptions &Opts,
1732 std::vector<char> &Defines) const {
1733 DefineStd(Defines, "bfin", Opts);
1734 DefineStd(Defines, "BFIN", Opts);
1735 Define(Defines, "__ADSPBLACKFIN__");
1736 // FIXME: This one is really dependent on -mcpu
1737 Define(Defines, "__ADSPLPBLACKFIN__");
1738 // FIXME: Add cpu-dependent defines and __SILICON_REVISION__
1739 }
1740
1741 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1742 unsigned &NumRecords) const {
1743 // FIXME: Implement.
1744 Records = 0;
1745 NumRecords = 0;
1746 }
1747
Jakob Stoklund Olesen0de52f92009-08-17 20:08:44 +00001748 virtual void getGCCRegNames(const char * const *&Names,
1749 unsigned &NumNames) const;
1750
1751 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1752 unsigned &NumAliases) const {
1753 // No aliases.
1754 Aliases = 0;
1755 NumAliases = 0;
1756 }
1757
1758 virtual bool validateAsmConstraint(const char *&Name,
1759 TargetInfo::ConstraintInfo &Info) const {
1760 if (strchr("adzDWeABbvfcCtukxywZY", Name[0])) {
1761 Info.setAllowsRegister();
1762 return true;
1763 }
1764 return false;
1765 }
1766
1767 virtual const char *getClobbers() const {
1768 return "";
1769 }
1770
1771 virtual const char *getVAListDeclaration() const {
1772 return "typedef char* __builtin_va_list;";
1773 }
1774 };
1775
1776 const char * const BlackfinTargetInfo::GCCRegNames[] = {
1777 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
1778 "p0", "p1", "p2", "p3", "p4", "p5", "sp", "fp",
1779 "i0", "i1", "i2", "i3", "b0", "b1", "b2", "b3",
1780 "l0", "l1", "l2", "l3", "m0", "m1", "m2", "m3",
1781 "a0", "a1", "cc",
1782 "rets", "reti", "retx", "retn", "rete", "astat", "seqstat", "usp",
1783 "argp", "lt0", "lt1", "lc0", "lc1", "lb0", "lb1"
1784 };
1785
1786 void BlackfinTargetInfo::getGCCRegNames(const char * const *&Names,
1787 unsigned &NumNames) const {
1788 Names = GCCRegNames;
1789 NumNames = llvm::array_lengthof(GCCRegNames);
1790 }
1791}
1792
Eli Friedmana9c3d712009-08-19 20:47:07 +00001793namespace {
1794
Mike Stump11289f42009-09-09 15:08:12 +00001795 // LLVM and Clang cannot be used directly to output native binaries for
1796 // target, but is used to compile C code to llvm bitcode with correct
Eli Friedmana9c3d712009-08-19 20:47:07 +00001797 // type and alignment information.
Mike Stump11289f42009-09-09 15:08:12 +00001798 //
1799 // TCE uses the llvm bitcode as input and uses it for generating customized
1800 // target processor and program binary. TCE co-design environment is
Eli Friedmana9c3d712009-08-19 20:47:07 +00001801 // publicly available in http://tce.cs.tut.fi
1802
1803 class TCETargetInfo : public TargetInfo{
1804 public:
1805 TCETargetInfo(const std::string& triple) : TargetInfo(triple) {
1806 TLSSupported = false;
1807 IntWidth = 32;
1808 LongWidth = LongLongWidth = 32;
Eli Friedmana9c3d712009-08-19 20:47:07 +00001809 PointerWidth = 32;
1810 IntAlign = 32;
1811 LongAlign = LongLongAlign = 32;
1812 PointerAlign = 32;
1813 SizeType = UnsignedInt;
1814 IntMaxType = SignedLong;
1815 UIntMaxType = UnsignedLong;
1816 IntPtrType = SignedInt;
1817 PtrDiffType = SignedInt;
1818 FloatWidth = 32;
1819 FloatAlign = 32;
1820 DoubleWidth = 32;
1821 DoubleAlign = 32;
1822 LongDoubleWidth = 32;
1823 LongDoubleAlign = 32;
1824 FloatFormat = &llvm::APFloat::IEEEsingle;
1825 DoubleFormat = &llvm::APFloat::IEEEsingle;
1826 LongDoubleFormat = &llvm::APFloat::IEEEsingle;
1827 DescriptionString = "E-p:32:32:32-a0:32:32"
1828 "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64"
Chris Lattner5c67237f2009-11-07 18:59:41 +00001829 "-f32:32:32-f64:32:64-n32";
Eli Friedmana9c3d712009-08-19 20:47:07 +00001830 }
1831
1832 virtual void getTargetDefines(const LangOptions &Opts,
1833 std::vector<char> &Defines) const {
1834 DefineStd(Defines, "tce", Opts);
1835 Define(Defines, "__TCE__");
1836 Define(Defines, "__TCE_V1__");
1837 }
1838 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1839 unsigned &NumRecords) const {}
Daniel Dunbar576d90d2009-08-24 09:54:37 +00001840 virtual const char *getClobbers() const {
1841 return "";
1842 }
Eli Friedmana9c3d712009-08-19 20:47:07 +00001843 virtual const char *getVAListDeclaration() const {
1844 return "typedef void* __builtin_va_list;";
1845 }
Eli Friedmana9c3d712009-08-19 20:47:07 +00001846 virtual void getGCCRegNames(const char * const *&Names,
1847 unsigned &NumNames) const {}
1848 virtual bool validateAsmConstraint(const char *&Name,
1849 TargetInfo::ConstraintInfo &info) const {
1850 return true;
1851 }
1852 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1853 unsigned &NumAliases) const {}
1854 };
1855}
1856
Edward O'Callaghane9a58b12009-11-15 10:22:07 +00001857namespace {
1858class MipsTargetInfo : public TargetInfo {
1859 static const TargetInfo::GCCRegAlias GCCRegAliases[];
1860 static const char * const GCCRegNames[];
1861public:
1862 MipsTargetInfo(const std::string& triple) : TargetInfo(triple) {
1863 DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
1864 "i64:32:64-f32:32:32-f64:64:64-v64:64:64-n32";
1865 }
1866 virtual void getTargetDefines(const LangOptions &Opts,
1867 std::vector<char> &Defines) const {
1868 DefineStd(Defines, "mips", Opts);
1869 Define(Defines, "_mips");
1870 DefineStd(Defines, "MIPSEB", Opts);
1871 Define(Defines, "_MIPSEB");
1872 Define(Defines, "__REGISTER_PREFIX__", "");
1873 }
1874 virtual void getTargetBuiltins(const Builtin::Info *&Records,
1875 unsigned &NumRecords) const {
1876 // FIXME: Implement!
1877 }
1878 virtual const char *getVAListDeclaration() const {
1879 return "typedef void* __builtin_va_list;";
1880 }
1881 virtual void getGCCRegNames(const char * const *&Names,
1882 unsigned &NumNames) const;
1883 virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
1884 unsigned &NumAliases) const;
1885 virtual bool validateAsmConstraint(const char *&Name,
1886 TargetInfo::ConstraintInfo &Info) const {
1887 switch (*Name) {
1888 default:
1889 case 'r': // CPU registers.
1890 case 'd': // Equivalent to "r" unless generating MIPS16 code.
1891 case 'y': // Equivalent to "r", backwards compatibility only.
1892 case 'f': // floating-point registers.
1893 Info.setAllowsRegister();
1894 return true;
1895 }
1896 return false;
1897 }
1898
1899 virtual const char *getClobbers() const {
1900 // FIXME: Implement!
1901 return "";
1902 }
1903};
1904
1905const char * const MipsTargetInfo::GCCRegNames[] = {
1906 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
1907 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
1908 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
1909 "$24", "$25", "$26", "$27", "$28", "$sp", "$fp", "$31",
1910 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
1911 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
1912 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
1913 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
1914 "hi", "lo", "", "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
1915 "$fcc5","$fcc6","$fcc7"
1916};
1917
1918void MipsTargetInfo::getGCCRegNames(const char * const *&Names,
1919 unsigned &NumNames) const {
1920 Names = GCCRegNames;
1921 NumNames = llvm::array_lengthof(GCCRegNames);
1922}
1923
1924const TargetInfo::GCCRegAlias MipsTargetInfo::GCCRegAliases[] = {
1925 { { "at" }, "$1" },
1926 { { "v0" }, "$2" },
1927 { { "v1" }, "$3" },
1928 { { "a0" }, "$4" },
1929 { { "a1" }, "$5" },
1930 { { "a2" }, "$6" },
1931 { { "a3" }, "$7" },
1932 { { "t0" }, "$8" },
1933 { { "t1" }, "$9" },
1934 { { "t2" }, "$10" },
1935 { { "t3" }, "$11" },
1936 { { "t4" }, "$12" },
1937 { { "t5" }, "$13" },
1938 { { "t6" }, "$14" },
1939 { { "t7" }, "$15" },
1940 { { "s0" }, "$16" },
1941 { { "s1" }, "$17" },
1942 { { "s2" }, "$18" },
1943 { { "s3" }, "$19" },
1944 { { "s4" }, "$20" },
1945 { { "s5" }, "$21" },
1946 { { "s6" }, "$22" },
1947 { { "s7" }, "$23" },
1948 { { "t8" }, "$24" },
1949 { { "t9" }, "$25" },
1950 { { "k0" }, "$26" },
1951 { { "k1" }, "$27" },
1952 { { "gp" }, "$28" },
1953 { { "sp" }, "$29" },
1954 { { "fp" }, "$30" },
1955 { { "ra" }, "$31" }
1956};
1957
1958void MipsTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
1959 unsigned &NumAliases) const {
1960 Aliases = GCCRegAliases;
1961 NumAliases = llvm::array_lengthof(GCCRegAliases);
1962}
1963} // end anonymous namespace.
1964
1965namespace {
1966class MipselTargetInfo : public MipsTargetInfo {
1967public:
1968 MipselTargetInfo(const std::string& triple) : MipsTargetInfo(triple) {
1969 DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
1970 "i64:32:64-f32:32:32-f64:64:64-v64:64:64-n32";
1971 }
1972
1973 virtual void getTargetDefines(const LangOptions &Opts,
1974 std::vector<char> &Defines) const;
1975};
1976
1977void MipselTargetInfo::getTargetDefines(const LangOptions &Opts,
1978 std::vector<char> &Defines) const {
1979 DefineStd(Defines, "mips", Opts);
1980 Define(Defines, "_mips");
1981 DefineStd(Defines, "MIPSEL", Opts);
1982 Define(Defines, "_MIPSEL");
1983 Define(Defines, "__REGISTER_PREFIX__", "");
1984}
1985} // end anonymous namespace.
1986
Chris Lattner5ba61f02006-10-14 07:39:34 +00001987//===----------------------------------------------------------------------===//
1988// Driver code
1989//===----------------------------------------------------------------------===//
1990
Daniel Dunbarb9bbd542009-11-15 06:48:46 +00001991static TargetInfo *AllocateTarget(const std::string &T) {
Daniel Dunbar52322032009-08-18 05:47:58 +00001992 llvm::Triple Triple(T);
1993 llvm::Triple::OSType os = Triple.getOS();
Eli Friedmanb5366062008-05-20 14:21:01 +00001994
Daniel Dunbar52322032009-08-18 05:47:58 +00001995 switch (Triple.getArch()) {
1996 default:
1997 return NULL;
Eli Friedmanb5366062008-05-20 14:21:01 +00001998
Daniel Dunbar52322032009-08-18 05:47:58 +00001999 case llvm::Triple::arm:
Daniel Dunbar33a004e2009-09-11 01:14:50 +00002000 case llvm::Triple::thumb:
Daniel Dunbar52322032009-08-18 05:47:58 +00002001 switch (os) {
2002 case llvm::Triple::Darwin:
Eli Friedman873f65a2008-08-21 00:13:15 +00002003 return new DarwinARMTargetInfo(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002004 case llvm::Triple::FreeBSD:
Torok Edwinb2b37c62009-06-30 17:10:35 +00002005 return new FreeBSDTargetInfo<ARMTargetInfo>(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002006 default:
2007 return new ARMTargetInfo(T);
2008 }
Eli Friedmanb5366062008-05-20 14:21:01 +00002009
Daniel Dunbar52322032009-08-18 05:47:58 +00002010 case llvm::Triple::bfin:
Jakob Stoklund Olesen0de52f92009-08-17 20:08:44 +00002011 return new BlackfinTargetInfo(T);
2012
Daniel Dunbar52322032009-08-18 05:47:58 +00002013 case llvm::Triple::msp430:
2014 return new MSP430TargetInfo(T);
Eli Friedmanb5366062008-05-20 14:21:01 +00002015
Edward O'Callaghane9a58b12009-11-15 10:22:07 +00002016 case llvm::Triple::mips:
2017 if (os == llvm::Triple::Psp)
2018 return new PSPTargetInfo<MipsTargetInfo>(T);
2019 if (os == llvm::Triple::Linux)
2020 return new LinuxTargetInfo<MipsTargetInfo>(T);
2021 return new MipsTargetInfo(T);
2022
2023 case llvm::Triple::mipsel:
2024 if (os == llvm::Triple::Psp)
2025 return new PSPTargetInfo<MipselTargetInfo>(T);
2026 if (os == llvm::Triple::Linux)
2027 return new LinuxTargetInfo<MipselTargetInfo>(T);
2028 return new MipselTargetInfo(T);
2029
Daniel Dunbar52322032009-08-18 05:47:58 +00002030 case llvm::Triple::pic16:
2031 return new PIC16TargetInfo(T);
2032
2033 case llvm::Triple::ppc:
2034 if (os == llvm::Triple::Darwin)
2035 return new DarwinTargetInfo<PPCTargetInfo>(T);
2036 return new PPC32TargetInfo(T);
2037
2038 case llvm::Triple::ppc64:
2039 if (os == llvm::Triple::Darwin)
2040 return new DarwinTargetInfo<PPC64TargetInfo>(T);
2041 return new PPC64TargetInfo(T);
2042
2043 case llvm::Triple::sparc:
Edward O'Callaghan9dda8e982009-10-18 13:33:59 +00002044 if (os == llvm::Triple::AuroraUX)
2045 return new AuroraUXSparcV8TargetInfo(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002046 if (os == llvm::Triple::Solaris)
2047 return new SolarisSparcV8TargetInfo(T);
2048 return new SparcV8TargetInfo(T);
2049
2050 case llvm::Triple::systemz:
2051 return new SystemZTargetInfo(T);
2052
Eli Friedmana9c3d712009-08-19 20:47:07 +00002053 case llvm::Triple::tce:
2054 return new TCETargetInfo(T);
2055
Daniel Dunbar52322032009-08-18 05:47:58 +00002056 case llvm::Triple::x86:
2057 switch (os) {
Edward O'Callaghan9dda8e982009-10-18 13:33:59 +00002058 case llvm::Triple::AuroraUX:
2059 return new AuroraUXTargetInfo<X86_32TargetInfo>(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002060 case llvm::Triple::Darwin:
2061 return new DarwinI386TargetInfo(T);
2062 case llvm::Triple::Linux:
2063 return new LinuxTargetInfo<X86_32TargetInfo>(T);
2064 case llvm::Triple::DragonFly:
2065 return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(T);
2066 case llvm::Triple::NetBSD:
2067 return new NetBSDTargetInfo<X86_32TargetInfo>(T);
2068 case llvm::Triple::OpenBSD:
2069 return new OpenBSDI386TargetInfo(T);
2070 case llvm::Triple::FreeBSD:
2071 return new FreeBSDTargetInfo<X86_32TargetInfo>(T);
2072 case llvm::Triple::Solaris:
2073 return new SolarisTargetInfo<X86_32TargetInfo>(T);
2074 case llvm::Triple::Cygwin:
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00002075 return new CygwinX86_32TargetInfo(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002076 case llvm::Triple::MinGW32:
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00002077 return new MinGWX86_32TargetInfo(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002078 case llvm::Triple::Win32:
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00002079 return new VisualStudioWindowsX86_32TargetInfo(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002080 default:
2081 return new X86_32TargetInfo(T);
2082 }
2083
2084 case llvm::Triple::x86_64:
2085 switch (os) {
Edward O'Callaghan9dda8e982009-10-18 13:33:59 +00002086 case llvm::Triple::AuroraUX:
2087 return new AuroraUXTargetInfo<X86_64TargetInfo>(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002088 case llvm::Triple::Darwin:
2089 return new DarwinX86_64TargetInfo(T);
2090 case llvm::Triple::Linux:
2091 return new LinuxTargetInfo<X86_64TargetInfo>(T);
2092 case llvm::Triple::NetBSD:
2093 return new NetBSDTargetInfo<X86_64TargetInfo>(T);
2094 case llvm::Triple::OpenBSD:
2095 return new OpenBSDX86_64TargetInfo(T);
2096 case llvm::Triple::FreeBSD:
2097 return new FreeBSDTargetInfo<X86_64TargetInfo>(T);
2098 case llvm::Triple::Solaris:
2099 return new SolarisTargetInfo<X86_64TargetInfo>(T);
Daniel Dunbar3e7a7232009-09-23 07:31:35 +00002100 case llvm::Triple::MinGW64:
2101 return new MinGWX86_64TargetInfo(T);
2102 case llvm::Triple::Win32: // This is what Triple.h supports now.
2103 return new VisualStudioWindowsX86_64TargetInfo(T);
Daniel Dunbar52322032009-08-18 05:47:58 +00002104 default:
2105 return new X86_64TargetInfo(T);
2106 }
2107 }
Chris Lattner5ba61f02006-10-14 07:39:34 +00002108}
Daniel Dunbarb9bbd542009-11-15 06:48:46 +00002109
2110/// CreateTargetInfo - Return the target info object for the specified target
2111/// triple.
2112TargetInfo *TargetInfo::CreateTargetInfo(Diagnostic &Diags,
2113 const TargetOptions &Opts) {
2114 llvm::Triple Triple(Opts.Triple);
2115
2116 // Construct the target
2117 llvm::OwningPtr<TargetInfo> Target(AllocateTarget(Triple.str()));
2118 if (!Target) {
2119 Diags.Report(diag::err_target_unknown_triple) << Triple.str();
2120 return 0;
2121 }
2122
2123 // Set the target ABI if specified.
2124 if (!Opts.ABI.empty() && !Target->setABI(Opts.ABI)) {
2125 Diags.Report(diag::err_target_unknown_abi) << Opts.ABI;
2126 return 0;
2127 }
2128
2129 // Compute the default target features, we need the target to handle this
2130 // because features may have dependencies on one another.
2131 llvm::StringMap<bool> Features;
2132 Target->getDefaultFeatures(Opts.CPU, Features);
2133
2134 // Apply the user specified deltas.
2135 for (std::vector<std::string>::const_iterator it = Opts.Features.begin(),
2136 ie = Opts.Features.end(); it != ie; ++it) {
2137 const char *Name = it->c_str();
2138
2139 // Apply the feature via the target.
2140 if ((Name[0] != '-' && Name[0] != '+') ||
2141 !Target->setFeatureEnabled(Features, Name + 1, (Name[0] == '+'))) {
2142 Diags.Report(diag::err_target_invalid_feature) << Name;
2143 return 0;
2144 }
2145 }
2146
2147 // Add the features to the compile options.
2148 //
2149 // FIXME: If we are completely confident that we have the right set, we only
2150 // need to pass the minuses.
2151 std::vector<std::string> StrFeatures;
2152 for (llvm::StringMap<bool>::const_iterator it = Features.begin(),
2153 ie = Features.end(); it != ie; ++it)
2154 StrFeatures.push_back(std::string(it->second ? "+" : "-") + it->first());
2155 Target->HandleTargetFeatures(StrFeatures);
2156
2157 return Target.take();
2158}